【问题标题】:Why does searchview only outputs the first item on the listview?为什么searchview只输出listview上的第一项?
【发布时间】:2019-09-13 12:06:36
【问题描述】:

我有一个列表视图,其中包含自定义行。每当我在我的搜索视图上使用过滤器时,只要它可以过滤某些东西,就会只显示第一个项目。我使用数组来存储数据。

例如

items: A, B, C

如果我搜索“A”,它会显示“A”(第一个数据,或者在本例中为行),每当我搜索“B”或“C”时,它仍然显示“A” .然后,每当我搜索除“H”之类的项目以外的任何内容时,它都不会显示任何内容(这是正确的)。

我想通过联系人姓名“mContact”搜索他们。

这些是我的代码:

MainActivity.java

ListView listView;
    TextView totalText;

    String currency = "₱";
    String mContact[] = {"Craig", "Agatha", "Dave", "Brandon", "Russel", "Gleceper", "Percy", "Test"};
    double mDebt[] = {2000, 525, 8000, 5000, 955, 4000, 50123, 51247};
    double mDebtTotal = 0;
    String mDesc[] = {"This is a description... etc", "", "", "", "", "", "", ""};
    String mDate[] = {"Apr. 21, 2016", "", "", "", "", "", "", ""};
    int mImg[] = {R.drawable.debtcontact_craig, R.drawable.debtcontact_agatha, R.drawable.debtcontact_dave, R.drawable.debtcontact_brandon, R.drawable.debtcontact_russel, R.drawable.debtcontact_gleceper, R.drawable.debtcontact_lola, R.drawable.ic_launcher_background};

    MyAdapter adapter;

    DecimalFormat formatter = new DecimalFormat("###,###,###.##");

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

        /* Set text of Total based on total amt of mDebt*/
        totalText = findViewById(R.id.TotalTextView);
        for (double x: mDebt) { //Compute total mDebt
            mDebtTotal += x;
        }
        if (mDebtTotal == 0){ //If mDebtTotal == 0
            totalText.setText("Create a debt with an amount first.");
        } else {
            totalText.setText("Total: " + currency + " " + formatter.format(mDebtTotal));
        }


        /* Display contents of listview*/
        listView = findViewById(R.id.listView);
        adapter = new MyAdapter(this, mContact, mDebt, mDesc, mDate, mImg);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                makeDialog(mContact[i], mDebt[i], mDesc[i], mDate[i]);
            }
        });

    }

    class MyAdapter extends ArrayAdapter<String> {
        Context context;
        String rContact[];
        double rDebt[];
        String rDesc[];
        String rDate[];
        int rImg[];

        MyAdapter(Context c, String contact[], double debt[], String desc[], String date[], int img[]){
            super(c, R.layout.listview_row, R.id.Contact, contact);
            this.context = c;
            this.rContact = contact;
            this.rDebt = debt;
            this.rDesc = desc;
            this.rDate = date;
            this.rImg = img;
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            LayoutInflater layoutInflater = (LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View row = layoutInflater.inflate(R.layout.listview_row, parent, false);
            ImageView images = row.findViewById(R.id.image);
            TextView myContact = row.findViewById(R.id.Contact);
            TextView myDebt = row.findViewById(R.id.Debt);
            TextView myDesc = row.findViewById(R.id.Desc);
            TextView myDate = row.findViewById(R.id.Date);

            images.setImageResource(rImg[position]);
            myContact.setText(rContact[position]);
            myDebt.setText(currency + " " + formatter.format(rDebt[position])); /* Adds currency at the beginning */
            myDesc.setText(rDesc[position]);

            myDate.setText(rDate[position]);

            return row;
        }
    }

MainActivity.java SearchView

@Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_main, menu);

        MenuItem searchItem = menu.findItem(R.id.app_searchbutton);
        searchItem.getActionView();

        SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.setQueryHint("Enter a contact e.g 'Robert'");
        searchView.setIconified(true);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                Toast.makeText(getApplicationContext(), query, Toast.LENGTH_SHORT).show();
                return false;
            }

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

        return super.onCreateOptionsMenu(menu);
    }

【问题讨论】:

    标签: android android-listview searchview


    【解决方案1】:

    ArrayAdapter 创建在构造函数中发送的数组的副本,并将该副本用于所有操作。因此,当您调用 filter() 时,该副本被修改而不是 rContact 数组。因此,当适配器决定只显示列表中的一项时,您从 rContact 填充第一项,该项目始终为“A”。

    替换

    myContact.setText(rContact[position]);
    

    myContact.setText(getItem[position]);
    

    但是您必须自己想办法在其他字段中填充正确的数据。

    【讨论】:

    • 感谢您的建议,它现在将联系人姓名替换为正确的搜索过滤器,但图片保持不变(引用第一行),以及描述和日期。我尝试为每个人替换代码,但应用程序会崩溃。
    • 您要么需要使用 BaseAdapter 并自己编写过滤器逻辑,要么使用其他方式将名称与其他数据相关联
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2016-09-13
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多