Android仿QQ侧滑(删除、置顶等)功能

实现类似QQ滑动出现可操作项的功能,在网上看到有人自定义LinearLayout实现这个效果,但是灵活性有限。此demo使用开源项目SwipeLayout实现该功能。关于SwipeLayout的常用设置和属性,这里都做介绍,下面进入正题。

一、效果图

swipeLayout.gif

二、代码片段

  • 主页布局和主页的Java代码都和平时使用没有区别,代码没必要贴出来了。这里使用的ListView演示,还可以是GridView,ExpandableListView。
  • 最关键的代码部分,ListView适配器布局:
  • <?xml version="1.0" encoding="utf-8"?>
    <com.daimajia.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/swipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:drag_edge="right">
    
        <LinearLayout
            android:id="@+id/trash"
            android:layout_width="160dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="horizontal"
            android:tag="Bottom">
    
            <TextView
                android:id="@+id/swipe_open"
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#f55509"
                android:gravity="center"
                android:text="打开"
                android:textColor="@android:color/white"
                android:textSize="20sp" />
    
            <TextView
                android:id="@+id/swipe_delete"
                android:layout_width="1dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@android:color/holo_red_dark"
                android:gravity="center"
                android:text="删除"
                android:textColor="@android:color/white"
                android:textSize="20sp" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="5dp">
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_launcher" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/white"
                android:orientation="vertical"
                android:paddingLeft="5dp">
    
                <TextView
                    android:id="@+id/tv_nickname"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="17sp" />
    
                <TextView
                    android:id="@+id/tv_msg"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:textSize="15sp" />
            </LinearLayout>
        </LinearLayout>
    </com.daimajia.swipe.SwipeLayout>
    

    说明:最外层是我们的SwipeLayout,里面是两个LinearLayout,第一层是我们的页面布局,第二层是我们的侧边划出来的布局。关键的属性这里有体现:

    app:drag_edge="right"

    此属性是设置我们的侧边布局划出位置,默认是右边,可以设置左边、底部、顶部。

  • 适配器Java代码:
  • package com.example.mjj.swipelayoutdemo;
    
    import android.content.Context;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.daimajia.swipe.SwipeLayout;
    import com.daimajia.swipe.adapters.BaseSwipeAdapter;
    
    import java.util.List;
    
    /**
     * Description:适配器
     * <p>
     * Created by Mjj on 2016/12/12.
     */
    
    public class MySwipeAdapter extends BaseSwipeAdapter implements View.OnClickListener {
    
        private Context context;
        private List<ItemBean> list;
        private final String TAG = "MySwipeAdapter";
    
        public MySwipeAdapter(Context context, List<ItemBean> list) {
            this.context = context;
            this.list = list;
        }
    
        /**
         * 返回SwipeLayout的ID
         *
         * @param position
         * @return
         */
        @Override
        public int getSwipeLayoutResourceId(int position) {
            return R.id.swipe;
        }
    
        /**
         * 绑定布局
         *
         * @param position
         * @param parent
         * @return
         */
        @Override
        public View generateView(int position, ViewGroup parent) {
            View itemView = View.inflate(context, R.layout.item_swipe, null);
            SwipeLayout swipeLayout = (SwipeLayout) itemView.findViewById(getSwipeLayoutResourceId(position));
    
            // 设置滑动是否可用,默认为true
            swipeLayout.setSwipeEnabled(true);
    
            /**
             * 打开时调用:循环调用onStartOpen,onUpdate,onHandRelease,onUpdate,onOpen,
             * 关闭时调用:onStartClose,onUpdate,onHandRelease,onHandRelease,onUpdate,onClose
             */
            swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
                @Override
                public void onStartOpen(SwipeLayout layout) {
    //                Log.e(TAG, "onStartOpen: ");
                }
    
                @Override
                public void onOpen(SwipeLayout layout) {
    //                Log.e(TAG, "onOpen: ");
                }
    
                @Override
                public void onStartClose(SwipeLayout layout) {
    //                Log.e(TAG, "onStartClose: ");
                }
    
                @Override
                public void onClose(SwipeLayout layout) {
    //                Log.e(TAG, "onClose: ");
                }
    
                @Override
                public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
    //                Log.e(TAG, "onUpdate: ");
                }
    
                @Override
                public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
    //                Log.e(TAG, "onHandRelease: ");
                }
            });
    
            // 设置为true,在当前一条item(除侧滑以外部分)点击时,可收回侧滑出来部分,默认为false
            swipeLayout.setClickToClose(true);
    
            // SwipeLayout单击事件,可替代ListView的OnitemClickListener事件.
            swipeLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    //                Log.e(TAG, "onClick: ");
                }
            });
    
            return itemView;
        }
    
        /**
         * 绑定数据
         *
         * @param position
         * @param convertView
         */
        @Override
        public void fillValues(int position, View convertView) {
            TextView tvNickName = (TextView) convertView.findViewById(R.id.tv_nickname);
            TextView tvMsg = (TextView) convertView.findViewById(R.id.tv_msg);
            TextView tvSwipeOpen = (TextView) convertView.findViewById(R.id.swipe_open);
            TextView tvSwipeDelete = (TextView) convertView.findViewById(R.id.swipe_delete);
            tvNickName.setText(list.get(position).getNickName());
            tvMsg.setText(list.get(position).getMsg());
    
            tvSwipeDelete.setOnClickListener(this);
            tvSwipeOpen.setOnClickListener(this);
        }
    
        @Override
        public int getCount() {
            return list.size();
        }
    
        @Override
        public ItemBean getItem(int i) {
            return list.get(i);
        }
    
        @Override
        public long getItemId(int i) {
            return i;
        }
    
        @Override
        public void onClick(View view) {
            int id = view.getId();
            switch (id) {
                case R.id.swipe_open:
                    // 关闭所有打开的Swipe的item
                    this.closeAllItems();
                    Toast.makeText(context, "Swipe--Open", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.swipe_delete:
                    this.closeAllItems();
                    Toast.makeText(context, "Swipe--Delete", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
    

    说明:和平时我们写的适配器不一样的是继承自BaseSwipeAdapter,需要实现的方法除了图中展示的,还有一个getItemId();再没有别的。这里主要解释下几个平时没有见过的方法:

    public int getSwipeLayoutResourceId(int position)

    此方法返回的是我们的SwipeLayout的ID,而不是布局的ID。

    public View generateView(int position, ViewGroup parent)

    此方法返回的作用是和我们的item布局进行关联的,并在这里设置swipeLayout的相关属性。

    public void fillValues(int position, View convertView)

    此方法用来给我们的item中的控件绑定数据,并根据需要设置事件等操作。

    *三、常用设置介绍*

    1,如果我们的这个适配器是重用的,而有些时候不需要滑动功能,那么可以调用此方法来控制滑动是否可用。  

    swipeLayout.setSwipeEnabled(true);

    2,当我们的侧边布局还出来的时候,此时点击该条item,默认是不会收回的,也就是下面代码默认是false。

    falseswipeLayout.setClickToClose(true);

    3,如演示,当点击了删除或者打开后,划出来的侧边布局自动收回了,及时通过下面的属性closeAllItems()方法控制的。默认是不会收回的。

    this.closeAllItems();

    4,前面已经提到了,我们的侧滑出现的位置,如有需求是需要左边或者右边,别忘了它:

    app:drag_edge="right"

    *四、使用*

    compile 'com.daimajia.swipelayout:library:1.2.0'

    五、总结
    demo已上传至github,链接放在了公众号”code小生”里,关注查看。

    上一篇精彩文章《Android仿简书、微信向右滑动关闭界面

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code小生

有头像,我们容易成为朋友

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值