一站式筛选:Android自定义View多菜单封装解决方案之使用篇

1,102 阅读3分钟

前言

对于多菜单筛选,我们先看两个竞品,分别是美团和携程的

竞品效果图
  • 美团切换的方案,是先关闭已展开的,关闭之后再展开新的,有点相当于有几个tab,就有几个Menu布局
  • 携程切换方案就比较生硬,没有动画,看起来很难受
效果图

多条目菜单删选.gif

添加依赖

Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
  • Step 2. Add the dependency
implementation 'com.github.Peakmain:BasicUI:+'
  • Step 3.some probleam

    如果你的gradle版本比3.5.3高,可能会出现以下几个问题:

    1、Entry name 'AndroidManifest.xml' collided

    解决办法:在gradle.properties添加以下代码

    android.useNewApkCreator=false
    

    2、如果安装失败,用adb install安装报错提示如下

    failed to install app-debug.apk: Failure [INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: Failed to parse /data/app/vmdl1335956833.tmp/base.apk: Corrupt XML binary file]

    解决办法:在添加依赖的build.gradle中添加以下代码

    android{
        packagingOptions {
         exclude 'AndroidManifest.xml'
      }
    }
    

如何使用多菜单筛选

一、添加布局
 <com.peakmain.ui.widget.menu.ListMenuView
    android:id="@+id/list_data_screen_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
二、设置适配器

适配器继承BaseListMenuAdapter,会重写三个方法:

  1. getTitleLayoutId: 设置标题布局
  2. getMenuLayoutId(int position):设置菜单布局,可根据不同position设置不同的布局
  3. setMenuContent(View menuView, final int position):设置菜单里面的内容。menu是每个位置的View

默认情况下,打开菜单的时候,标题字体的颜色#01a8e3,关闭菜单的时候,标题字体的颜色为Color.BLACK,如果你想修改打开菜单或者关闭菜单的时候标题样式,你可以重写以下两个方法

  1. openMenu(@NonNull View tabView)
  2. closeMenu(@NonNull View tabView)
1、getTitleLayoutId()设置标题布局
    @Override
    public int getTitleLayoutId() {
        return R.layout.ui_list_data_screen_tab;
    }
2、getMenuLayoutId(int position):设置菜单布局,可根据不同position设置不同的布局
    @Override
    protected int getMenuLayoutId(int position) {
        if (position == 0)//推荐排序
            return R.layout.layout_menu_recommend_sort;
        else if (position == 1 || position == 2)//酒店品牌和热门地点
            return R.layout.layout_menu_brand;
        else
            //综合筛选
            return R.layout.layout_categorize_screen;
    }
3、setMenuContent(View menuView, final int position):设置菜单里面的内容
@Override
protected void setMenuContent(View menuView, final int position) {
    if (menuView == null) return;
    if (position == 0) {
        RecyclerView recyclerView = menuView.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
        recyclerView.setAdapter(new MenuRecommendSortAdapter(mContext, mRecommendSortList));
    } else if (position == 1) {
        TextView tvBrandTitle = menuView.findViewById(R.id.tv_brand_title);
        tvBrandTitle.setText("品牌偏好");
        RecyclerView recyclerView = menuView.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new GridLayoutManager(mContext, 3));
        recyclerView.setAdapter(new MenuBrandAdapter(mContext, mBrandList));
    } else if (position == 2) {
        TextView tvBrandTitle = menuView.findViewById(R.id.tv_brand_title);
        tvBrandTitle.setText("热门住宿地");
        RecyclerView recyclerView = menuView.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new GridLayoutManager(mContext, 3));
        recyclerView.setAdapter(new MenuHotCityAdapter(mContext, mCityList));
    } else {
         //综合筛选
        RecyclerView rvLeft = menuView.findViewById(R.id.rv_left);
        rvLeft.setLayoutManager(new LinearLayoutManager(mContext));
        MenuLeftRecyclerAdapter leftRecyclerAdapter =
                new MenuLeftRecyclerAdapter(mContext, mLeftMenuList);
        rvLeft.setAdapter(leftRecyclerAdapter);

        RecyclerView rvRight = menuView.findViewById(R.id.rv_right);
        rvRight.setLayoutManager(new LinearLayoutManager(mContext));
        rvRight.setAdapter(new MenuRightRecyclerAdapter(mContext, mCategoryRightBeans));
        LinearLayoutManager rvRightLayoutManager = (LinearLayoutManager) rvRight.getLayoutManager();
        leftRecyclerAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                int selectPosition = leftRecyclerAdapter.mSelectPosition;
                if (selectPosition == position) return;
                leftRecyclerAdapter.setSelectItem(position);

                rvRightLayoutManager
                        .scrollToPositionWithOffset(position, 0);
            }
        });
        rvRight.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int firstVisibleItemPosition = rvRightLayoutManager.findFirstVisibleItemPosition();
                if (firstVisibleItemPosition != -1) {
                    rvLeft.smoothScrollToPosition(firstVisibleItemPosition);
                    leftRecyclerAdapter.setSelectItem(firstVisibleItemPosition);
                }
            }
        });
    }
}
4、重写打开菜单时标题的样式
@Override
public void openMenu(@NonNull View tabView) {
    super.openMenu(tabView);
    ((ImageView)tabView.findViewById(R.id.iv_down)).setImageResource(R.drawable.ic_triangle_up);
}
5、重写关闭菜单时标题的样式
@Override
public void closeMenu(@NonNull View tabView) {
    TextView textView = tabView.findViewById(R.id.tv_menu_tab_title);
    textView.setTextColor(ContextCompat.getColor(mContext,R.color.color_272A2B));
    ((ImageView)tabView.findViewById(R.id.iv_down)).setImageResource(R.drawable.ic_triangle_down);
}
三、设置adapter即可,需要将标题集合传进去
  mMenuView = findViewById(R.id.list_data_screen_view);
  mMenuView.setAdapter(adapter);//自己的适配器

总结

  • 上面中我们主要介绍自定义View实现多菜单筛选的封装的使用,用户不需要关心底层打开菜单、关闭菜单和切换菜单的动画效果
  • 使用也是非常简单的,就三步,一、使用布局ListMenuView,二、为ListMenuView设置适配器,三、调用listMenuView的setAdapter将适配器和View进行绑定
  • 如果大家觉得有帮助,欢迎大家点个小星星哦
  • 项目的github地址:github.com/Peakmain/Ba…