• ViewDragHelper练习使用



    这个Demo是用来练习VIewDragHelper的,也是仿照网上一个大神的代码。我通过他的代码学会的ViewDragHelper,然后仿照效果写的同样的效果。
    原文连接:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0911/1680.html
    效果图:
    1.gif

    主要代码就是一个继承VIewGroup的类。写了注释,就不再解释了。
    我写的主要代码如下:

    public class YouLayout extends RelativeLayout {

    private View topView;
    private View bottomView;
    private ViewDragHelper mDragHelper;


    public YouLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
    init(context);
    }
    public YouLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
    // TODO Auto-generated constructor stub
    }
    public YouLayout(Context context) {
    super(context);
    init(context);
    }
    private void init(Context context){
    mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallBack());
    }
    @Override
    protected void onFinishInflate() {
    super.onFinishInflate();
    topView = getTopView();
    bottomView = getBottomView();
    }
    private View getTopView(){
    return getChildAt(0);
    }
    private View getBottomView(){
    return getChildAt(1);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) {
    mDragHelper.cancel();
    return false;
    }
    return mDragHelper.shouldInterceptTouchEvent(ev); //将事件传递给ViewDragHelper,让它自己处理是否需要打断。
    }
    private int downX ;
    private int downY ;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    mDragHelper.processTouchEvent(event); //同样是传递事件给ViewdragHelper
    int x = (int) event.getX();
    int y = (int) event.getY();
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
    downX = x ;
    downY = y ;
    break;
    case MotionEvent.ACTION_UP:
    int dx = x - downX;
    int dy = y - downY;
    int slop = mDragHelper.getTouchSlop();
    if ((Math.pow(dx, 2) + Math.pow(dy, 2)) < Math.pow(slop, 2)) {
    //说明是点击事件
    if (mDragOffset == 0 ) {
    moveTo(1f);
    }else {
    moveTo(0);
    }
    }
    break;
    }//收拾的放下,抬起的处理,是为了针对点击事件做的处理
    return  isMyView(topView, x, y) || isMyView(bottomView, x, y); //判断当前的点击事件是在TopView或者是在BottomView上,如果在其上,则返回true
    //如果是在TopView上,事件则传递给ViewDragHelper处理,如果是在BottomView上,则自然的传递下去。如果是在其他地方,则返回false,将事件传递下去。
    }
    @Override
    public void computeScroll() {
    //这个是为了将事件执行到底
    if (mDragHelper.continueSettling(true)) {
    ViewCompat.postInvalidateOnAnimation(this);
    }
    }
    //判断点击事件是否在View上
    private boolean isMyView(View view, int x, int y) {
           int[] viewLocation = new int[2];
           view.getLocationOnScreen(viewLocation);
           int[] parentLocation = new int[2];
           this.getLocationOnScreen(parentLocation);
           int screenX = parentLocation[0] + x;
           int screenY = parentLocation[1] + y;
           return screenX >= viewLocation[0] && screenX < viewLocation[0] + view.getWidth() &&  screenY >= viewLocation[1] && screenY < viewLocation[1] + view.getHeight();
     }
    //移动到指定的位置
    boolean moveTo(float slideRatio) {
            final int topBound = getPaddingTop();
            int y = (int) (topBound + slideRatio * mHeight);
            if (mDragHelper.smoothSlideViewTo(topView, topView.getLeft(), y)) {
                ViewCompat.postInvalidateOnAnimation(this);
                return true;
            }
            return false;
        }

    class DragHelperCallBack extends Callback{

    /**
    * 这个是为了判断力要ViewDragHelper处理的是哪个View,很明显,这里处理的是TopView
    */
    @Override
    public boolean tryCaptureView(View child, int arg1) {
      return child == topView;
    }
    //时时回调。提供的是TopView时时更改的状态
    @Override
    public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
    mTop = top;

    mDragOffset = (float) top / mHeight;

               topView.setPivotX(topView.getWidth());
               topView.setPivotY(topView.getHeight());
               topView.setScaleX(1 - mDragOffset / 2);
               topView.setScaleY(1 - mDragOffset / 2);

               bottomView.setAlpha(1 - mDragOffset);
               requestLayout();
               System.out.println("onviewpositionChhanged");
    }

     
     
    @Override
    public void onViewReleased(View releasedChild, float xvel, float yvel) {
    int top = getPaddingTop();
    if (yvel > 0 || (yvel == 0 && mDragOffset > 0.5f)) {
    top += mHeight;
    }
    mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top);
    invalidate();
    }

    @Override
    public int getViewVerticalDragRange(View child) {
    return mHeight;
    }
    /**
    * 如果手指是竖向滑动,事件则是在这个方法中处理的
    */
    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
    int topBound = getPaddingTop();
    int bottomBound = getHeight() - topView.getHeight() - topView.getPaddingBottom();
    int newTop = Math.min(Math.max(top, topBound), bottomBound);
    return newTop;
    }
    }
    /**
    * 重新的测量View
    */
    @Override
       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
           measureChildren(widthMeasureSpec, heightMeasureSpec);

           int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
           int maxHeight = MeasureSpec.getSize(heightMeasureSpec);

           setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
                   resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
       }
     
     
     
    private int mTop = 0 ;
    private int mHeight;
    private float mDragOffset;
    /**
    * 重新的布局子View   ,不重新布局也是可以的如果只是简单的移动一个topView的时候。在这个Demo中,需要让BottomView与TopView一起的移送,
    * ViewdragHelper不能控制两个View,这里自己布局,然后使得在onViewPositionChanged的方法中,重新调用,重新布局,实现两个VIew的联动
    */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    mHeight = getHeight() - topView.getHeight();
    topView.layout(0, mTop, r, mTop + topView.getMeasuredHeight());
    bottomView.layout(0, mTop + topView.getMeasuredHeight(), r, mTop +b);
    }
     
    }


    我的github地址:https://github.com/flyme2012
    我的博客地址:http://www.cnblogs.com/flyme2012/




    附件列表

  • 相关阅读:
    Zookeeper系列(二)特征及应用场景
    Scala学习笔记(三)类层级和特质
    zookeeper系列(一)安装
    Scala学习笔记(二)表达式和函数
    Spring笔记(四)SpingAOP
    Spring笔记(三)AOP前篇之动态代理
    Scala学习笔记(一)数据类型
    Linux内核系列设备模型(一) Kobject与Kset
    Spring笔记(二)Core层
    Linux内核系列之Block块层(一)
  • 原文地址:https://www.cnblogs.com/flyme2012/p/4076674.html
Copyright © 2020-2023  润新知