【问题标题】:Searching a ListView does not work - why?搜索 ListView 不起作用 - 为什么?
【发布时间】:2019-05-01 16:45:54
【问题描述】:

您好,我在 Dialog 中有一个 listView,并且我已经为 Dialog 设置了一个自定义适配器。

我查找并设置了 addTextChangedListener 但似乎不起作用。

我只想在用户输入编辑文本时搜索列表并刷新列表

请知道我哪里弄错了

这是我的代码

private void showCompaniesDialog(List<Company> companies) {
    if(companies != null) {
        final Dialog dialog = new Dialog(getContext());
        // dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCancelable(false);
        dialog.setContentView(R.layout.dialog_company_listview);

        Button btndialog = (Button) dialog.findViewById(R.id.btndialog);
        btndialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                dialog.dismiss();
            }
        });

        ListView listView = (ListView) dialog.findViewById(R.id.listview);
        //ArrayAdapter arrayAdapter = new ArrayAdapter(getContext(), R.layout.company_list_item, R.id.tv, companies);
        CompanyAdapter companyAdapter = new CompanyAdapter(getActivity(), 0, companies);
        listView.setAdapter(companyAdapter);

        //HERE I SET THE TEXT FILTER ENABLED
        listView.setTextFilterEnabled(true);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //textView.setText("You have clicked : " + companies[position]);
                dialog.dismiss();
            }
        });

        //HERE I ADD CHANGED LISTENER
        EditText etSearch = (EditText) dialog.findViewById(R.id.etSearch);
        etSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                //companyAdapter.getFilter().filter(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {
                companyAdapter.getFilter().filter(editable);
            }
        });

        dialog.show();
    }

}

这是公司的自定义适配器

public class CompanyAdapter extends ArrayAdapter<Company>{
    private Activity activity;
    private List<Company> lCompany;
    private LayoutInflater inflater = null;

    public CompanyAdapter (Activity activity, int textViewResourceId, List<Company> lCompany){
        super(activity, textViewResourceId, lCompany);
        try{
            this.activity = activity;
            this.lCompany = lCompany;

            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public int getCount(){
        return lCompany.size();
    }

    public Company getItem (Company position){
        return position;
    }

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

    public  class ViewHolder {
        public TextView display_name;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        final ViewHolder holder;
        try {
            if (convertView == null) {
                vi = inflater.inflate(R.layout.company_list_item, null);
                holder = new ViewHolder();

                holder.display_name = (TextView) vi.findViewById(R.id.tvCompanyName);


                vi.setTag(holder);
            } else {
                holder = (ViewHolder) vi.getTag();
            }
            holder.display_name.setText(lCompany.get(position).getName());

        } catch (Exception e) {
            e.printStackTrace();

        }
        return vi;
    }
}

任何建议都会很有帮助

【问题讨论】:

  • 您将自己的ListArrayAdapter 内部维护的ArrayAdapter 分开,并对其进行过滤。只需删除您的 private List&lt;Company&gt; lCompany; 字段和使用它的覆盖,然后使用 getItem(position) 代替 getView() 中的 lCompany.get(position)。然后只需确保您的 Company 类有一个 toString() 覆盖,它返回 getName() - 或其相应的字段 - 并且 ArrayAdapter 的内置 Filter 将为您工作。
  • @MikeM。我试过了,当我在 EditText 中输入内容时,它会清空列表并且不过滤。当你说覆盖 toString.在 Company 类中,我有 @SerializedName("name") private String name; public String getName() { 返回名称;它已经返回一个字符串,所以我应该在这里做其他事情吗?另一点,当我输入一些内容时,它会清空列表,当我删除我输入的文本时,列表又回来了。任何想法可能发生的事情
  • 你必须专门重写toString()方法; @Override public String toString() { return name; }。事实上,您根本不需要自定义Adapter,如果您唯一要做的就是设置TextView 的文本。将 toString() 覆盖添加到 Company,然后添加 ArrayAdapter&lt;Company&gt; companyAdapter = new ArrayAdapter&lt;&gt;(getActivity(), R.layout.company_list_item, R.id.tvCompanyName, companies);。就是这样。

标签: android search android-listview android-dialog


【解决方案1】:

您需要将Filterable 接口添加到您的适配器。

您可以将以下代码添加到您的适配器

public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            String filterString = constraint.toString().toLowerCase();

            FilterResults results = new FilterResults();

            final List < String > list = originalData;

            int count = list.size();
            final ArrayList < String > nlist = new ArrayList < String > (count);

            String filterableString;

            for (int i = 0; i < count; i++) {
                filterableString = list.get(i);
                if (filterableString.toLowerCase().contains(filterString)) {
                    nlist.add(filterableString);
                }
            }

            results.values = nlist;
            results.count = nlist.size();

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredData = (ArrayList < String > ) results.values;
            notifyDataSetChanged();
        }
    }
}

您需要根据您的要求进行更改

【讨论】:

  • ArrayAdapter 已经实现了Filterable,并提供了自己的Filter。这不是真的必要。
【解决方案2】:

我使用与 ListView 配对的 SearchView 来实现这一点。 SearchView 有一些内置方法,这些方法会在更改文本或单击搜索时触发,您可以覆盖这些方法以在 ListView 中设置过滤器。

MyActivity.java

        // Setup the ListView
        // breedListView = (ListView)rootView.findViewById(R.id.breedListView);

        // My 'Activity' is actually a ListFragment so getListView() is how it is done
        breedListView = getListView();
        breedListView.setFastScrollEnabled(true);
        breedListView.setTextFilterEnabled(true);

        // Setup the searchView
        searchView = (SearchView)rootView.findViewById(R.id.searchView);                    
        setupSearchView();

        // Set some default properties
        private void setupSearchView() {
            searchView.setIconifiedByDefault(false);
            searchView.setOnQueryTextListener(this);
            searchView.setSubmitButtonEnabled(false);
            searchView.setQueryHint("Search");
        }

        // Reset the filter as the user types
        public boolean onQueryTextChange(String newText) {
            if (TextUtils.isEmpty(newText)) {
                breedListView.clearTextFilter();
            } else {
                breedListView.setFilterText(newText.toString());
            }
            return true;
        }

        // Reset the filter when Search is pressed
        public boolean onQueryTextSubmit(String query) {
            if (TextUtils.isEmpty(query)) {
                breedListView.clearTextFilter();
            } else {
                breedListView.setFilterText(query.toString());
            }
            return false;
        }


        // After getting/refreshing the list, do this to reapply the query to the new list
        CharSequence suggestWord = searchView.getQuery();
        searchView.setQuery(suggestWord, true);

MyActivity.xml

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <SearchView
                android:id="@+id/searchView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </SearchView>

            <LinearLayout 
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="match_parent">     
                    <ListView
                      android:id="@android:id/list"
                      android:layout_weight="0.1"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content" >
                    </ListView>

                    <ListView
                        android:id="@+id/listIndex"
                        android:dividerHeight="0dp"
                        android:divider="@null"
                        android:scrollbars="none"
                        android:layout_width="30dp"
                        android:layout_height="wrap_content" >
                    </ListView>
            </LinearLayout> 
        </LinearLayout>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 2021-07-19
    相关资源
    最近更新 更多