zoukankan      html  css  js  c++  java
  • Android ListView快速定位(二)

    方法二:android:textFilterEnabled="true" + Filter

    这个属性在android.widget.AbsListView下,要求adapter必须实现Filterable接口
    索引.png
    参考: http://justcallmebrian.com/?p=149

    实现步骤:

    1.listview
    布局文件中设置android:textFilterEnabled="true"
    或代码中listview.setTextFilterEnabled(true);

    2.adapter实现Filterable接口
    Filterable接口很简单,就只有一个方法
    索引.png
    这里要求返回一个Filter对象。
    Filter是一个抽象类,需要自己写个类MyFilter,重写其中的方法
    索引.png
    performFiltering方法,将用户输入的条件传过来,在这个方法中可以按照自己需要的条件过滤
    publishResults中可以将过滤后的新数据传给adapter(通过一个全局变量 或者自己定义一个变量,提供get方法)

    重写了上述两个方法后,外部可以通过adapter.getFilter().filter(s)完成过滤
    索引.png
    另外,Filter还有一个内部类和一个内部接口
    索引.png
    Filter.FilterListener中有一个onFilterComplete方法
    索引.png
    Filter.FilterResults中有两个成员变量,用于存储过滤时的值
    索引.png

    例: 实现MyFilter

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    private class MyFilter extends Filter{
    
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
    
            //存储过滤的值
            FilterResults retval = new FilterResults(); 
            retval.values = list_data;
            retval.count = list_data.size();
    
            //有筛选条件时,显示被筛选的内容; 没有筛选条件时,显示所有内容
            if(constraint != null && constraint.toString().length() > 0) {
    
                constraint = constraint.toString().toUpperCase();
                List<Map<String, String>> filt = new ArrayList<Map<String, String>>();
                List<Map<String, String>> tmpItems = new ArrayList<Map<String, String>>();
                tmpItems.addAll(origin_items);
                for(int i = 0; i < tmpItems.size(); i++) {
    
                    Map<String, String> sf = tmpItems.get(i);
                    if( sf.get("cid").toUpperCase().contains(constraint)
                    || sf.get("type").toUpperCase().contains(constraint)
                    || sf.get("title").toUpperCase().contains(constraint)
                    || sf.get("answer").toUpperCase().contains(constraint)) {
    
                        filt.add(sf);
    
                    }
    
                }
                retval.count = filt.size();
                retval.values = filt;
    
            }
            return retval;
    
        }
    
    
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
    
            //先清空旧数据
            filteredItems.clear();
            adapter.notifyDataSetChanged();
    
            //再添加新数据
            filteredItems.addAll((List<Map<String, String>>)results.values);
            adapter.notifyDataSetChanged();
            }
    
        }
    
    }
    

    例: 实现Filterable接口

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class MyAdapter extends BaseAdapter implements Filterable{
                   private MyFilter filter;
                    private List<Map<String, String>> filteredItems = new ArrayList<Map<String, String>>();
    
                    public View getView(int position, View convertView, ViewGroup parent) {
                          //操作filteredItems 
                    }
    
                    @Override
    
            public Filter getFilter() {
    
                if(filter == null){
    
                    filter = new MyFilter();
    
                }
                return filter;
    
            }
    
    }
    

    注意: 这里我犯了一个比较严重的错误

    关于过滤后的数据filteredItems的存储,我原来是直接

    1
     filteredItems = (List<Map<String, String>>)results.values;
    

    adapter中的绑定数据的方法也是直接用"="

    1
    2
    3
    4
    5
    6
      public void setData(List<Map<String, String>> list){
    
            this.filteredItems = list;
            this.notifyDataSetChanged();
    
            }
    

    因为我希望筛选的时候,如果条件为空,还是要把原来所有的数据都显示出来。
    然而使用" = " 这个写法其实是将引用指给了我最原始的数据,前后虽然有2个变量,但是指向的是同一个空间。
    那么,当我publishResults时,会先清空旧数据,一旦清空,我的数据就会被我清掉,再也找不回来。

    解决办法:
    后来,我声明时直接给它实例化、分配了新空间。
    使用时统一使用addAll方法,这样就相当于把数据复制一份出来,对复制的数据进行清空。
    那么我每一次筛选条件为空时,还是可以取到原始的所有数据,显示出来。

    效果图:
    图片标题

  • 相关阅读:
    plt/sns draw histgram
    normalization, standardization and regularization
    DTU DeepLearning: exercise 7
    DTU DeepLearning: exercise 6
    pytorch save model + Gmatch4py + jupyter debugger + community structure
    GCN
    networkx graph save and load
    DeepLearningDTU: Building a RNN step by step
    通过属性找方法,传参数
    react语法
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3632520.html
Copyright © 2011-2022 走看看