DrawerLayout(侧滑栏)详解,仿QQ消息列表(置顶、删除)

前言

本篇文章大致可分为三个部分(可选择性阅读):
一:DrawerLayout的单独使用(简单使用)
二:DrawerLayout搭配RecycleView实现列表侧滑菜单的使用(仿QQ消息列表)

DrawerLayout的单独使用(简单使用)

效果图

图中实现的效果汇总:
1.左右侧滑的实现
2.点击按钮打开侧滑栏(单个)
3.点击按钮关闭所有侧滑栏(以及单个关闭)
在这里插入图片描述

具体实现

XML布局
这里需要注意
1.内容区(也就是你不用任何操作显示的区域),布局需要设置成占满父布局match_parent
2.两侧的侧滑栏布局的LinearLayout需要给到android:layout_gravity="start(end)"属性

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--内容区-->
    <LinearLayout
        android:id="@+id/view_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher" />

        <Button
            android:id="@+id/btn_open"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="打开侧滑栏" />

    </LinearLayout>

    <!--左侧滑区-->
    <LinearLayout
        android:id="@+id/view_left"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#3F51B5"
        android:gravity="center"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="关闭所有侧滑栏" />

        <Button
            android:id="@+id/btn_left_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="关闭当前侧滑栏" />

    </LinearLayout>

    <!--右侧滑区-->
    <LinearLayout
        android:id="@+id/view_right"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:background="#2196F3"
        android:gravity="center"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_right_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="关闭当前侧滑栏" />

    </LinearLayout>

</androidx.drawerlayout.widget.DrawerLayout>

Java后台
由于其余部分都是控件的声明,所以这里只贴出核心

//View.OnClickListener接口的实现
@Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_open://打开侧滑栏
                drawerLayout.openDrawer(GravityCompat.START);//打开左边
                drawerLayout.openDrawer(GravityCompat.END);//打开右边
                break;
            case R.id.btn_close://关闭所有侧滑栏
                drawerLayout.closeDrawers();
                break;
            case R.id.btn_left_close://关闭左侧
                drawerLayout.closeDrawer(GravityCompat.START);
                break;
            case R.id.btn_right_close://关闭右侧
                drawerLayout.closeDrawer(GravityCompat.END);
                break;
        }
    }
补充

这里补充几个常用方法:
1.侧滑栏滑出后,内容区的覆盖颜色(侧滑栏滑出后,内容区会有一层灰色覆盖,下面是直接设置成透明覆盖,也就相当于没有覆盖)

//去除侧滑栏滑出后灰色覆盖
drawerLayout.setScrimColor(Color.TRANSPARENT);

2.判断侧滑栏当前状态(是否展开)

//判断左边侧滑栏状态(是否打开)
drawerLayout.isDrawerOpen(GravityCompat.START);
//判断右边侧滑栏状态(是否打开)
drawerLayout.isDrawerOpen(GravityCompat.END);

3.DrawerLayout监听器

drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
                //滑动
            }

            @Override
            public void onDrawerOpened(@NonNull View drawerView) {
                //打开
            }

            @Override
            public void onDrawerClosed(@NonNull View drawerView) {
                //关闭
            }

            @Override
            public void onDrawerStateChanged(int newState) {
                //状态改变
            }
        });

DrawerLayout搭配RecycleView实现列表侧滑菜单的使用(仿QQ消息列表)

效果图

图中实现的效果汇总:
1.RecycleView结合DrawerLayout实现仿QQ消息列表效果
2.侧滑出置顶按钮和删除按钮,并且实现两个按钮效果
在这里插入图片描述

具体实现

XML布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycle_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
</LinearLayout>

XML布局(Item)

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dl"
    android:layout_width="match_parent"
    android:layout_height="100dp">

    <LinearLayout
        android:id="@+id/ll_item"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/iv_icon"
            android:layout_width="100dp"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/txv_name"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="22sp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:layout_gravity="end">

        <TextView
            android:id="@+id/top"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FFEB3B"
            android:gravity="center"
            android:text="置顶"
            android:textSize="26sp" />

        <TextView
            android:id="@+id/del"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#F10001"
            android:gravity="center"
            android:text="删除"
            android:textSize="26sp" />

    </LinearLayout>

</androidx.drawerlayout.widget.DrawerLayout>

Adapter适配器(核心功能区)
功能点汇总:
1.利用DrawerLayout的监听事件实现了RecycleView的子项随着侧滑而向左滑动的效果
2.点击侧滑栏置顶子项
3.置顶后,RecycleView移动到首项
4.点击侧滑栏删除子项
注意:这里的置顶和删除功能最容易出错的就是position容易因为置顶和删除操作导致错乱,所以这里记得每次进行子项的操作要进行局部刷新

置顶功能实现思路:把当前子项内容加到List第一个位置,并且删除当前子项,最后利用LinearLayoutManager让RecycleView滚动到第一项的位置。
为了避免position错乱,先保存好当前子项的值,再删除,最后添加到第一个的位置

public class AdapterDrawer extends RecyclerView.Adapter<AdapterDrawer.ViewHolder> {

    List<BeanDrawer> list;
    LinearLayoutManager manager;

    public AdapterDrawer(List<BeanDrawer> list, LinearLayoutManager manager) {
        this.list = list;
        this.manager = manager;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle_drawer, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
        holder.ivIcon.setImageResource(list.get(position).getIcon());
        holder.txvName.setText(list.get(position).getName());
        //实现仿QQ消息列表,整个子项左移的效果
        holder.dl.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
                //DrawerLayout滑动监听
                holder.llItem.setTranslationX(-(drawerView.getMeasuredWidth() * slideOffset));
            }

            @Override
            public void onDrawerOpened(@NonNull View drawerView) {

            }

            @Override
            public void onDrawerClosed(@NonNull View drawerView) {

            }

            @Override
            public void onDrawerStateChanged(int newState) {

            }
        });
        holder.top.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //置顶思路,把当前子项内容加到List第一个位置,并且删除当前子项(避免position错乱,先保存好值,再删除,再添加)
                String name = list.get(position).getName();
                int icon = list.get(position).getIcon();
                list.remove(position);
                notifyItemRemoved(position);
                //RecycleView局部更新,防止position错乱
                notifyItemRangeChanged(position, 1);
                BeanDrawer beanDrawer = new BeanDrawer();
                beanDrawer.setName(name);
                beanDrawer.setIcon(icon);
                list.add(0, beanDrawer);
                notifyItemInserted(0);
                //RecycleView局部更新,防止position错乱
                notifyItemRangeChanged(0, 1);
                //RecycleView移动到第一项
                manager.scrollToPositionWithOffset(0, 0);
                //关闭侧滑栏
                holder.dl.closeDrawers();
            }
        });
        holder.del.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //List移除当前数据,防止更新时出现数据错乱
                list.remove(position);
                //RecycleView移除当前子项(有动画效果)
                notifyItemRemoved(position);
                //RecycleView局部更新,防止position错乱
                notifyItemRangeChanged(position, 1);
                //关闭侧滑栏,防止删除一项后,侧滑栏还处于开启状态
                holder.dl.closeDrawers();
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private DrawerLayout dl;
        private LinearLayout llItem;
        private ImageView ivIcon;
        private TextView txvName;
        private TextView top;
        private TextView del;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            dl = (DrawerLayout) itemView.findViewById(R.id.dl);
            llItem = (LinearLayout) itemView.findViewById(R.id.ll_item);
            ivIcon = (ImageView) itemView.findViewById(R.id.iv_icon);
            txvName = (TextView) itemView.findViewById(R.id.txv_name);
            top = (TextView) itemView.findViewById(R.id.top);
            del = (TextView) itemView.findViewById(R.id.del);

            //设置侧滑栏划出后,内容区的覆盖颜色(这里设置成透明)
            dl.setScrimColor(Color.TRANSPARENT);
        }
    }
}

Java后台
这里没什么好说的,就是加了10条数据,然后设置了布局管理器,加上了子项的分割线,很简单

public class RecycleDrawerActivity extends AppCompatActivity {

    private RecyclerView recycleView;

    BeanDrawer beanDrawer;
    AdapterDrawer adapterDrawer;
    List<BeanDrawer> list = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycle_drawer);
        initView();
        initData();
        //布局管理器
        LinearLayoutManager manager = new LinearLayoutManager(this);
        //设置成竖直
        manager.setOrientation(RecyclerView.VERTICAL);
        recycleView.setLayoutManager(manager);
        //子项分割线
        recycleView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        adapterDrawer = new AdapterDrawer(list,manager);
        recycleView.setAdapter(adapterDrawer);
    }

    private void initData() {
        for (int i = 0; i < 10; i++) {
            beanDrawer = new BeanDrawer();
            beanDrawer.setIcon(R.mipmap.ic_launcher);
            beanDrawer.setName("天问" + i + "号");
            list.add(beanDrawer);
        }
    }

    private void initView() {
        recycleView = (RecyclerView) findViewById(R.id.recycle_view);
    }
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在 DrawerLayout 中添加多个侧滑,可以使用一个布局来作为容器,然后在该容器中添加多个 Fragment。以下是一种实现方式: 1. 在布局文件中创建一个 DrawerLayout,并且在其中添加一个 FrameLayout 作为侧滑容器。 ```xml <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 主布局 --> <FrameLayout android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- 侧滑容器 --> <FrameLayout android:id="@+id/drawer_container" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" /> </android.support.v4.widget.DrawerLayout> ``` 2. 创建多个侧滑 Fragment,并且分别添加到侧滑容器中。 ```java // 添加第一个侧滑 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.drawer_container, new FirstDrawerFragment()); transaction.commit(); // 添加第二个侧滑 transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.drawer_container, new SecondDrawerFragment()); transaction.commit(); ``` 3. 在主布局中添加菜单按钮,点击菜单按钮时切换侧滑的显示和隐藏状态。 ```java ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawerLayout.addDrawerListener(toggle); toggle.syncState(); // 切换侧滑的显示和隐藏状态 navigationView.setNavigationItemSelectedListener(item -> { drawerLayout.closeDrawer(GravityCompat.START); return true; }); ``` 这样就可以实现 DrawerLayout 中添加多个侧滑的功能了。需要注意的是,多个侧滑之间可能会有冲突,需要按照需求进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值