前言
用ViewDragHelper实现小圆点.
ViewDragHelper 拖动效果,对onInterceptTouchEvent onTouchEvent进行了封装,Android开发者可以不用深度去了解View的事件分发就特效拖拉的代码。包括侧滑删除、IOS小圆点。这里我分享一下AssistiveTouch的实现,废话不说,先效果 再代码。
效果:
代码:
package com.steptowin.eshop.common.viewgroup;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import com.steptowin.library.base.app.LogStw;
/**
* Created by fjw on 2017/9/28.
* [email protected]
* http://blog.csdn.net/u011850446/article/details/78136299
*/
public class DragViewLayout extends FrameLayout {
private View view_one;
private ViewDragHelper mDragHelper;
public DragViewLayout(Context context) {
this(context, null);
}
public DragViewLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DragViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallback());
}
class DragHelperCallback extends ViewDragHelper.Callback {
/**
* 进行捕获拦截,那些View可以进行drag操作
*
* @param child
* @param pointerId
* @return 直接返回true,拦截所有的VIEW
*/
@Override
public boolean tryCaptureView(View child, int pointerId) {
return /*view_one == child*/true;
}
/**
* 水平滑动 控制left
*
* @param child
* @param left
* @param dx
* @return
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//LogStw.d("DragLayout", "clampViewPositionHorizontal " + left + "," + dx);
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - view_one.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}
/**
* 垂直滑动,控制top
*
* @param child
* @param top
* @param dy
* @return
*/
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
LogStw.d("DragLayout", "clampViewPositionVertical " + top + "," + dy);
final int topBound = getPaddingTop();
final int bottomBound = getHeight() - view_one.getHeight();
final int newTop = Math.min(Math.max(top, topBound), bottomBound);
return newTop;
}
@Override
public int getViewHorizontalDragRange(View child) {
return getMeasuredWidth() - child.getMeasuredWidth();
}
@Override
public int getViewVerticalDragRange(View child) {
return getMeasuredHeight() - child.getMeasuredHeight();
}
/**
* 当手指松开的时候回调方法
*
* @param xvel
* @param yvel
* @paramreleasedChild 滑动手指松开的View
*/
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
//LogStw.e("onViewReleased", ("getLeft:" + view_one.getLeft() + ", getTop=" + view_one.getTop()));
float maxHeight = getHeight() - view_one.getHeight();
float maxWidth = getWidth() - view_one.getWidth();
float x = view_one.getLeft();
float y = view_one.getTop();
float diffx = maxWidth - x;
float diffy = maxHeight - y;
float min = Math.min(Math.min(Math.min(x, y), diffx), diffy);
if (min == x)
//左移动
if (mDragHelper.smoothSlideViewTo(view_one, 0, (int) y)) {
ViewCompat.postInvalidateOnAnimation(DragViewLayout.this);
}
if (min == diffx)
//右移动
if (mDragHelper.smoothSlideViewTo(view_one, (int) maxWidth, (int) y)) {
ViewCompat.postInvalidateOnAnimation(DragViewLayout.this);
}
if (min == y)
//上移动
if (mDragHelper.smoothSlideViewTo(view_one, (int) x, 0)) {
ViewCompat.postInvalidateOnAnimation(DragViewLayout.this);
}
if (min == diffy)
//下移动
if (mDragHelper.smoothSlideViewTo(view_one, (int) x, (int) maxHeight)) {
ViewCompat.postInvalidateOnAnimation(DragViewLayout.this);
}
//离左轴的距离 x
//离右轴的距离 maxRight - x
//离顶轴的距离 y
//离底轴的距离 winWidth - y
//mDragHelper.smoothSlideViewTo(view_one, 0, 0);
invalidate();
}
}
@Override
public void computeScroll() {
super.computeScroll();
if (mDragHelper.continueSettling(true)) {
invalidate();
}
}
/**
* 事件分发
*
* @param ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercept = mDragHelper.shouldInterceptTouchEvent(ev);
//LogStw.e("intercept", String.valueOf(intercept));
return intercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
mDragHelper.processTouchEvent(ev);
return true;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
view_one = getChildAt(1);
}
}
注意问题
@Override
protected void onFinishInflate() {
super.onFinishInflate();
view_one = getChildAt(1);//这里的1 对于你们来说不一定是1
// 可以传一个属性过来 说明是第几个Child是小圆点
}
好了 完毕。
API介绍
//固定写法 绑定this View与 ViewDragHelper工厂 ,不用理解
mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallback());
//固定写法 ViewDragHelper帮助处理 onInterceptTouchEvent onTouchEvent,不用理解
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercept = mDragHelper.shouldInterceptTouchEvent(ev);
//LogStw.e("intercept", String.valueOf(intercept));
return intercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
mDragHelper.processTouchEvent(ev);
return true;
}
//onFinishInflate这里去拿ChlidView
protected void onFinishInflate() {
super.onFinishInflate();
view_one = getChildAt(1);
}
//固定写法 处理松手滚动效果 ,不用理解
@Override
public void computeScroll() {
super.computeScroll();
if (mDragHelper.continueSettling(true)) {
invalidate();
}
}
//松手回调 **关键代码** 这里看情况处理 配合打印日志理解 最终算出效果
onViewReleased
//当View有点击事件的时候需要添加 不用理解。
@Override
public int getViewHorizontalDragRange(View child) {
return getMeasuredWidth() - child.getMeasuredWidth();
}
@Override
public int getViewVerticalDragRange(View child) {
return getMeasuredHeight() - child.getMeasuredHeight();
}
//控制滑动范围的两个方法 如果没有滑动范围要求按如下填写,**最好理解**。
/**
* 水平滑动 控制left
*
* @param child
* @param left
* @param dx
* @return
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//LogStw.d("DragLayout", "clampViewPositionHorizontal " + left + "," + dx);
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - view_one.getWidth();
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}
/**
* 垂直滑动,控制top
*
* @param child
* @param top
* @param dy
* @return
*/
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
LogStw.d("DragLayout", "clampViewPositionVertical " + top + "," + dy);
final int topBound = getPaddingTop();
final int bottomBound = getHeight() - view_one.getHeight();
final int newTop = Math.min(Math.max(top, topBound), bottomBound);
return newTop;
}
配合onFinishInflate 使用判断那些View可以进行拖拉操作
/**
* 进行捕获拦截,那些View可以进行drag操作
*
* @param child
* @param pointerId
* @return 直接返回true,拦截所有的VIEW
*/
@Override
public boolean tryCaptureView(View child, int pointerId) {
return /*view_one == child*/true;
}
总结
除了上面不用理解的,需要理解的就是onFinishInflate、tryCaptureView、onViewReleased三个方法了。Copy这份代码然后在这几个方法上改动就能写出大部分Viewgroup拖拉效果了。是不是很心动,快去试试吧。转载来自http://blog.csdn.net/u011850446/article/details/78136299。