博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
左滑显示删除按钮
阅读量:7086 次
发布时间:2019-06-28

本文共 10469 字,大约阅读时间需要 34 分钟。

public class CleerScrollHorizontalView extends CleerDividerLinearLayout {    private static final String TAG = "Cleer.ScrollView";    private static final boolean DEBUG = true;    private static final int MAX_DRAG_LENGTH = 316;    private static final int START_SCROLL_LENGTH = MAX_DRAG_LENGTH / 2;    private static int DRAG_NOT_CLICK_SIGN_LENGTH;    private static final int SCROLL_ANIM_DURATION = 850;    private static final int COLOR_RED_NORMAL = 0xffe70909;    private static final int COLOR_RED_PRESSED = 0x5fe70909;    private Scroller mScroller;    private Paint deleteBgPaint;    private Paint deleteIconPaint;    private Bitmap deleteBitmap;    private int layoutWidth;    private int layoutHeight;    private int deleteWidth;    private int deleteHeight;    private boolean deleteClickSign = false;    private boolean itemExceptDeleteClickSign = false;    private boolean itemClickSign = false;    private boolean deleteClickAnimation = false;    private boolean needShowDeleteView = false;    private int currX;    private int prevX;    private int origX;    private boolean intercept;    //For log    private String logTag = TAG;    private OnDeleteClickListener listener;    private OnClickListener onClickListener;    public void setLogTag(String tag) {        logTag = tag;    }    public interface OnDeleteClickListener {        void onClick();    }    public void setOnDeleteClickListener(OnDeleteClickListener listener) {        this.listener = listener;    }    public void setOnClickListener(OnClickListener listener) {        onClickListener = listener;    }    public CleerScrollHorizontalView(Context context, AttributeSet attrs) {        super(context, attrs);        mScroller = new Scroller(context, new DecelerateInterpolator());        deleteBgPaint = new Paint();        deleteIconPaint = new Paint();        deleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_item_delete);        DRAG_NOT_CLICK_SIGN_LENGTH = ViewConfiguration.get(context).getScaledTouchSlop();        //Force layout to invoke onDraw        setWillNotDraw(false);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        layoutWidth = this.getMeasuredWidth();        layoutHeight = this.getMeasuredHeight();        deleteWidth = deleteBitmap.getWidth();        deleteHeight = deleteBitmap.getHeight();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        deleteBgPaint.setColor(deleteClickAnimation ? COLOR_RED_PRESSED : COLOR_RED_NORMAL);        //Draw deleteBg        canvas.drawRect(layoutWidth, 0, layoutWidth + MAX_DRAG_LENGTH, layoutHeight, deleteBgPaint);        //Draw deleteIcon        int deleteLeft = layoutWidth + (MAX_DRAG_LENGTH - deleteWidth) / 2;        int deleteTop = (layoutHeight - deleteHeight) / 2;        canvas.drawBitmap(deleteBitmap, deleteLeft, deleteTop, deleteIconPaint);    }    private boolean isTouchPointInDeleteView(int x, int y) {        return x > layoutWidth && x <= layoutWidth + MAX_DRAG_LENGTH                && y >= 0 && y <= layoutHeight;    }    private boolean isTouchPointInItemNotDeleteView(int x, int y) {        return x >= 0 && x <= layoutWidth                && y >= 0 && y <= layoutHeight;    }    /** Hide the deleteView */    private void hideDeleteView() {        startScroll(getScrollX(), 0, -getScrollX(), 0, SCROLL_ANIM_DURATION);    }    /** Hide all the layouts except itself */    private void triggerInitAllOthersLayouts() {        if (getParent() instanceof ViewGroup) {            ViewGroup parent = (ViewGroup) getParent();            for (int i = 0; i < parent.getChildCount(); ++i) {                View child = parent.getChildAt(i);                if (child instanceof CleerScrollHorizontalView && !child.equals(this)) {                    CleerScrollHorizontalView c = (CleerScrollHorizontalView) child;                    c.hideDeleteView();                }            }        }    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN: {                if (DEBUG)                    Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_DOWN->" + ev.getX());                triggerInitAllOthersLayouts();                mScroller.forceFinished(true);                origX = currX = prevX = (int) ev.getX();                needShowDeleteView = false;                deleteClickSign = isTouchPointInDeleteView((int) ev.getX() + getScrollX(), (int) ev.getY());                itemExceptDeleteClickSign = !deleteClickSign;                itemClickSign = true;                //For deleteView rendering, type:ACTION_DOWN                deleteClickAnimation = deleteClickSign;                invalidate();                intercept = false;                break;            }            case MotionEvent.ACTION_MOVE: {                if (DEBUG) Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_MOVE");                //Scroll animation                currX = (int) ev.getX();                if (intercept) {                    int dOffset = -(currX - prevX);                    if (getScrollX() + dOffset < 0) {                        if (DEBUG)                            Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_MOVE" + ", move type one");                        scrollTo(0, 0);                    } else if (getScrollX() + dOffset > MAX_DRAG_LENGTH) {                        if (DEBUG)                            Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_MOVE" + ", move type two");                        scrollTo(MAX_DRAG_LENGTH, 0);                    } else {                        if (DEBUG)                            Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_MOVE" + ", move type three->" + dOffset);                        scrollBy(dOffset, 0);                    }                }                //For deleteView rendering, type:ACTION_MOVE                deleteClickAnimation = isTouchPointInDeleteView((int) ev.getX() + getScrollX(), (int) ev.getY());                invalidate();                if (Math.abs(currX - origX) >= DRAG_NOT_CLICK_SIGN_LENGTH) {                    //Disallow parent to intercept MotionEvent                    getParent().requestDisallowInterceptTouchEvent(true);                    intercept = true;                }                prevX = currX;                break;            }            case MotionEvent.ACTION_CANCEL:            case MotionEvent.ACTION_UP: {                if (DEBUG) Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_UP");                currX = (int) ev.getX();                if (Math.abs(currX - origX) >= DRAG_NOT_CLICK_SIGN_LENGTH) {                    itemClickSign = false;                    itemExceptDeleteClickSign = false;                }                if (deleteClickSign && isTouchPointInDeleteView((int) ev.getX() + getScrollX(), (int) ev.getY())) {                    if (DEBUG) Log.v(TAG, "logTag->" + logTag + " deleteView clicked");                    hideDeleteView();                    if (listener != null) {                        listener.onClick();                    }                    itemClickSign = true;                }                //For deleteView rendering, type:ACTION_UP                deleteClickAnimation = false;                invalidate();                //Scroll animation                if (getScrollX() > 0 && getScrollX() < START_SCROLL_LENGTH) {                    needShowDeleteView = false;                }                if (getScrollX() > START_SCROLL_LENGTH) {                    needShowDeleteView = true;                }                if (currX > origX) {                    needShowDeleteView = false;                }                if (needShowDeleteView) {                    if (DEBUG)                        Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_UP" + ", up to changed");                    mScroller.forceFinished(true);                    startScroll(getScrollX(), 0, MAX_DRAG_LENGTH - getScrollX(), 0, SCROLL_ANIM_DURATION);                } else {                    if (DEBUG)                        Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_UP" + ", up to origin2");                    mScroller.forceFinished(true);                    startScroll(getScrollX(), 0, -getScrollX(), 0, SCROLL_ANIM_DURATION);                }                if (needShowDeleteView && itemClickSign) {                    if (DEBUG)                        Log.v("dispatchTouchEvent", "logTag->" + logTag + ", ACTION_UP" + ", up to origin3");                    mScroller.forceFinished(true);                    startScroll(getScrollX(), 0, -getScrollX(), 0, SCROLL_ANIM_DURATION);                }                break;            }        }        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        if (!itemClickSign) {            return true;        }        return super.onInterceptTouchEvent(ev) || intercept;    }    @Override    public boolean performClick() {        boolean r = super.performClick();        if (onClickListener != null) {            onClickListener.onClick(this);            return true;        }        return r;    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        if (!intercept)            super.onTouchEvent(ev);        if (ev.getAction() == MotionEvent.ACTION_UP) {            if (itemExceptDeleteClickSign                    && isTouchPointInItemNotDeleteView((int) ev.getX() + getScrollX(), (int) ev.getY())                    && !isTouchPointInDeleteView((int) ev.getX() + getScrollX(), (int) ev.getY())) {                if (DEBUG) Log.v(TAG, "logTag->" + logTag + " itemExceptDeleteView clicked");                performClick();                itemExceptDeleteClickSign = false;            }        }        return true;    }    private void startScroll(int startX, int startY, int dx, int dy, int duration) {        int readDuration = Math.abs((int) (1.0f * duration / MAX_DRAG_LENGTH * dx));        mScroller.startScroll(startX, startY, dx, dy, readDuration);        invalidate();    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), 0);            postInvalidate();        }    }}复制代码

转载地址:http://qzzql.baihongyu.com/

你可能感兴趣的文章
leetcode:Merge Sorted Array (合并排好序的数组)
查看>>
数字反转(升级版)
查看>>
【转】安卓毛玻璃效果
查看>>
python Django 之 Model ORM inspectdb(数据库表反向生成)
查看>>
Oracle 11.2 静默安装脚本
查看>>
《C++编程思想》(第二版)第3章 C++中的C(笔记、习题及答案)(二)
查看>>
iOS自己主动化測试的那些干货
查看>>
创业的需求分析——创业杂记【1】
查看>>
1098 均分纸牌
查看>>
Android EditText控件即设置最小高度又运行高度随内容增加而变化
查看>>
this指向及改变this指向的方法
查看>>
安装MySQL-python 的问题
查看>>
SQL Server中,varchar和nvarchar如何选择?
查看>>
Django 文件上传
查看>>
Neural networks representation 习题
查看>>
Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (TireTree之位字典树)
查看>>
懒加载预加载(图片)
查看>>
网站的Information Architecture--构建一个最优用户体验的site structure
查看>>
GeoServer地图开发(001)-环境配置
查看>>
点化讲究机缘--剑雨
查看>>