美文网首页it菜鸟升职记android shareAndroid知识
栗子——ListView实现筛选菜单滑动吸顶悬停

栗子——ListView实现筛选菜单滑动吸顶悬停

作者: 淡漠de人生 | 来源:发表于2016-05-30 21:33 被阅读3592次

    用ListView实现滑动到筛选菜单的位置是,筛选菜单滑动吸顶悬停的效果。

    栗子配图.png

    先来看下需求吧!

    需求.png
    1. 头部--头部有两排按钮,这个直接ListView+头部实现
    2. 下拉筛选(顶部悬停)--在按钮下方是下拉筛选,这个要实现顶部悬停效果,就是当下拉筛选滑出界面时要在顶部悬停
    3. 列表数据这个就不多说了~

    栗子惯例,先上GIF

    Demo效果.gif

    首先为ListView添加head

    为item填充假数据,填充数据不在赘述。

    /** 列表 */
    private ListView lvIfication;
    /**适配器 */
    private MainAdapter adapter;
    
    /** 头部View*/
    View view = View.inflate(this, R.layout.list_header, null);
    adapter = new MainAdapter(this);
    lvIfication.addHeaderView(view);
    lvIfication.setAdapter(adapter);
    

    添加不悬浮的筛选按钮

    在前面的代码基础上添加一组按钮充当下拉筛选View(这个View是只有需要按钮的点击效果,但是要和悬浮的下拉筛选的UI效果一致)

    点击事件只是点击后,先移动到第二的Item,然后显示真的下拉筛选组件,然后触发点击事件弹出筛选条件。

    adapter = new MainAdapter(this);
    lvIfication.addHeaderView(view);
    //将充当下拉筛选的View,添加到头部
    lvIfication.addHeaderView(hoverView);
    lvIfication.setAdapter(adapter);
    //监听listview的滑动
    lvIfication.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {}
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            //从0开始,当item为1代表滑动到了充当下拉筛选的View,
            //此时显示悬浮按钮(真正的下拉筛选),否则隐藏
            if (firstVisibleItem >= 1) {
                invis.setVisibility(View.VISIBLE);
            } else {
                invis.setVisibility(View.GONE);
            }
        }
    });
    //设置按钮的点击事件
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.llHoverType:
            lvIfication.setSelection(1);//移动到Item1
            invis.setVisibility(View.VISIBLE);//显示悬浮按钮(真正的下拉筛选)
            chooseType.performClick();//触发点击事件展开筛选列表
        break;
        case R.id.llHoverRegion:
            lvIfication.setSelection(1);
            invis.setVisibility(View.VISIBLE);
            chooseLabel.performClick();
        break;
        case R.id.llHoverSort:
            lvIfication.setSelection(1);
            invis.setVisibility(View.VISIBLE);
            chooseOrder.performClick();
        break;
        }
    }
    

    设置悬浮的筛选按钮及数据填充

    这里我改过原来Demo的代码~具体不清楚的可以查看【参考1】。

    private class DropdownButtonsController implements
        DropdownListView.Container {
        private DropdownListView currentDropdownList;
        // 全部标签
        private List<DropdownItemObject> datasetAllLabel;
        // 标签集合
        private List<DropdownItemObject> datasetLabel = datasetAllLabel;
        // 全部分类
        private List<DropdownItemObject> datasetType;
        // 地区
        private List<DropdownItemObject> datasetMyLabel;
        // 排序
        private List<DropdownItemObject> datasetOrder;
    
        @Override
        public void show(DropdownListView view) {
            if (currentDropdownList != null) {
                currentDropdownList.clearAnimation();
                currentDropdownList.startAnimation(dropdown_out);
                currentDropdownList.setVisibility(View.GONE);
                currentDropdownList.button.setChecked(false);
            }
            currentDropdownList = view;
            mask.clearAnimation();
            mask.setVisibility(View.VISIBLE);
            currentDropdownList.clearAnimation();
            currentDropdownList.startAnimation(dropdown_in);
            currentDropdownList.setVisibility(View.VISIBLE);
            currentDropdownList.button.setChecked(true);
        }
    
        @Override
        public void hide() {
            if (currentDropdownList != null) {
                currentDropdownList.clearAnimation();
                currentDropdownList.startAnimation(dropdown_out);
                currentDropdownList.button.setChecked(false);
                mask.clearAnimation();
                mask.startAnimation(dropdown_mask_out);
            }
            currentDropdownList = null;
        }
    
        @Override
        public void onSelectionChanged(DropdownListView view) {
            String Content = view.button.textView.getText().toString();
            updateLabels(getCurrentLabels());
             //分类点击
            if (view == dropdownType) {
                tvHoverType.setText(Content);
            }
            // 地区点击
            else if (view == dropdownLabel) {
                tvHoverRegion.setText(Content);
            }
            // 排序点击
            else if (view == dropdownOrder) {
                tvHoverSort.setText(Content);
            }
    
        }
    
        void reset() {
            chooseType.setChecked(false);
            chooseLabel.setChecked(false);
            chooseOrder.setChecked(false);
    
            dropdownType.setVisibility(View.GONE);
            dropdownLabel.setVisibility(View.GONE);
            dropdownOrder.setVisibility(View.GONE);
            mask.setVisibility(View.GONE);
    
            dropdownType.clearAnimation();
            dropdownLabel.clearAnimation();
            dropdownOrder.clearAnimation();
            mask.clearAnimation();
        }
    
        void init() {
            reset();
    
            typeAll = new ArrayList<String>();
            typeAll.add(0, "分类");
            typeAll.add(1, "分类1");
            typeAll.add(2, "分类2");
            labelAll = new ArrayList<String>();
            labelAll.add(0, "地区");
            labelAll.add(1, "地区1");
            labelAll.add(2, "地区2");
            orderAll = new ArrayList<String>();
            orderAll.add(0, "排序");
            orderAll.add(1, "正序");
            orderAll.add(2, "倒序");
    
            // 全部标签
            datasetAllLabel = new ArrayList<DropdownItemObject>();
            // 标签集合
            datasetLabel = datasetAllLabel;
            // 全部分类
            datasetType = new ArrayList<DropdownItemObject>();
            // 地区
            datasetMyLabel = new ArrayList<DropdownItemObject>();
            // 排序
            datasetOrder = new ArrayList<DropdownItemObject>();
            for (int i = 0; i < typeAll.size(); i++) {
                datasetType.add(new DropdownItemObject(typeAll.get(i), i,
                        typeAll.get(i)));
            }
            dropdownType.bind(datasetType, chooseType, this, 0);
    
            for (int i = 0; i < labelAll.size(); i++) {
                datasetMyLabel.add(new DropdownItemObject(labelAll.get(i), i,
                        labelAll.get(i)));
            }
            dropdownLabel.bind(datasetMyLabel, chooseLabel, this, 0);
    
            for (int i = 0; i < orderAll.size(); i++) {
                datasetOrder.add(new DropdownItemObject(orderAll.get(i), i,
                        orderAll.get(i)));
            }
    
            dropdownOrder.bind(datasetOrder, chooseOrder, this, 0);
    
            dropdown_mask_out
                .setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {}
    
                    @Override
                    public void onAnimationEnd(Animation animation) {
                        if (currentDropdownList == null) {
                            reset();
                        }
                    }
    
                @Override
                public void onAnimationRepeat(Animation animation) {}
            });
        }
    
        private List<DropdownItemObject> getCurrentLabels() {
            return datasetAllLabel;
        }
    
        void updateLabels(List<DropdownItemObject> targetList) {
            if (targetList == getCurrentLabels()) {
                datasetLabel = targetList;
            }
        }
    }
    

    这里放一下布局吧!还是有点繁琐的
    activity_main.xml

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.dmdrs.headdropdown.MainActivity" >
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <ListView
                android:id="@+id/lvIfication"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:footerDividersEnabled="false" />
    
            <View
                android:id="@+id/mask"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#80000000" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >
    
                <LinearLayout
                    android:id="@+id/invis"
                    android:layout_width="match_parent"
                    android:layout_height="48dp"
                    android:background="@color/white"
                    android:gravity="center"
                    android:visibility="gone" >
    
                    <com.dmdrs.headdropdown.view.DropdownButton
                        android:id="@+id/chooseType"
                        android:layout_width="0px"
                        android:layout_height="match_parent"
                        android:layout_weight="1" />
    
                    <View
                        android:layout_width="0.5dp"
                        android:layout_height="18dp"
                        android:background="#dddddd" />
    
                    <com.dmdrs.headdropdown.view.DropdownButton
                        android:id="@+id/chooseLabel"
                        android:layout_width="0px"
                        android:layout_height="match_parent"
                        android:layout_weight="1" />
    
                    <View
                        android:layout_width="0.5dp"
                        android:layout_height="18dp"
                        android:background="#dddddd" />
    
                    <com.dmdrs.headdropdown.view.DropdownButton
                        android:id="@+id/chooseOrder"
                        android:layout_width="0px"
                        android:layout_height="match_parent"
                        android:layout_weight="1" />
                </LinearLayout>
    
                <View
                    android:layout_width="match_parent"
                    android:layout_height="0.5dp"
                    android:background="@color/divide" />
    
                <com.dmdrs.headdropdown.view.DropdownListView
                    android:id="@+id/dropdownType"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" />
    
                <com.dmdrs.headdropdown.view.DropdownListView
                    android:id="@+id/dropdownLabel"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" />
    
                <com.dmdrs.headdropdown.view.DropdownListView
                    android:id="@+id/dropdownOrder"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" />
            </LinearLayout>
        </FrameLayout>
    </RelativeLayout>
    

    list_header.xml

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    
        <TextView
            android:background="#FF3BBD79"
            android:layout_width="match_parent"
            android:layout_height="120dp" />
    </LinearLayout>
    

    list_hover_head.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="wrap_content"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:background="@color/white"
            android:gravity="center" >
    
            <LinearLayout
                android:id="@+id/llHoverType"
                android:layout_width="0px"
                android:layout_weight="1"
                android:gravity="center"
                android:layout_height="match_parent">
                <TextView
                    android:id="@+id/tvHoverType"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="分类"
                    android:textSize="14sp"
                    android:layout_centerInParent="true"
                    android:drawablePadding="2dp"
                    android:drawableRight="@drawable/ic_dropdown_normal"
                    android:ellipsize="end"
                    android:maxLines="1"
                    android:singleLine="true"/>
             </LinearLayout>
    
             <View
                android:layout_width="0.5dp"
                android:layout_height="18dp"
                android:background="#dddddd" />
    
             <LinearLayout
                android:id="@+id/llHoverRegion"
                android:layout_width="0px"
                android:layout_weight="1"
                android:gravity="center"
                android:layout_height="match_parent">
                <TextView
                    android:id="@+id/tvHoverRegion"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="地区"
                    android:textSize="14sp"
                    android:layout_centerInParent="true"
                    android:drawablePadding="2dp"
                    android:drawableRight="@drawable/ic_dropdown_normal"
                    android:ellipsize="end"
                    android:maxLines="1"
                    android:singleLine="true"/>
            </LinearLayout>
    
            <View
                android:layout_width="0.5dp"
                android:layout_height="18dp"
                android:background="#dddddd" />
    
            <LinearLayout
                android:id="@+id/llHoverSort"
                android:layout_width="0px"
                android:layout_weight="1"
                android:gravity="center"
                android:layout_height="match_parent">
            <TextView
                    android:id="@+id/tvHoverSort"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="排序"
                    android:textSize="14sp"
                    android:layout_centerInParent="true"
                    android:drawablePadding="2dp"
                    android:drawableRight="@drawable/ic_dropdown_normal"
                    android:ellipsize="end"
                    android:maxLines="1"
                    android:singleLine="true"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    

    总结

    其实实现起来也不是很复杂,主要的核心代码都贴上了,实在没搞懂的,可以解读参考的两个例子的代码。


    参考如下,感谢作者:
    参考1:Android 简单实现ListView顶部悬浮效果
    参考2:过滤功能的下拉菜单FilterDropDownMenu


    警告:不建议使用这种方法实现,后期发现BUG,如果只有一条数据就会出现滑动问题,但是还是有解决方案的,另一种实现方式移步本人另一篇文章Android新特性之筛选菜单,虽然这篇文章有问题未解决,但是学技术要有专研精神,从中也能学到东西,所以没有删除这篇文章,毕竟是花了很多的时间来写的,勿喷!!!


    未经本人允许禁止转载,违者必究


    个人博客:WWW.FJ917.COM
    简书:www.jianshu.com/u/3d2770e6e489

    欢迎加入QQ交流群657206000点我加入
    QQ交流群:657206000

    相关文章

      网友评论

      • 69959bed43b2:请问点击筛选按钮之后是如何更新listview里面的筛选按钮来保持同步的?
        //分类点击
        if (view == dropdownType) {
        tvHoverType.setText(Content);
        }
        作者是在这里更新的,但是如何在DropdownButtonsController里拿到listview头部里的tvHoverType呢?
      • fendo:赞一个!!
        淡漠de人生: @fendo 谢谢😀
      • 浅笑_JIE:用 CoordinatorLayout 和 CollapsingToolbarLayout 和 RecyclerView 可以实现你的需求 还更加简单
        淡漠de人生:@浅笑_JIE 嗯嗯,多谢,回头研究研究😊
      • 风之丨旅人:非常好,亲一个!
        淡漠de人生: @javakam 谢谢。么么哒!
      • 醉酒肆之:类团购,蛮实用呢
        淡漠de人生:@醉酒肆之 嗯嗯,有用就行。哈哈
      • cb2794101ef2:楼主数据为空的别忘了处理
        淡漠de人生:@Mulqueen 这个是必须的。呵呵
      • 79d7fe0fb071:这个滚动位置是个关注点,还有一般需求可能要求底部添加占位,占位的高度我没有处理好,不过大方面没什么特殊问题,哈哈哈哈
        淡漠de人生:@HTML5_ 只是提供个方向,其他需求要看情况处理了!
      • 这条鱼有点甜:地区支持三级联动吗?
        淡漠de人生:@Zaaach 因为项目没这个需求,没往这方面考虑~等有时间我考虑下这种需求!٩(๑^o^๑)۶
        这条鱼有点甜: @淡漠de人生 (๑′°︿°๑)
        淡漠de人生:@Zaaach 不支持😊,只是个简单的筛选

      本文标题:栗子——ListView实现筛选菜单滑动吸顶悬停

      本文链接:https://www.haomeiwen.com/subject/twtcdttx.html