防QQ侧滑条目

每当我们看到侧滑的时候就会不由自主的想到ViewDragHelper,下面我将给大家来介绍关于ViewDragHelper的用法,以及自定义控件中需要注意的点;

ViewDragHelper的使用方法,分为以下几个步骤;
  • 第一步是创建类,继承ViewGrup,建立布局
<?xml version="1.0" encoding="utf-8"?>
<com.example.selfviewdemo.ViewDragHelperTest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipeLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:gravity="center_vertical">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:src="@mipmap/ic_launcher"/>

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="@string/nihao"
            android:textColor="#444"
            android:textSize="18sp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="140dp"
        android:layout_height="50dp">

        <TextView
            android:layout_width="70dp"
            android:layout_height="match_parent"
            android:background="#ccc"
            android:gravity="center"
            android:text="置顶"
            android:textColor="#fff"/>

        <TextView
            android:id="@+id/tv_del"
            android:layout_width="70dp"
            android:layout_height="match_parent"
            android:background="#f00"
            android:clickable="true"
            android:gravity="center"
            android:text="刪除"
            android:textColor="#fff"/>
    </LinearLayout>
</com.example.selfviewdemo.ViewDragHelperTest>
  • 第二步初始化ViewDragHelper
ViewDragHelper viewDragHelper = ViewDragHelper.create(this, new MyCallbak());
  • 第三步拦截事件,这一点非常重要,因为很多新手在做这一步的时候总会忘了他。当然忘记的后果就是没法收到手势事件。而处理方法很简单只需加两行固定的代码就行了。
 @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    //拦截事件给ViewDragHelper
        return dragHelper.shouldInterceptTouchEvent(ev);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        dragHelper.processTouchEvent(event);
        //自己处理此事件;
        return true;
    }
  • 第四步得到viewgrup中的子控件对象,也是固定代码
 @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        contentlayout = getChildAt(0);//内容区域
        deletelayout = getChildAt(1);//侧滑菜单

        //得到布局的宽高;
        mContentheight = contentlayout.getLayoutParams().height;
        mDeletewidth = deletelayout.getLayoutParams().width;
        mDeleteheight = deletelayout.getLayoutParams().height;

    }
  • 第五步,测量,和布局控件
  • 第六步,实现ViewDragHelper.Callback();里面几个重要的方法如下:
        //这里判断当前的滑动控件;
@Override
        public boolean tryCaptureView(View child, int pointerId) {}
        //这里是水平方向上做滑动;
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {}
        //当控件位子改变时调用,这里的left是当前滑动子控件的左边距离父控件左边的坐标距离(在父左边为负在右边为正)
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {}
        //当手指离开控件时调用。
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
  //首先要得到子控件的x坐标;
  int content_dx = contentlayout.getLeft();
  //再根据子控件的x坐标进行判断位子。最后调用一下动画到所要到的子定位置;
  ViewDragHelper.smoothSlideViewTo(View view,x,y);
    view 为所需要动画的View对象,
    “x,y”分别为指定该控件要到达的“左,上”坐标值;
}

最后为了动画加上一段代码让其动画看上去更加的流畅。代码如下:直接粘贴复制就行了,这是一段固定代码;

 // 持续平滑动画 高频调用
    public void computeScroll() {
        // 如果返回true,动画还需要继续
        if (dragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

完整代码如下:

package com.example.selfviewdemo;

import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

/**
 * Created by yuchao on 17/2/10.
 */
public class ViewDragHelperTest extends LinearLayout {

    private static final String TAG = ViewDragHelperTest.class.getSimpleName();
    private ViewDragHelper dragHelper;
    private View contentlayout;
    private View deletelayout;
    private int mContentheight;
    private int mDeletewidth;
    private int mDeleteheight;

    public ViewDragHelperTest(Context context) {
        this(context, null);
    }

    public ViewDragHelperTest(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ViewDragHelperTest(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        dragHelper = ViewDragHelper.create(this, mCallback);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        contentlayout = getChildAt(0);//内容区域
        deletelayout = getChildAt(1);//侧滑菜单

        //得到布局的宽高;
        mContentheight = contentlayout.getLayoutParams().height;
        mDeletewidth = deletelayout.getLayoutParams().width;
        mDeleteheight = deletelayout.getLayoutParams().height;

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d(TAG, "onMeasure: mDeletewidth = " + mDeletewidth);
        //1.测量content
        int contentHight = MeasureSpec.makeMeasureSpec(mContentheight, MeasureSpec.EXACTLY);
        contentlayout.measure(widthMeasureSpec, contentHight);
        //1.测量delete
        int deleteHight = MeasureSpec.makeMeasureSpec(mDeleteheight, MeasureSpec.EXACTLY);
        int deleteWidth = MeasureSpec.makeMeasureSpec(mDeletewidth, MeasureSpec.EXACTLY);
        deletelayout.measure(deleteWidth, deleteHight);

        //setMeasuredDimension(widthMeasureSpec, contentHight);
        setMeasuredDimension(widthMeasureSpec, contentHight);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        Log.d(TAG, "onLayout: enter");
        int dx = 0;
        contentlayout.layout(0 - dx, 0, contentlayout.getMeasuredWidth(), contentlayout.getMeasuredHeight());

        deletelayout.layout(contentlayout.getMeasuredWidth() - dx, 0,
                contentlayout.getMeasuredWidth() + deletelayout.getMeasuredWidth() - dx
                , deletelayout.getMeasuredHeight());
    }

    private ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {

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

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if (child == contentlayout) {
                if (left > 0) {
                    return 0;
                } else if (left < -mDeletewidth) {
                    return -mDeletewidth;
                }
            } else if (child == deletelayout) {
                if (left > contentlayout.getMeasuredWidth()) {
                    return contentlayout.getMeasuredWidth();
                } else if (left < contentlayout.getMeasuredWidth() - mDeletewidth) {
                    return contentlayout.getMeasuredWidth() - mDeletewidth;
                }
            }
            return left;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            //移动内容
            if (changedView == contentlayout) {
                //改变删除组件的位置
                int deleteleft = contentlayout.getMeasuredWidth() + left;
                int deletetop = 0;
                int deleteright = deleteleft + deletelayout.getMeasuredWidth();
                int deletebottom = deletelayout.getMeasuredHeight();
                deletelayout.layout(deleteleft, deletetop, deleteright, deletebottom);
            } else if (changedView == deletelayout) {
                int contentLeft = left - contentlayout.getMeasuredWidth();
                int contentTop = 0;
                int contentRight = contentLeft + contentlayout.getMeasuredWidth();
                int contentbotton = contentlayout.getMeasuredHeight();
                contentlayout.layout(contentLeft, contentTop, contentRight, contentbotton);
            }
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            //松开手;
            //得到contentlayout的X坐标;
            int content_dx = contentlayout.getLeft();
            if (content_dx < -deletelayout.getMeasuredWidth() / 2) {
                dragHelper.smoothSlideViewTo(contentlayout, -deletelayout.getMeasuredWidth(), 0);
                dragHelper.smoothSlideViewTo(deletelayout, contentlayout.getMeasuredWidth() - deletelayout.getMeasuredWidth(), 0);
                invalidate();
            } else {
                dragHelper.smoothSlideViewTo(contentlayout, 0, 0);
                dragHelper.smoothSlideViewTo(deletelayout, contentlayout.getMeasuredWidth(), 0);
                invalidate();
            }
        }
    };

    // 持续平滑动画 高频调用
    public void computeScroll() {
        // 如果返回true,动画还需要继续
        if (dragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return dragHelper.shouldInterceptTouchEvent(ev);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        dragHelper.processTouchEvent(event);
        return true;
    }

}

有什么不足的地方希望能给出一些建议!感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值