【问题标题】:How to filter in Custom ListView with BaseAdapter如何使用 BaseAdapter 在自定义 ListView 中进行过滤
【发布时间】:2015-05-06 10:10:52
【问题描述】:

我似乎找不到如何使我的自定义 getFilter() 工作。 我的CustomAdapter 扩展了BaseAdapter,据我所知,它没有实现过滤,所以我需要自己做。我尝试了各种方法,但都没有成功。

Q1:方法是什么? (如何正确实现过滤?)

Q2:如何更改我的CustomAdapter(!) 以使过滤成为一项自动功能?

请不要忽视! 提前非常感谢!

这是一段代码:

Main.java

    //  import ....

    public class MainActivity extends Activity  {

    ListView lv;
    Context context;
    EditText et;
    CustomAdapter adapter;
    View v;

    public  int [] Images=   {R.drawable.1,R.drawable.2,R.drawable.3,R.drawable.4};
    public  String [] NameList={"item1","item2","item3","item4"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context=this;

        lv=(ListView) findViewById(R.id.listView);
        adapter = new CustomAdapter(this, fruitNameList,fruitImages);
        lv.setAdapter(adapter);

        et = (EditText)findViewById(R.id.editText);

        /**
         * Enabling Search Filter
         * */
        et.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                MainActivity.this.adapter.getFilter().filter(cs); // !!!!getFilter() is not found I tried to write methods on my own but nothing worked
            }

            @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
            }
        });



   }// end of onCreate

    public void onClick (View v) {
        switch (v.getId()) {
            case R.id.search:
                et.setVisibility(v.VISIBLE);
                et.setHint("Search names...");

                break;
        }
    }

    public void SearchFilterEnable() {
        /**
         * Enabling Search Filter
         * */
        et.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                MainActivity.this.adapter.getFilter().filter(cs);
            }

            @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
            }
        });

    }
}

CustomAdapter.java

  //import...

  public class CustomAdapter extends BaseAdapter implements Filterable{
  String [] result;
  Context context;
  int [] imageId;
  private static LayoutInflater inflater=null;
  public CustomAdapter(MainActivity mainActivity, String[] NameList, int[] Images) {
    result=NameList;
    context=mainActivity;
    imageId=Images;
    inflater = ( LayoutInflater )context.
            getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
    return result.length;
}

@Override
public Object getItem(int position) {
    return position;
}

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

public class Holder
{
    TextView tv;
    ImageView img;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    Holder holder=new Holder();
    View v;
    v = inflater.inflate(R.layout.name_list, null);
    holder.tv=(TextView) v.findViewById(R.id.textView1);
    holder.img=(ImageView) v.findViewById(R.id.imageView1);
    holder.tv.setText('\t'+result[position]);
    holder.img.setImageResource(imageId[position]);
    v.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(context, "You Clicked " + result[position], Toast.LENGTH_LONG).show();
        }
    });

         return v;
    }



}

【问题讨论】:

  • 究竟出了什么问题?您能否发布代码的最小 版本,足以重现该问题?
  • getFilter() 不调用

标签: android filtering baseadapter


【解决方案1】:

一种方法是更改​​适配器的底层数据(也就是过滤数据),然后在适配器上调用notifyDataSetChanged();。如果您这样做,您的 ListView 将被告知数据集已更改并将更新其内容。

您应该在适配器中存储两个数据列表,一个包含原始数据的列表,一个包含过滤数据的列表。适配器本身对过滤后的列表进行操作,每当您调用过滤器方法时,它只会将原始列表中的数据复制到过滤后的列表中(基于您的过滤条件)。

private List<String> originalData;
private List<String> filteredData;

public void filter(String prefix) {
    filteredData = new ArrayList<>();
    for(String data : originalData) {
        if(data.startsWith(prefix)) filteredData.add(data);
    }
    notifyDataSetChanged();
}

【讨论】:

  • 但是我怎样才能调用 getFilter() 呢?
  • 我在答案中添加了一些代码。您不必调用 getFilter(),只需实现一个公共 filter(...) 方法并调用它。并且不要忘记调用 notifyDataSetChanged();在您的自定义过滤方法结束时。
  • 对不起,我在示例中使用了 List 而不是 String 数组。但是您应该很容易将示例转换为使用字符串数组。还是您需要更多代码?
  • 使用我写的不是 List 而是 ArrayList 的字符串数组。现在试图了解在我的代码中删除什么以及在哪里通过你的过滤器方法(我只是初学者)
  • 没关系 ;) 我只是倾向于这样写:private List&lt;String&gt; filteredData = new ArrayList&lt;&gt;();
猜你喜欢
  • 2012-01-24
  • 2012-09-09
  • 2013-03-28
  • 2019-02-13
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多