防QQ侧滑条目
2017-02-18 19:46
155 查看
每当我们看到侧滑的时候就会不由自主的想到ViewDragHelper,下面我将给大家来介绍关于ViewDragHelper的用法,以及自定义控件中需要注意的点;
第二步初始化ViewDragHelper
第三步拦截事件,这一点非常重要,因为很多新手在做这一步的时候总会忘了他。当然忘记的后果就是没法收到手势事件。而处理方法很简单只需加两行固定的代码就行了。
第四步得到viewgrup中的子控件对象,也是固定代码
第五步,测量,和布局控件
第六步,实现ViewDragHelper.Callback();里面几个重要的方法如下:
最后为了动画加上一段代码让其动画看上去更加的流畅。代码如下:直接粘贴复制就行了,这是一段固定代码;
完整代码如下:
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 4000 ="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; a06b 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; } }
有什么不足的地方希望能给出一些建议!感谢!
相关文章推荐
- 使用RecyclerView打造QQ条目侧滑效果
- 【Android】自定义控件-仿QQ联系人侧滑条目,右侧滑菜单。
- 自定义SwipeLayout--仿QQ侧滑条目
- 一步集成侧滑(删除)菜单,高仿QQ、IOS条目侧滑删除
- 技术共享之QQ条目侧滑菜单
- Android自定义SwipeLayout仿QQ侧滑条目
- 仿QQ条目侧滑置顶与删除
- ViewDragHelper实现QQ条目侧滑效果
- Android DrawerLayout 高仿QQ5.2双向侧滑菜单
- Android自定义View之ListView条目滑动删除(仿QQ5.1)
- Android实现仿QQ5.0的侧滑效果
- 仿QQ新版本侧滑效果
- Android防QQ侧滑菜单
- Android 高仿 QQ5.2 侧滑菜单效果及QQmini效果
- Android listview 侧滑 SwipeListView 详解 实现微信,QQ等滑动删除效果
- Listview侧滑删除(仿QQ侧滑删除)
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭
- 类似qq的侧滑功能
- 再造 “手机QQ” 侧滑菜单(三)——视图联动
- Android UI设计: 仿ios,仿qq实现Listview侧滑出现按钮