【问题标题】:How to implement Search in a Custom ListView in android?如何在android的自定义ListView中实现搜索?
【发布时间】:2018-06-21 14:21:26
【问题描述】:

我的应用程序中有一个编辑文本和一个列表视图,我的列表视图显示联系人列表。我想要带有edittext的listview过滤器。我在谷歌上搜索了很多,发现了一些例子,但没有一个对我有用这是我的代码 我的自定义适配器

public class MainActivity extends AppCompatActivity {

private static final int CODE_GET_REQUEST = 1024;
private static final int CODE_POST_REQUEST = 1025;

EditText editTextHeroId, editTextName, editTextRealname, editTextComment;
Spinner spinnerTeam;
ProgressBar progressBar;
ListView listView;
Button buttonAddUpdate;
Button buttonScan;
SearchView searchView;
Adapter HeroAdapter;

private List<Hero> heroList = new ArrayList<Hero>();
boolean isUpdating = false;

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

    editTextHeroId = (EditText) findViewById(R.id.editTextHeroId);
    editTextName = (EditText) findViewById(R.id.editTextName);
    editTextRealname = (EditText) findViewById(R.id.editTextRealname);
    editTextComment = (EditText) findViewById(R.id.editTextComment);
    spinnerTeam = (Spinner) findViewById(R.id.spinnerTeamAffiliation);

    buttonAddUpdate = (Button) findViewById(R.id.buttonAddUpdate);
    buttonScan = (Button) findViewById(R.id.buttonScan);

    progressBar = (ProgressBar) findViewById(R.id.progressBar);
    listView = (ListView) findViewById(R.id.listViewHeroes);
    listView.setTextFilterEnabled(true);
    heroList = new ArrayList<>();

    HeroAdapter adapter = new HeroAdapter(heroList);
    final ArrayAdapter<Hero> HeroAdapter = new ArrayAdapter<Hero>(this, R.layout.layout_hero_list, heroList);
    listView.setAdapter(adapter);

    editTextName.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            HeroAdapter.getFilter().filter(cs);
        }

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

        @Override
        public void afterTextChanged(Editable arg0) {}

    });

适配器

public class HeroAdapter extends ArrayAdapter<Hero> implements Filterable {

    List<Hero> heroList;

    public HeroAdapter(List<Hero> heroList) {
        super(MainActivity.this, R.layout.layout_hero_list, heroList);
        this.heroList = heroList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = getLayoutInflater();
        View listViewItem = inflater.inflate(R.layout.layout_hero_list, null, true);

        final TextView textViewName = listViewItem.findViewById(R.id.textViewName);
        TextView textViewUpdate = listViewItem.findViewById(R.id.textViewUpdate);
        TextView textViewDelete = listViewItem.findViewById(R.id.textViewDelete);

        final Hero hero = heroList.get(position);

        textViewName.setText(hero.getName());

        textViewUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isUpdating = true;
                editTextHeroId.setText(String.valueOf(hero.getId()));
                editTextName.setText(hero.getName());
                editTextRealname.setText(hero.getRealname());
                editTextComment.setText(hero.getRating());
                spinnerTeam.setSelection(((ArrayAdapter<String>) spinnerTeam.getAdapter()).getPosition(hero.getTeamaffiliation()));
                buttonAddUpdate.setText("Update");
            }
        });

        textViewDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

                builder.setTitle("Delete " + hero.getName())
                        .setMessage("Are you sure you want to delete it?")
                        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                deleteHero(hero.getId());
                            }
                        })
                        .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        })
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();
            }
        });
        return listViewItem;
    }

    public Filter getFilter() {

        Filter filter = new Filter() {

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                heroList = (List<Hero>) results.values;
                notifyDataSetChanged();
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                FilterResults results = new FilterResults();
                ArrayList<Hero> heroList = new ArrayList<Hero>();

                // perform your search here using the searchConstraint String.

                constraint = constraint.toString().toLowerCase();
                for (int i = 0; i < heroList.size(); i++) {
                    Hero dataNames = heroList.get(i);
                    if (dataNames.toString().toLowerCase().startsWith(constraint.toString()))  {
                        heroList.add(dataNames);
                    }
                }

                results.count = heroList.size();
                results.values = heroList;
                Log.e("VALUES", results.values.toString());

                return results;
            }
        };

        return filter;
    }
}

当我从edittext填写关键字时,列表数据无法显示,.任何帮助将不胜感激。提前致谢

【问题讨论】:

标签: android json listview search filter


【解决方案1】:

heroList.size() 始终为 0,因此根本不会进入“for (int i = 0; i

您必须删除“ArrayList heroList = new ArrayList();”选择 GLOBAL heroList。

protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();
            **ArrayList<Hero> heroList = new ArrayList<Hero>();**

            // perform your search here using the searchConstraint String.

            constraint = constraint.toString().toLowerCase();
            for (int i = 0; i < heroList.size(); i++) {
                Hero dataNames = heroList.get(i);
                if (dataNames.toString().toLowerCase().startsWith(constraint.toString()))  {
                    heroList.add(dataNames);
                }
            }

            results.count = heroList.size();
            results.values = heroList;
            Log.e("VALUES", results.values.toString());

            return results;
        }

【讨论】:

  • 这是不正确的。新列表是添加过滤结果。删除它将删除其他数据,或添加重复项
  • 我明白了,但 heroList.size() 仍然为 0。程序计数器不会进入“for”。我不确定,但也许本地 heroList 与全局 heroList 冲突
【解决方案2】:

首先,在活动的顶部

Adapter HeroAdapter;

应该是

HeroAdapter adapter;

那么你需要真正初始化那个一个,而不是不同的适配器,甚至是其中的两个

this.heroList = new ArrayList<>();
this.adapter = new HeroAdapter(this, heroList);
listView.setAdapter(adapter);

在您修复适配器的构造函数以接受 Context 而不是耦合到 MainActivity 之后

public class HeroAdapter extends ArrayAdapter<Hero> implements Filterable {

    private List<Hero> heroList;

    public HeroAdapter(Context c, List<Hero> heroList) {
        super(c, R.layout.layout_hero_list, heroList);
        this.heroList = heroList;
    }

然后,当您尝试过滤时,您也会用一个空列表“遮蔽”您的列表。如果您阅读警告,Android Studio 甚至可能会向您指出这一点。

将其重命名为其他名称

FilterResults results = new FilterResults();
List<Hero> filtered = new ArrayList<>();
constraint = constraint.toString().toLowerCase();
for (Hero h : MainActivity.this.heroList) {
     if (h.getName().toLowerCase().startsWith(constraint))  {
         filtered.add(h);
     }
 }

results.count = filtered.size();
results.values = filtered;
return results;

【讨论】:

  • 我遇到了这个问题,错误:找不到符号变量 dataNames
  • 当我尝试在edittext上写入时,列表视图无法显示特定的关键字,它只显示列表中的所有数据。
  • 1) 抱歉打错了 2) 我之前实际上没有实现过 Filterable。我只是在纠正你已经拥有的代码
【解决方案3】:

您在 onTextChanged() 方法中使用了适配器的类名,而不是适配器的对象。

试试这个:

 @Override
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
        String text = editTextName.getText().toString().toLowerCase(Locale.getDefault());
        adapter.filter(text);
    }

【讨论】:

  • 这不是类名。该字段大写
  • 还应该使用cs,而不是从edittext中获取文本
  • 你在这里创建了一个对象: HeroAdapter adapter = new HeroAdapter(heroList);正如我提到的,这需要在 onTextChanged() 中使用:adapter.filter(text)
猜你喜欢
  • 1970-01-01
  • 2017-09-25
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 2014-04-15
  • 1970-01-01
相关资源
最近更新 更多