【Android】毫无耦合性,一个Item根布局搞定 item侧滑删除菜单,像IOS那样简单的使用侧滑删除。

重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup.

本控件不依赖任何父布局,不是针对 RecyclerView、ListView,而是任意的ViewGroup里的childView都可以使用侧滑(删除)菜单。

最新使用说明:http://blog.csdn.net/zxt0601/article/details/53157090

Github传送门:https://github.com/mcxtzhang/SwipeDelMenuLayout


==================================================================================

【1 序言】

伸手党看完1 2 3 可直接去文末下载代码~

侧滑删除的轮子网上有很多,最初在github上看过一个,还是ListView时代,那是一个自定义ListView 实现侧滑删除的,当初就觉得这种做法不是最佳,万一我项目里又同时有自定义ListView的需求,会增加复杂度。

写这篇文章之前又通过毒度搜了一下,排名前几的CSDN文章,都是通过自定义ListVIew和ViewGropup实现的滑动删除。

况且现在是RecyclerView时代,难不成我要把那些代码再自定义RecyclerView写一遍么。

我想说No,网上大多数的做法代码侵入性太强,尽量不要继承 ListVIew 做什么事,换成 RecyclerView 呢,扩展性太局限了,

本文的做法只要在 Item 的根布局换成这个 自定义ViewGroup 即可,完全不 care 你用 RecyclerView 还是 ListVIew,耦合性为 0

听说隔壁IOS 侧滑删除是一个系统自带的控件,那么我们Android党能否也自定义一个ViewGroup控件,然后一劳永逸,每次简单拿来用就好了呢?

自定义ViewGroup实现侧滑删除简单,难得是还要同时 处理多指滑动的屏蔽,防止两个侧滑菜单同时出现,等等,

有办法将这些东西都用一个ViewGroup搞定么?

看本文如何巧用static类变量来解决这些矛盾冲突。

==================================================================================

【2 预览】

那么我们先看一下最终的效果:

非阻塞式Android特色版本(我司自用版本 ) 平滑滚动动画用属性动画实现 ,即使有一个侧滑菜单处于打开状态,在打开其他item侧滑菜单时,依然无阻塞,会自动关闭上次开启的菜单:~


为了满足个别产品的,高仿IOS版本 平滑滚动用Scroller实现 阻塞式交互(自己的说法) 打开了某个侧滑菜单后 点击其他地方会自动关闭这个侧滑菜单 并且不能做其他操作 :



包含且不仅包含以下功能:

1 侧滑拉出菜单。

2 点击除了这个item的其他位置,菜单关闭。

3 侧滑过程中,不许父控件上下滑动。

4 多指同时滑动,屏蔽后触摸的几根手指。

5 不会同时展开两个侧滑菜单。

6 侧滑菜单时 拦截了长按事件。

7 侧滑时,拦截了点击事件(20160905更新)

8 通过开关 isLeftSwipe支持左滑右滑(2016 09 30 更新):


==================================================================================

【3 使用预览】

看起来还不错吧,忽略颜值,可以再细调,主要的是解决了那几个难题,那么,使用起来麻烦么。

<mcxtzhang.listswipemenudemo.view.CstSwipeDelMenuViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true">

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="试试看" />

    <Button
        android:id="@+id/btnDelete"
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:background="@color/red_ff4a57"
        android:text="删除" />

</mcxtzhang.listswipemenudemo.view.CstSwipeDelMenuViewGroup>
就这么简单,

只需要在 侧滑删除的item的layout的xml里,将根布局父控件换成我们的自定义ViewGroup即可。

第一个子View放置item的内容即可(正式项目里一般是一个ViewGroup),

从2+子View开始,是我们的侧滑菜单区域,如我们的demo图,是三个Button。

//注意事项,设置item点击,不能对整个holder.itemView设置咯,只能对第一个子View,即原来的content设置,这算是局限性吧。
(holder.content).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(mContext, ""+mDatas.get(position).name, Toast.LENGTH_SHORT).show();
    }
});

==================================================================================

【4 实现方法】

使用起来这么简单,让我们一步一步实现它吧。

首先说的是,颜值非本文的重点,UI动画仍有调整空间,重要的是在一个自定义ViewGroup里处理那些冲突。

首先,本类继承自ViewGroup,那么onMeasure()和onLayout()方法,就需要我们自己动手写了,而且在上文我们也提到,使用时,第一个子View放置item内容,2+子View为侧滑菜单区域,那么这需要我们在onMeasure()和onLayout()方法里进行一些特殊处理,设置第一个childView宽度为全屏。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //Log.d(TAG, "onMeasure() called with: " + "widthMeasureSpec = [" + widthMeasureSpec + "], heightMeasureSpec = [" + heightMeasureSpec + "]");
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mRightMenuWidths = 0;//由于ViewHolder的复用机制,每次这里要手动恢复初始值
    int childCount = getChildCount();

    //add by 2016 08 11 为了子View的高,可以matchParent(参考的FrameLayout 和LinearLayout的Horizontal)
    final boolean measureMatchParentChildren = MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
    boolean isNeedMeasureChildHeight = false;

    for (int i = 0; i < childCount; i++) {
        View childView = getChildAt(i);
        if (childView.getVisibility() != GONE) {
            //measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0);
            final MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
            mHeight = Math.max(mHeight, childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
            if (measureMatchParentChildren && lp.height == LayoutParams.MATCH_PA
评论 86
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值