ListView的自定义过滤器过滤提供了选择的时候错误的项目 [英] ListView custom filter gives wrong item selected when filtered

查看:107
本文介绍了ListView的自定义过滤器过滤提供了选择的时候错误的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的Andr​​oid编程和我有过滤的时候总是返回我的第一个项目列表中的一个ListView,所以我怎么解决这个问题?

例如,我的列表中包含A.A,A·B,A.C,B.C,B.D.当我要搜索的列表中开始为B的东西,我会得到B.C,B.D但是当我点击B.C,它返回我A.A和B.D,它返回我的A·B

我是个星期,我正在寻找一个解决方案!请帮助我!

 公共类MainActivity扩展活动器具
    SearchView.OnQueryTextListener,AdapterView.OnItemClickListener {LV的ListView;
搜索查看search_view;的String [] country_names,iso_ codeS;
TypedArray country_flags;ArrayList的<国家> countrylist;
CustomAdapter适配器;@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);    LV =(ListView控件)findViewById(R.id.list_view);
    sea​​rch_view =(搜索查看)findViewById(R.id.search_view);    country_names = getResources()getStringArray(R.array.country_names)。
    。iso_ codeS = getResources()getStringArray(R.array.iso_ code);
    country_flags = getResources()obtainTypedArray(R.array.country_flags)。    countrylist =新的ArrayList<国家>();
    的for(int i = 0; I< country_names.length;我++){
        国家国家=新的国家(country_names [I],iso_ codeS [I]
                country_flags.getResourceId(I,1));
        countrylist.add(国家);
    }    适配器=新CustomAdapter(getApplicationContext(),countrylist);
    lv.setAdapter(适配器);    sea​​rch_view.setOnQueryTextListener(本);
    lv.setOnItemClickListener(本);
}@覆盖
公共布尔onQueryTextChange(字符串newText){
    。adapter.getFilter()过滤器(newText);
    返回false;
}@覆盖
公共布尔onQueryTextSubmit(查询字符串){
    返回false;
}公共无效onItemClick(适配器视图<> L,视图V,INT位置,长的id){
    Log.i(HelloListView,你点击项目:+身份证+的位置:+位置);
    //然后,你开始通过意向新活动
    意向意图=新的Intent();
    intent.setClass(这一点,ListItemDetail.class);
    intent.putExtra(位置,位置);
    //或/和
    intent.putExtra(ID,身份证);
    startActivity(意向);
}

列表项的细节

 公共类ListItemDetail延伸活动{@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_list_item_detail);    意向意图= getIntent();
    INT位置= intent.getIntExtra(位置,0);    //这里我们把你的string.xml在一个数组
    的String [] = myKeys getResources()getStringArray(R.array.sections)。
    的String [] = myKeys2 getResources()getStringArray(R.array.testo2)。    的String [] = myKeys3 getResources()getStringArray(R.array.testo3)。    的String [] = myKeys4 getResources()getStringArray(R.array.testo4)。    TextView的myTextView =(的TextView)findViewById(R.id.my_textview);
    myTextView.setText(myKeys [位置]);    TextView的myTextView2 =(的TextView)findViewById(R.id.testo2);
    myTextView2.setText(myKeys2 [位置]);    TextView的myTextView3 =(的TextView)findViewById(R.id.testo3);
    myTextView3.setText(myKeys3 [位置]);    TextView的myTextView4 =(的TextView)findViewById(R.id.testo4);
    myTextView4.setText(myKeys4 [位置]);

customlistAdapter

 公共类CustomAdapter扩展BaseAdapter实现过滤的{上下文语境;
ArrayList的<国家> countrylist;
ArrayList的<国家> mStringFilterList;
ValueFilter valueFilter;CustomAdapter(上下文的背景下,ArrayList的<国家> countrylist){
    this.context =背景;
    this.countrylist = countrylist;
    mStringFilterList = countrylist;
}@覆盖
公众诠释的getCount(){
    返回countrylist.size();
}@覆盖
公共对象的getItem(INT位置){
    返回countrylist.get(位置);
}@覆盖
众长getItemId(INT位置){
    返回countrylist.indexOf(的getItem(位置));
}@覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup){    LayoutInflater mInflater =(LayoutInflater)上下文
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);    convertView = NULL;
    如果(convertView == NULL){
        convertView = mInflater.inflate(R.layout.list_item,NULL);        TextView的name_tv =(TextView中)convertView.findViewById(R.id.name);
        TextView的iso_tv =(TextView中)convertView.findViewById(R.id. code);
        ImageView的IV =(ImageView的)convertView.findViewById(R.id.flag);        国家国家= countrylist.get(位置);        name_tv.setText(country.getName());
        iso_tv.setText(country.getIso_ code());        毕加索
                。随着(上下文)
                .load(URL [位置])
                .fit()//稍后会解释
                .centerCrop()
                .into(四);
    }
    返回convertView;
}@覆盖
公共过滤用getFilter(){
    如果(valueFilter == NULL){
        valueFilter =新ValueFilter();
    }
    返回valueFilter;
}私有类ValueFilter扩展过滤器{
    @覆盖
    保护FilterResults performFiltering(CharSequence的约束){
        FilterResults结果=新FilterResults();        如果(约束=空&放大器;!&放大器; constraint.length()大于0){
            ArrayList的<国家> filterList =新的ArrayList<国家>();
            的for(int i = 0; I< mStringFilterList.size();我++){
                如果((mStringFilterList.get(ⅰ).getName()。与toUpperCase())
                        。载(constraint.toString()。与toUpperCase())){                    国家国家=新的国家(mStringFilterList.get(I)
                            .getName(),mStringFilterList.get㈠
                            .getIso_ code(),mStringFilterList.get(I)
                            .getFlag());                    filterList.add(国家);
                }
            }
            results.count = filterList.size();
            results.values​​ = filterList;
        }其他{
            results.count = mStringFilterList.size();
            results.values​​ = mStringFilterList;
        }
        返回结果;    }    @覆盖
    保护无效publishResults(CharSequence的约束,
                                  FilterResults结果){
        countrylist =(ArrayList的<国家>)results.values​​;
        notifyDataSetChanged();
    }}

contry

 公共类国家{字符串名称;
字符串iso_ code;
INT标志;国家(字符串名称,字符串iso_ code,INT标志){
    this.name =名称;
    this.iso_ code = iso_ code;
    this.flag =标志;
}公共字符串getIso_ code(){
    返回iso_ code;
}公共无效setIso_ code(字符串iso_ code){
    this.iso_ code = iso_ code;
}公共字符串的getName(){
    返回名称;
}公共无效setname可以(字符串名称){
    this.name =名称;
}公众诠释getFlag(){    返回标志;
}公共无效setFlag(INT标志){    this.flag =标志;
}


解决方案

我注意到你正在使用的输入 ListItemDetail 活动的位置。这将导致你的问题的位置对于一个给定的项目会被过滤列表中更改。

您应该只是把项目值到意图然后使用这些值,并在 ListItemDetail 不看任何东西

 公共无效onItemClick(适配器视图<> L,视图V,INT位置,长的id){    国家国家=(国家)((CustomAdapter)l.getAdapter())的getItem(位置)。    意向意图=新意图(这一点,ListItemDetail.class);
    intent.putExtra(名,country.getName());
    intent.putExtra(iso_ code,country.getIso_ code());
    intent.putExtra(标记,country.getFlag());
    startActivity(意向);
}

现在改变你的 ListDetailActivity 来使用这些值:

 公共类ListItemDetail延伸活动{    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_list_item_detail);        意向意图= getIntent();
        字符串名称= intent.getStringExtra(名称);
        字符串iso_ code = intent.getStringExtra(iso_ code);
        INT flagResId = intent.getIntExtra(标记);        //使activity_list_item_detail.xml一个TextView名为名
        TextView的nameTextView =(的TextView)findViewById(R.id.name);
        nameTextView .setText(名);        //使activity_list_item_detail.xml一个TextView称为iso_ code
        TextView的ISO codeTextView =(的TextView)findViewById(R.id.iso_ code);
        ISO codeTextView .setText(iso_ code);        //使activity_list_item_detail.xml一个ImageView的所谓的标志
        ImageView的flagImageView =(ImageView的)findViewById(R.id.flag);
        flagImageView.setImageResource(flagResId);
    }
}

请注意本次活动将无法正常工作,直到您更新activity_list_item_detail.xml作为意见提出

I am new to Android programming and I have a ListView when filtered always return me the first item in the list, so how do I fix this?

For instance, my list contains A.A, A.B, A.C, B.C, B.D. When I want to search the list for things starting with B, I will get B.C, B.D but when I click B.C, it returns me A.A and B.D, it returns me A.B

I am weeks I'm looking for a solution! please help me !!

public class MainActivity extends Activity implements
    SearchView.OnQueryTextListener, AdapterView.OnItemClickListener {

ListView lv;
SearchView search_view;

String[] country_names , iso_codes ;
TypedArray country_flags ;

ArrayList<Country> countrylist ;
CustomAdapter adapter;

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

    lv = (ListView) findViewById(R.id.list_view);
    search_view = (SearchView) findViewById(R.id.search_view);

    country_names = getResources().getStringArray(R.array.country_names);
    iso_codes = getResources().getStringArray(R.array.iso_Code);
    country_flags = getResources().obtainTypedArray(R.array.country_flags);

    countrylist = new ArrayList<Country>();
    for (int i = 0; i < country_names.length; i++) {
        Country country = new Country(country_names[i] , iso_codes[i] ,
                country_flags.getResourceId(i, -1) );
        countrylist.add(country);
    }

    adapter = new CustomAdapter(getApplicationContext(), countrylist );
    lv.setAdapter(adapter);

    search_view.setOnQueryTextListener(this);
    lv.setOnItemClickListener(this);










}

@Override
public boolean onQueryTextChange(String newText) {
    adapter.getFilter().filter(newText);
    return false;
}

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

public void onItemClick(AdapterView<?> l, View v, int position, long id) {
    Log.i("HelloListView", "You clicked Item: " + id + " at position:" + position);
    // Then you start a new Activity via Intent
    Intent intent = new Intent();
    intent.setClass(this, ListItemDetail.class);
    intent.putExtra("position", position);
    // Or / And
    intent.putExtra("id", id);
    startActivity(intent);
}

list item detail

public class ListItemDetail extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_item_detail);

    Intent intent = getIntent();
    int position = intent.getIntExtra("position", 0);

    // Here we turn your string.xml in an array
    String[] myKeys = getResources().getStringArray(R.array.sections);
    String[] myKeys2 = getResources().getStringArray(R.array.testo2);

    String[] myKeys3 = getResources().getStringArray(R.array.testo3);

    String[] myKeys4 = getResources().getStringArray(R.array.testo4);



    TextView myTextView = (TextView) findViewById(R.id.my_textview);
    myTextView.setText(myKeys[position]);

    TextView myTextView2 = (TextView) findViewById(R.id.testo2);
    myTextView2.setText(myKeys2[position]);

    TextView myTextView3 = (TextView) findViewById(R.id.testo3);
    myTextView3.setText(myKeys3[position]);

    TextView myTextView4 = (TextView) findViewById(R.id.testo4);
    myTextView4.setText(myKeys4[position]);

customlistAdapter

public class CustomAdapter extends BaseAdapter implements Filterable {

Context context;
ArrayList<Country> countrylist;
ArrayList<Country> mStringFilterList;
ValueFilter valueFilter;



CustomAdapter(Context context , ArrayList<Country> countrylist) {
    this.context = context;
    this.countrylist = countrylist;
    mStringFilterList = countrylist;
}

@Override
public int getCount() {
    return countrylist.size();
}

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

@Override
public long getItemId(int position) {
    return countrylist.indexOf(getItem(position));
}

@Override
public View getView(int position , View convertView , ViewGroup parent ) {

    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

    convertView = null;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item, null);

        TextView name_tv = (TextView) convertView.findViewById(R.id.name);
        TextView iso_tv = (TextView) convertView.findViewById(R.id.code);
        ImageView iv = (ImageView) convertView.findViewById(R.id.flag);

        Country country = countrylist.get(position);

        name_tv.setText(country.getName());
        iso_tv.setText(country.getIso_code());



        Picasso
                .with(context)
                .load(url[position])
                .fit() // will explain later
                .centerCrop()
                .into(iv);
    }
    return convertView;
}

@Override
public Filter getFilter() {
    if (valueFilter == null) {
        valueFilter = new ValueFilter();
    }
    return valueFilter;
}

private class ValueFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults results = new FilterResults();

        if (constraint != null && constraint.length() > 0) {
            ArrayList<Country> filterList = new ArrayList<Country>();
            for (int i = 0; i < mStringFilterList.size(); i++) {
                if ( (mStringFilterList.get(i).getName().toUpperCase() )
                        .contains(constraint.toString().toUpperCase())) {

                    Country country = new Country(mStringFilterList.get(i)
                            .getName() ,  mStringFilterList.get(i)
                            .getIso_code() ,  mStringFilterList.get(i)
                            .getFlag());

                    filterList.add(country);
                }
            }
            results.count = filterList.size();
            results.values = filterList;
        } else {
            results.count = mStringFilterList.size();
            results.values = mStringFilterList;
        }
        return results;

    }

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

}

contry

public class Country {

String name;
String iso_code;
int flag;

Country(String name, String iso_code, int flag) {
    this.name = name;
    this.iso_code = iso_code;
    this.flag = flag;
}

public String getIso_code() {
    return iso_code;
}

public void setIso_code(String iso_code) {
    this.iso_code = iso_code;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getFlag() {

    return flag;
}

public void setFlag(int flag) {

    this.flag = flag;
}

解决方案

I notice you're using the position as input to the ListItemDetail activity. This will cause you problems as the position for a given item will change as the list is filtered.

You should just put the item values into the Intent then use those values and not look anything up in ListItemDetail

public void onItemClick(AdapterView<?> l, View v, int position, long id) {

    Country country = (Country) ((CustomAdapter ) l.getAdapter()).getItem(position);

    Intent intent = new Intent(this, ListItemDetail.class);
    intent.putExtra("name", country.getName());
    intent.putExtra("iso_code", country.getIso_code());
    intent.putExtra("flag", country.getFlag());
    startActivity(intent);
}

Now change your ListDetailActivity to use these values:

public class ListItemDetail extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_item_detail);

        Intent intent = getIntent();
        String name = intent.getStringExtra("name");
        String iso_code = intent.getStringExtra("iso_code");
        int flagResId = intent.getIntExtra("flag");

        // make a TextView in activity_list_item_detail.xml called "name"
        TextView nameTextView = (TextView) findViewById(R.id.name);
        nameTextView .setText(name);

        // make a TextView in activity_list_item_detail.xml called "iso_code"
        TextView isoCodeTextView = (TextView) findViewById(R.id.iso_code);
        isoCodeTextView .setText(iso_code);

        // make an ImageView in activity_list_item_detail.xml called "flag" 
        ImageView flagImageView = (ImageView) findViewById(R.id.flag);
        flagImageView.setImageResource(flagResId);
    }
}

Note this activity won't work until you update your activity_list_item_detail.xml as suggested in the comments

这篇关于ListView的自定义过滤器过滤提供了选择的时候错误的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆