android自定义控件SwipeLayout实现类似QQ滑动删除效果2

之间就说过还有一个实现方式,一时忙没写。
今天我这里就写下吧。
这个是写了继承LinearLayout的控件。
先说下思路吧,这里我写了个自定义控件SwipeLayout继承了LinearLayout,SwipeLayout包含两个子view,第一个子view是内容区域,第二个子view是操作区域。滑动效果的控制,主要就是通过检测SwipeLayout的touch事件来实现,这里我不想自己去通过监听touch事件来实现滑动效果,那是一个很繁琐的过程。Android support库里其实已经提供了一个很好的工具类来帮我们做这件事情ViewDragHelper。DrawerLayout的滑动效果也是通过ViewDragHelper类实现的。

这里主要注意的提下就算了,剩下你们看代码就好了。
需要注意的就是时间分发,因为这里我们的空间下面有其他的子布局,那么我们本身的滑动效果是在我们的控件处理onTouchEvent吧ViewDragHelper加上去的

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);//执行自己的触摸下效果
        return true;
    }

如果我们不处理的事件分发的,那么我们点击到子布局所在的位置的时候默认的会吧事件分发到子布局,那么我的滑动效果就肯定执行不了,因为我们的所在的viewgroup根本就没有消费事件。所以我们要处理一下,这里用到了onInterceptTouchEvent

 //这里既是个事件分发的拦截  当滑动操作的时候为了防止点击事件分发给子布局 这里我们要返回true事件就会交给自己的onTouchEvent的处理  不然你点击操作区你会发现划不动
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(viewDragHelper.shouldInterceptTouchEvent(ev)) {
            return true;
        }
        return super.onInterceptTouchEvent(ev);
    }

好了剩下就把代码直接给你们吧

这个是SwipeLayout

package com.example.admin.huadongmenu;

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.LinearLayout;

/**
 * 
 */
public class SwipeLayout extends LinearLayout {

    private ViewDragHelper viewDragHelper;
    private View contentView;
    private View actionView;
    private int dragDistance;//操作区域的宽度,用于下面的弹出和影藏的时候判断
    private final double AUTO_OPEN_SPEED_LIMIT = 800.0;
    private int draggedX;

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

    public SwipeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        viewDragHelper = ViewDragHelper.create(this, new DragHelperCallback());
    }

    @Override
    protected void onFinishInflate() {
        contentView = getChildAt(0);//你放入的第一个布局  注意这里只的是它包裹下的第一层布局  子布局不算
        actionView = getChildAt(1);//第二个
        actionView.setVisibility(GONE);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //将操作区域的宽度赋值
        dragDistance = actionView.getMeasuredWidth();
    }

    private class DragHelperCallback extends ViewDragHelper.Callback {

        @Override
        public boolean tryCaptureView(View view, int i) {
            return view == contentView || view == actionView;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            draggedX = left;
            if (changedView == contentView) {
                actionView.offsetLeftAndRight(dx);
            } else {
                contentView.offsetLeftAndRight(dx);
            }
            if (actionView.getVisibility() == View.GONE) {
                actionView.setVisibility(View.VISIBLE);
            }
            invalidate();
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if (child == contentView) {
                final int leftBound = getPaddingLeft();
                final int minLeftBound = -leftBound - dragDistance;
                final int newLeft = Math.min(Math.max(minLeftBound, left), 0);
                return newLeft;
            } else {
                final int minLeftBound = getPaddingLeft() + contentView.getMeasuredWidth() - dragDistance;
                final int maxLeftBound = getPaddingLeft() + contentView.getMeasuredWidth() + getPaddingRight();
                final int newLeft = Math.min(Math.max(left, minLeftBound), maxLeftBound);
                return newLeft;
            }
        }

        @Override
        public int getViewHorizontalDragRange(View child) {
            return dragDistance;
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);
            boolean settleToOpen = false;
            if (xvel > AUTO_OPEN_SPEED_LIMIT) {
                settleToOpen = false;
            } else if (xvel < -AUTO_OPEN_SPEED_LIMIT) {
                settleToOpen = true;
            } else if (draggedX <= -dragDistance / 2) {
                settleToOpen = true;
            } else if (draggedX > -dragDistance / 2) {
                settleToOpen = false;
            }

            final int settleDestX = settleToOpen ? -dragDistance : 0;
            viewDragHelper.smoothSlideViewTo(contentView, settleDestX, 0);
            ViewCompat.postInvalidateOnAnimation(SwipeLayout.this);
        }
    }
    //这里既是个事件分发的拦截  当滑动操作的时候为了防止点击事件分发给子布局 这里我们要返回true事件就会交给自己的onTouchEvent的处理  不然你点击操作区你会发现划不动
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(viewDragHelper.shouldInterceptTouchEvent(ev)) {
            return true;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);//执行自己的触摸下效果
        return true;
    }
    //这里设置拖动后自动返回到原来的位置
    @Override
    public void computeScroll() {
        super.computeScroll();
        if(viewDragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

}

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:droidicon="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <com.example.admin.huadongmenu.SwipeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ffffff">

            <TextView android:text="来向左滑动试试效果!"
                android:textSize="20sp"
                android:paddingLeft="20dp"
                android:layout_gravity="center_vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="150dp"
            android:layout_height="50dp">
            <RelativeLayout
                android:id="@+id/btn_delete"
                android:clickable="true"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#ff0000">
                <View
                    android:layout_centerInParent="true"
                    android:layout_width="28dp"
                    android:layout_height="28dp"
                    android:background="@drawable/trash"/>
            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/btn_find"
                android:clickable="true"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#c2c2c2">
                <View
                    android:layout_centerInParent="true"
                    android:layout_width="28dp"
                    android:layout_height="28dp"
                    android:background="@drawable/magnifier"/>
            </RelativeLayout>

            <RelativeLayout
                android:id="@+id/btn_space"
                android:clickable="true"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#aaffff">
                <View
                    android:layout_centerInParent="true"
                    android:layout_width="28dp"
                    android:layout_height="28dp"
                    android:background="@drawable/star"/>
            </RelativeLayout>
        </LinearLayout>
    </com.example.admin.huadongmenu.SwipeLayout>
</RelativeLayout>

好了就到这里了,你们试试效果吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值