自定义View之基础概念(三)

1. Matrix原理

Matrix是一个矩阵,主要功能是坐标映射,数值转换。
1.缩放(Scale)
2.错切(Skew)
3.旋转(Rotate)
4.平移(Translate)

2. Matrix详解

setPolyToPoly

boolean setPolyToPoly (
    float[] src,    // 原始数组 src [x,y],存储内容为一组点
    int srcIndex,   // 原始数组开始位置
    float[] dst,    // 目标数组 dst [x,y],存储内容为一组点
    int dstIndex,   // 目标数组开始位置
    int pointCount) // 测控点的数量 取值范围是: 0到4

3. 利用setPolyToPoly制造3D效果

参考洪洋大大的

Android FoldingLayout 折叠布局 原理及实现(一)

Android FoldingLayout 折叠布局 原理及实现(二)

4. Matrix Camera

5. 事件分发、拦截与消费

View的事件分发机制实际上就是一个非常经典的责任链模式

责任链模式:

当有多个对象均可以处理同一请求的时候,将这些对象串联成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

6. 事件分发核心要点

1. 事件分发原理: 责任链模式,事件层层传递,直到被消费。
2. View 的 dispatchTouchEvent 主要用于调度自身的监听器和 onTouchEvent。
3. View的事件的调度顺序是 onTouchListener > onTouchEvent > onLongClickListener > onClickListener 。
4. 不论 View 自身是否注册点击事件,只要 View 是可点击的就会消费事件。
5. 事件是否被消费由返回值决定,true 表示消费,false 表示不消费,与是否使用了事件无关。
6. ViewGroup 中可能有多个 ChildView 时,将事件分配给包含点击位置的 ChildView。
7. ViewGroup 和 ChildView 同时注册了事件监听器(onClick等),由 ChildView 消费。
8. 一次触摸流程中产生事件应被同一 View 消费,全部接收或者全部拒绝。
9. 只要接受 ACTION_DOWN 就意味着接受所有的事件,拒绝 ACTION_DOWN 则不会收到后续内容。
10. 如果当前正在处理的事件被上层 View 拦截,会收到一个 ACTION_CANCEL,后续事件不会再传递过来。

7. Scroller使用

// 第一步,创建Scroller的实例
mScroller = new Scroller(context);
ViewConfiguration configuration = ViewConfiguration.get(context);
// 获取TouchSlop值
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration)
// 第二步,调用startScroll()方法来初始化滚动数据并刷新界面
mScroller.startScroll(getScrollX(), 0, dx, 0);
invalidate();
// 第三步,重写computeScroll()方法,并在其内部完成平滑
 @Override
public void computeScroll() {
   滚动的逻辑
    if (mScroller.computeScrollOffset()) {
        scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        invalidate();
    }
}

8. ViewDragerHelper使用

1.创建实例

扫描二维码关注公众号,回复: 2130516 查看本文章
mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback()
    {
    });

2.触摸相关方法

@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
    return mDragger.shouldInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
    mDragger.processTouchEvent(event);
    return true;
}

3.实现ViewDragHelper.CallCack相关方法

new ViewDragHelper.Callback()
    {
        @Override
        public boolean tryCaptureView(View child, int pointerId)
        {
            return true;
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx)
        {
            return left;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy)
        {
            return top;
        }
    }

4.功能展示

    边界检测、加速度检测(eg:DrawerLayout边界触发拉出)
    //在边界拖动时回调
    @Override
    public void onEdgeDragStarted(int edgeFlags, int pointerId) {
        super.onEdgeDragStarted(edgeFlags, pointerId);
        mDragHelper.captureChildView(mEdgeTrackerView,pointerId);
    }

    回调Drag Release(eg:DrawerLayout部分,手指抬起,自动展开/收缩)
    //手指释放的时候回调
    @Override
    public void onViewReleased(View releasedChild, float xvel, float yvel) {
        super.onViewReleased(releasedChild, xvel, yvel);
        //mAutoBackView手指释放时可以自动回去
        if(releasedChild == mAutoBackView){
            mDragHelper.settleCapturedViewAt((int)mAutoBackOriginPos.x,(int)mAutoBackOriginPos.y);
            invalidate();
        }
    }

     @Override
    public void computeScroll() {
        super.computeScroll();
        if(mDragHelper.continueSettling(true)){
            invalidate();
        }
    }

参考

GcsSloop的安卓自定义View教程目录

9. 联系方式

QQ:1509815887

猜你喜欢

转载自blog.csdn.net/rjgcszlc/article/details/80977564
今日推荐