【问题标题】:listview gives wrong item on click after filtering过滤后listview在点击时给出错误的项目
【发布时间】:2020-06-14 10:47:53
【问题描述】:

我有一个listView,带有一个实现可过滤的自定义适配器。过滤器功能终于可以正常工作了,直到我尝试在listView 中打开一个项目。当我尝试打开过滤后的结果时,它会将我移至错误的活动。我经历了一些与其他帖子不同的方法,其中一个(最新尝试)在下面的代码中标记为注释。

对我来说奇怪的是为什么会出现这个问题,因为我使用的是一个简单的“if-else”案例......

另一个帖子,我再也找不到了,建议使用我不太熟悉的 set/get-tag。我还怀疑问题可能出在过滤器中,因为过滤器没有给出arrayList,而是它的过滤版本。但是,我也想不通。

感谢任何帮助!

MainActivity 深入到它的核心:

public class MainActivity extends AppCompatActivity implements TextWatcher{
    MyAdapter adapter;`

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

        ListView lw = findViewById(R.id.lw);
        Button notiz = findViewById(R.id.btnNotiz);
        Button merk = findViewById(R.id.btnMerk);
        EditText suche = findViewById(R.id.suchen);

        lw.setLongClickable(true);

        final ArrayList<Objekt> arrayList = new ArrayList();

        arrayList.add(new Objekt("AAA", "AAA-Street"));
        arrayList.add(new Objekt( "BBB","BBB-Street")); // and so on

        adapter = new MyAdapter(this,arrayList);
        suche.addTextChangedListener(this);

        Collections.sort(arrayList, new Comparator<Objekt>() {
            @Override
            public int compare(Objekt o1, Objekt o2) {
              return o1.getKuerzel().compareToIgnoreCase(o2.getKuerzel());
            }
        });

        lw.setAdapter(adapter);

        lw.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                TextView textView = view.findViewById(R.id.textViewFullAdress);
                ClipboardManager cm = (ClipboardManager)
                        getSystemService(Context.CLIPBOARD_SERVICE);
                assert cm != null;
                cm.setText(textView.getText().toString());

                Toast.makeText(MainActivity.this, "Kopiert!", Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        lw.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String selection = arrayList.get(position).getKuerzel();
                //one of the things I've tried: Objekt selection = (Objekt)((MyAdapter)parent.getAdapter()).getItem(position);
                if(selection.equals("AAA")){
                    Intent intent0 = new Intent(MainActivity.this, AAA.class);
                    startActivity(intent0);
                } else if(selection.equals("BBB")){
                    Intent intent0 = new Intent(MainActivity.this, BBB.class);
                    startActivity(intent0);
                } //and so on
           }
        });

    }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            adapter.getFilter().filter(s);
        }

        @Override
        public void afterTextChanged(Editable s) {

        }

我的适配器:

public class MyAdapter extends BaseAdapter implements Filterable {

    Context context;
    ArrayList<Objekt> arr, tempArr;
    CustomFilter cs;

    public MyAdapter(Context context, ArrayList<Objekt> arr) {
        this.context = context;
        this.arr = arr;
        this.tempArr = arr;
    }

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

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

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

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

        convertView = LayoutInflater.from(context).inflate(R.layout.adapter_view_layout,parent,false);

        TextView kuerzel = convertView.findViewById(R.id.textViewKuerzel);
        TextView fullAdress = convertView.findViewById(R.id.textViewFullAdress);

        kuerzel.setText(arr.get(position).getKuerzel());
        fullAdress.setText(arr.get(position).getFullAdress());

        return convertView;
    }

    @Override
    public Filter getFilter() {
        if (cs == null){
            cs = new CustomFilter();
        }

    return cs;
    }

    class CustomFilter extends Filter{
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            if (constraint != null && constraint.length()>0) {
                constraint = constraint.toString().toUpperCase();

                ArrayList<Objekt> filters = new ArrayList<Objekt>();

                for (int i = 0; i < tempArr.size(); i++) {
                    if (tempArr.get(i).getKuerzel().toUpperCase().contains(constraint)) {
                        Objekt objekt = new Objekt(tempArr.get(i).getKuerzel(), tempArr.get(i).getFullAdress());
                        filters.add(objekt);
                    }
                }
                results.count = filters.size();
                results.values = filters;
            }
            else
            {
                results.count = tempArr.size();
                results.values = tempArr;
            }
            return results;
        }

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

对象:

public class Objekt {

    String kuerzel;
    String fullAdress;

    public Objekt(String kuerzel, String fullAdress) {
        this.kuerzel = kuerzel;
        this.fullAdress = fullAdress;
    }

    public String getKuerzel() {
        return kuerzel;
    }

    public void setKuerzel(String kuerzel) {
        this.kuerzel = kuerzel;
    }

    public String getFullAdress() {
        return fullAdress;
    }

    public void setFullAdress(String fullAdress) {
        this.fullAdress = fullAdress;
    }
}

我还没有完全弄清楚这里的格式,对不起...

【问题讨论】:

    标签: android listview filter onclick


    【解决方案1】:

    在 MyAdapter 类中应用过滤器后,MyAdapter 中的 arr 和 MainActivity 中的 arrayList 中的元素会有所不同。例如,如果最初您的列表包含 ['AAA','BBB','AAC','CCC','DDD'] 那么两个列表将具有相同的元素:

    arrayList = ['AAA','BBB','AAC','CCC','DDD'] // in MainActivity
    arr = ['AAA','BBB','AAC','CCC','DDD'] // in MyAdapter
    

    现在,如果您通过键入“AA”来应用过滤器,arr 的元素将被更新,但 arraylist 将保持不变。

    arrayList = ['AAA','BBB','AAC','CCC','DDD'] // in MainActivity
    arr = ['AAA','AAC'] // in MyAdapter
    

    现在,如果用户从列表中选择了第二个元素,即在索引 1 处。 在您的 MainActivity 中,您使用了 String selection = arrayList.get(position).getKuerzel();

    当您从 arrayList 中选择索引 1 时,它将返回“BBB”。

    解决问题的方法是在onTextChanged方法中过滤arrayList。

     @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            adapter.getFilter().filter(s);
            //filter arrayList
        }
    

    【讨论】:

    • 非常感谢您的详尽回答!由于我对应用程序编程相当陌生,因此我不确定如何继续在 onTextChanged 方法中过滤 arrayList... public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter ().filter(s); adapter.getFilter().filter(arrayList.toString());我不确定如何过滤 arrayList :thinking:
    猜你喜欢
    • 2021-04-28
    • 2021-04-27
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多