zoukankan      html  css  js  c++  java
  • 个人技术总结—列表搜索

    1、技术概述

    1. 技术概述

    利用数据适配器类实现列表搜索功能。

    1. 原因

    需要为用户提供搜索筛选功能,方便用户快速查找信息。

    1. 难点

    数据适配器及过滤器类的书写,数据刷新显示。

    2、技术详述

    最初在网上查阅了大量的代码,通过阅读多分代码比较会发现他们的一些相同的地方,这部分就是这个功能的关键部分了,然后仔细阅读这部分的代码,大致搞懂它的实现逻辑之后就自己动手参照着写代码了。实现过程如下:

    1. 写一个类实现适配器接口,用于适配需要展示的列表数据
    
    /**
     *数据适配器
     *
     */
    class RecomendAdapter extends BaseAdapter implements Filterable {
        Context context;
        List<Periodic> data; //这个数据是会改变的,所以要有个变量来备份一下原始数据
        List<Periodic> backData;//用来备份原始数据
        MyFilter mFilter ;
    
        
        public RecomendAdapter(Context context, List<Periodic> data) {
            this.context = context;
            this.data = data;
            backData = data;
        }
    
        
        @Override
        public int getCount() {
            return data.size();
        }
    
        
        @Override
        public Object getItem(int i) {
            return data.get(i);
        }
    
        
        @Override
        public long getItemId(int i) {
            return 0;
        }
    
        
        public  void addItem(Periodic obj){
            data.add(obj);
        }
    
        
        public void removeItem(int index){
            Periodic tep = data.get(index);
            backData.remove(tep);
            data.remove(tep);
        }
    
    
        public void clearAll(){
           data.clear();
           backData.clear();
        }
    
        
        public void setData(List<Periodic> data){
            this.data = data;
            backData = data;
        }
        
        
        @Override
        public View getView(int position, View view, ViewGroup viewGroup) {
            if (view ==null){
                view = LayoutInflater.from(context).inflate(R.layout.periodic_list_item,null);
            }
    
           //从数组中得到数据并然后给页面组件设置值
            Periodic periodicItem=data.get(position);
            TextView nameView = (TextView)view.findViewById(R.id.periodic_item_name);
            TextView moneyView = (TextView)view.findViewById(R.id.periodic_item_money);
            TextView startView = (TextView)view.findViewById(R.id.periodic_item_start);
            TextView endView = (TextView)view.findViewById(R.id.periodic_item_end);
            //设置periodic项目的值,信息
            //时间格式化
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            String tmpMoney=null;
            if(periodicItem.getType()==0){//支出
                tmpMoney = "-" + String.valueOf(periodicItem.getPeriodic_money());
                moneyView.setTextColor(Color.parseColor("#ff0000"));
            }
            else {//收入
                tmpMoney = "+" + String.valueOf(periodicItem.getPeriodic_money());
                moneyView.setTextColor(Color.parseColor("#00ff00"));
            }
            nameView.setText(periodicItem.getPeriodic_name());
            moneyView.setText(String.valueOf(periodicItem.getPeriodic_money()));
            startView.setText(format.format(periodicItem.getStart()));
            endView.setText(format.format(periodicItem.getEnd()));
            return view;
        }
        
        
        /**
         * 当ListView调用setTextFilter()方法的时候,便会调用该方法
         * @return 过滤器类
         */
        @Override
        public Filter getFilter() {
            if (mFilter ==null){
                mFilter = new MyFilter();
            }
            return mFilter;
        }
        
    }
    
    1. 写一个过滤类根据用户输入进行数据筛选,并刷新数据
     /**
         * 定义一个过滤器的类来定义过滤规则
         */
        class MyFilter extends Filter{
            /**
             * 义过滤规则
             * @param charSequence 输入的字符文本
             * @return
             */
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults result = new FilterResults();
                List<Periodic> list ;
                if (TextUtils.isEmpty(charSequence)){//当过滤的关键字为空的时候,我们则显示所有的数据
                    list  = backData;
                }else {//否则把符合条件的数据对象添加到集合中
                    list = new ArrayList<>();
                    for (Periodic recomend:backData){
                        if (recomend.getPeriodic_name().contains(charSequence)){
                            list.add(recomend);
                        }
                    }
                }
                result.values = list; //将得到的集合保存到FilterResults的value变量中
                result.count = list.size();//将集合的大小保存到FilterResults的count变量中
                return result;
            }
    
    
            /**
             * 告诉适配器更新界面
             * @param charSequence
             * @param filterResults
             */
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                data = (List<Periodic>)filterResults.values;
                if (filterResults.count>0){
                    notifyDataSetChanged();//通知数据发生了改变
                }else {
                    notifyDataSetInvalidated();//通知数据失效
                }
            }
        }
    
    
    1. 为列表注册适配器并添加搜索框事件响应处理
     searchPeriodic.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                /**
                 * 当点击搜索按钮时触发该方法
                 * @param query 输入的字符串
                 * @return
                 */
                @Override
                public boolean onQueryTextSubmit(String query) {
                    //提交搜索后的处理逻辑
                    return false;
                }
                
                
                /**
                 * 当搜索内容改变时触发该方法,时刻监听输入搜索框的值
                 * @param newText 当前输入的文本
                 * @return
                 */
                @Override
                public boolean onQueryTextChange(String newText) {
                    //如果newText长度不为0
                    if (TextUtils.isEmpty(newText)){
                        //清除ListView的过滤
                        listView.clearTextFilter();
                    }else{
                        //使用用户输入的内容对ListView的列表项进行过滤
                        listView.setFilterText(newText);
                    }
                    return true;
                }
            });
    

    3、遇到的问题和解决方法

    • 列表数据不刷新

    每次更改数据后要调用数据适配器的notifyDataSetChanged() 方法通知数据的变化

    4、总结

    最初列表展示的适配器是简单的数组适配器,并不能满足搜索的功能需求,在查阅资料后发现需要重写适配器才能达到功能需求,刚开始感觉这挺难的,但好在网上的资料足够丰富,也找到了一些例子可供参考,最后还是实现了这个功能。总之,遇到困难要抱着积极的态度去尝试解决。

    5、参考文献,博客等

  • 相关阅读:
    ps制作gif
    安装pycocotools错误
    labelimg最新版本的使用攻略
    1_0day安全漏洞分析技术学习_二进制文件概述_笔记
    2.陈治瑄问题,汉字写入数据库报错。这个汉字有什么特殊的吗?
    1.PHP中报出use of undefined constant count
    [转] 关于Multi-head的为什么
    [转] GPT、GPT-2到GPT-3概览
    [转] RoBERTa介绍
    [转] ELMo原理解析及简单上手使用
  • 原文地址:https://www.cnblogs.com/jiruqianlong/p/13185383.html
Copyright © 2011-2022 走看看