【问题标题】:Bypassing the bug in filtering that does not update ListView Android绕过过滤中不更新 ListView Android 的 bug
【发布时间】:2013-11-22 14:04:14
【问题描述】:

这是代码,我使用了自定义适配器,并应用了 Filter 方法,现在 ListView 在输入退格键时不会更新,当从项目活动切换回来时。我读到它是过滤器中的一个错误,但我如何绕过它,我知道已经实现了我想要的这种设置的应用程序。

public class IndexPageActivity extends Activity implements OnItemClickListener{ 
    ListView listView;
    EditText editTextB;
    PagesAdapter adapter1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.pageList);
        editTextB = (EditText) findViewById(R.id.searchB);
        adapter1 = new PagesAdapter(this);
        listView.setAdapter(adapter1);
        adapter1.notifyDataSetChanged();
        listView.setOnItemClickListener(this);

        editTextB.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                IndexPageActivity.this.adapter1.getFilter().filter(cs.toString());
                adapter1.notifyDataSetChanged();
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1,
                        int arg2, int arg3) { }

            @Override
            public void afterTextChanged(Editable arg0) { }
        });
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
        Intent i;
        String name = adapter1.getItem(position);
        Log.d("id", name);

        if (name.equals("Item1"))
        {
            i = new Intent(this, anActivity.class);
            startActivity(i);
        }
        else if (name.equals("Item2"))
        {
            i = new Intent(this, anActivity2.class);
            startActivity(i);
        }
    }
}

class SingleRow {
    String pagedata;
    SingleRow(String pagedata){
        this.pagedata=pagedata;
    }
}
class PagesAdapter extends BaseAdapter implements Filterable{
    ArrayList<String> pagelist;
    List<String> arrayList;
    Context context;
    String [] pagedatas;

    PagesAdapter(Context c){
        context=c;
        pagelist = new ArrayList<String>();
        Resources res = c.getResources();
        pagedatas = res.getStringArray(R.array.pages_data);
        for (int i=0;i<463;i++){
            pagelist.add(pagedatas[i]);
        }
    }
    @Override
    public int getCount() {
        return pagelist.size();
    }

    @Override
    public String getItem(int i) {
        return pagelist.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewG) {
        LayoutInflater inflater=(LayoutInflater)             context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View row=inflater.inflate(R.layout.single_row,viewG,false);
        TextView pagetitle = (TextView) row.findViewById(R.id.textViewRow);

        String temp=pagelist.get(i);

        pagetitle.setText(temp);
        return row;
    }

    public class filter_here extends Filter{
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults Result = new FilterResults();
            // if constraint is empty return the original names
            if(constraint.length() == 0 ){
                Result.values = pagelist;
                Result.count = pagelist.size();
                return Result;
            }

            ArrayList<String> Filtered_Names = new ArrayList<String>();
            String filterString = constraint.toString().toLowerCase();
            String filterableString;

            for(int i = 0; i<pagelist.size(); i++){
                filterableString = pagelist.get(i);
                if(filterableString.toLowerCase().contains(filterString)){
                    Filtered_Names.add(filterableString);
                }
            }
            Result.values = Filtered_Names;
            Result.count = Filtered_Names.size();

            return Result;
        }

        @Override
        protected void publishResults(CharSequence constraint,FilterResults results) {
            pagelist = (ArrayList<String>) results.values;
            notifyDataSetChanged();
        }
    }

    @Override
    public Filter getFilter() {
        return new filter_here();
    }
}

【问题讨论】:

    标签: android listview android-listview android-filterable


    【解决方案1】:

    1) 退格过滤

    在您的publishResults 中,您正在修改您的pagelist,因此如果您按退格键并再次过滤,pagelist 仅包含原始pagelist 条目的一小部分:

    因此,您需要保留原始数据的副本!比如:

    List<String> allData;
    
    PagesAdapter(Context c) {
        ...
        allData = pagelist;
        ...
    }
    

    在您的过滤方法中,使用 allData 对象:

    for (int i = 0; i < allData.size(); i++) {
        filterableString = allData.get(i);
        if (filterableString.toLowerCase().contains(filterString)) {
            Filtered_Names.add(filterableString);
        }
    }
    

    以及您将数据重置为原始数据的位置:

    // if constraint is empty return the original names
    if (constraint.length() == 0) {
        Result.values = allData;
        Result.count = allData.size();
        return Result;
    }
    

    2) 从另一个活动返回后清除过滤器:

    这可以在 onResume 中完成...就个人而言,我会清除 editText 中的文本以重置过滤器,如下所示:

    @Override
    protected void onResume() {
        if (editTextB != null) {
            editTextB.setText("");
        }
        super.onResume();
    }
    

    【讨论】:

      【解决方案2】:

      终于找到了退格的bug,你的过滤函数有一些错误,返回的是一个ArrayList,而不是保存变量的List,最终代码应该是:

      public class IndexPageActivity extends Activity implements OnItemClickListener{ 
      ListView listView;
      EditText editTextB;
      PagesAdapter adapter1;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          // TODO Auto-generated method stub
          super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
              listView = (ListView) findViewById(R.id.pageList);
              editTextB = (EditText) findViewById(R.id.searchB);
              adapter1 = new PagesAdapter(this);
              listView.setAdapter(adapter1);
              adapter1.notifyDataSetChanged();
              listView.setOnItemClickListener(this);
      
              editTextB.addTextChangedListener(new TextWatcher() {
      
                  @Override
                  public void onTextChanged(CharSequence cs, int arg1, int arg2,
                          int arg3) {
                      // When user changed the Text
                      IndexPageActivity.this.adapter1.getFilter().filter(cs.toString());
                      adapter1.notifyDataSetChanged();
                  }
      
                  @Override
                  public void beforeTextChanged(CharSequence arg0, int arg1,
                          int arg2, int arg3) {
                      // TODO Auto-generated method stub
      
                  }
      
                  @Override
                  public void afterTextChanged(Editable arg0) {
                      // TODO Auto-generated method stub
                  }
              });
      }
      
      
      @Override
      public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
      // TODO Auto-generated method stub
      Intent i;
      String name = adapter1.getItem(position);
              Log.d("id", name);
      if (name.equals("Item1"))
      {
          i = new Intent(this, anActivity.class);
          startActivity(i);
      }
      else if (name.equals("Item2"))
      {
          i = new Intent(this, anActivity2.class);
          startActivity(i);
      }
      }
      }
      
      
      class SingleRow {
      String pagedata;
      SingleRow(String pagedata){
          this.pagedata=pagedata;
      }
      }
      class PagesAdapter extends BaseAdapter implements Filterable{
      ArrayList<String> pagelist;
      List<String> arrayList;
      Context context;
      String [] pagedatas;
      
      PagesAdapter(Context c){
      context=c;
      pagelist = new ArrayList<String>();
      Resources res = c.getResources();
      pagedatas = res.getStringArray(R.array.pages_data);
      
      for (int i=0;i<463;i++){
          pagelist.add(pagedatas[i]);
      }
      arrayList = pagelist;
      }
      @Override
      public int getCount() {
      // TODO Auto-generated method stub
      return arrayList.size();
      }
      
      @Override
      public void notifyDataSetChanged() {
      super.notifyDataSetChanged();
      }
      
      @Override
      public String getItem(int i) {
      // TODO Auto-generated method stub
      return arrayList.get(i);
      }
      
      @Override
      public long getItemId(int i) {
      // TODO Auto-generated method stub
      return i;
      }
      
      
      @Override
      public View getView(int i, View view, ViewGroup viewG) {
      // TODO Auto-generated method stub
      LayoutInflater inflater=(LayoutInflater)                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      View row=inflater.inflate(R.layout.single_row,viewG,false);
      TextView pagetitle = (TextView) row.findViewById(R.id.textViewRow);
      
      String temp=arrayList.get(i);
      
      pagetitle.setText(temp);
      return row;
      }
      
      @Override
      public Filter getFilter() {
      // TODO Auto-generated method stub
      Filter filter = new Filter() {
          @SuppressWarnings("unchecked")
          @Override
          protected void publishResults(CharSequence constraint, FilterResults results) {
      
              arrayList = (List<String>) results.values;
              notifyDataSetChanged();
          }
      
          @Override
          protected FilterResults performFiltering(CharSequence constraint) {
      
           FilterResults results = new FilterResults();
              ArrayList<String> FilteredArrayNames = new ArrayList<String>();
      
              if (pagelist == null)    {
                  pagelist = new ArrayList<String>(arrayList);
              }
              if (constraint == null || constraint.length() == 0) {
                  results.count = pagelist.size();
                  results.values = pagelist;
              } else {
                  constraint = constraint.toString().toLowerCase();
                  for (int i = 0; i < pagelist.size(); i++) {
                      String dataNames = pagelist.get(i);
                      if (dataNames.toLowerCase().startsWith(constraint.toString()))  {
                          FilteredArrayNames.add(dataNames);
                      }
                  }
      
                  results.count = FilteredArrayNames.size();
                  System.out.println(results.count);
      
                  results.values = FilteredArrayNames;
                  Log.e("VALUES", results.values.toString());
              }
      
              return results;
      }
      };
      return filter;
      }
      }
      

      【讨论】:

      • 谢谢您,我将输入此内容并尽快回复您!非常感谢.. All Credits to You Coderji!
      • 是的 Coderji!它确实有效,另一件事出现了,当我在editText中输入说Twinkle时,它带来了相关的项目,当我使用退格键将它们全部删除时,显示的列表将以第一个字母“T”开头的项目在闪烁。如果在editText中输入了Chocolate,当退格时,只有以“C”开头的项目才会显示在ListView中。老板干得好!
      • 奇怪?!除了onItemClick,你有没有改变任何东西?在我这边的应用程序。它就像一个魅力
      • 能用,能用,一定是我用的模拟器。它确实有效!耶!谢谢 Coderji!
      • 我很高兴帮助你,男人从中学到了很多东西 :) 希望我值得评价 ;)
      【解决方案3】:

      怎么放

      adapter1.notifyDataSetChanged();
      

      在Activity的onResume()方法中?

      【讨论】:

        猜你喜欢
        • 2011-03-25
        • 2016-07-30
        • 2011-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-21
        • 1970-01-01
        • 2011-10-17
        相关资源
        最近更新 更多