文章目录
- 前言
- DrawerLayout的单独使用(简单使用)
- 效果图
- 具体实现
- 补充
- DrawerLayout搭配RecycleView实现列表侧滑菜单的使用(仿QQ消息列表)
- 效果图
- 具体实现
前言
本篇文章大致可分为三个部分(可选择性阅读):
一:DrawerLayout的单独使用(简单使用)
二:DrawerLayout搭配RecycleView实现列表侧滑菜单的使用(仿QQ消息列表)
三:DrawerLayout常见错误以及解决方法
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"><!--内容区--><LinearLayoutandroid:id="@+id/view_content"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><ImageViewandroid:layout_width="100dp"android:layout_height="100dp"android:src="@mipmap/ic_launcher" /><Buttonandroid:id="@+id/btn_open"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="打开侧滑栏" /></LinearLayout><!--左侧滑区--><LinearLayoutandroid: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"><Buttonandroid:id="@+id/btn_close"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="关闭所有侧滑栏" /><Buttonandroid:id="@+id/btn_left_close"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="关闭当前侧滑栏" /></LinearLayout><!--右侧滑区--><LinearLayoutandroid: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"><Buttonandroid: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接口的实现
@Overridepublic 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() {@Overridepublic void onDrawerSlide(@NonNull View drawerView, float slideOffset) {//滑动}@Overridepublic void onDrawerOpened(@NonNull View drawerView) {//打开}@Overridepublic void onDrawerClosed(@NonNull View drawerView) {//关闭}@Overridepublic 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.RecyclerViewandroid: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"><LinearLayoutandroid:id="@+id/ll_item"android:layout_width="match_parent"android:layout_height="100dp"android:orientation="horizontal"><ImageViewandroid:id="@+id/iv_icon"android:layout_width="100dp"android:layout_height="match_parent" /><TextViewandroid:id="@+id/txv_name"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:textSize="22sp" /></LinearLayout><LinearLayoutandroid:layout_width="200dp"android:layout_height="100dp"android:layout_gravity="end"><TextViewandroid: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" /><TextViewandroid: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@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void onDrawerSlide(@NonNull View drawerView, float slideOffset) {//DrawerLayout滑动监听holder.llItem.setTranslationX(-(drawerView.getMeasuredWidth() * slideOffset));}@Overridepublic void onDrawerOpened(@NonNull View drawerView) {}@Overridepublic void onDrawerClosed(@NonNull View drawerView) {}@Overridepublic void onDrawerStateChanged(int newState) {}});holder.top.setOnClickListener(new View.OnClickListener() {@Overridepublic 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() {@Overridepublic void onClick(View view) {//List移除当前数据,防止更新时出现数据错乱list.remove(position);//RecycleView移除当前子项(有动画效果)notifyItemRemoved(position);//RecycleView局部更新,防止position错乱notifyItemRangeChanged(position, 1);//关闭侧滑栏,防止删除一项后,侧滑栏还处于开启状态holder.dl.closeDrawers();}});}@Overridepublic 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<>();@Overrideprotected 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);}
}