【问题标题】:Android Searchview in custom listview is not functioning自定义列表视图中的 Android Searchview 不起作用
【发布时间】:2017-09-03 22:06:22
【问题描述】:

我正在我的一项活动的操作栏中实施搜索视图。在该活动中,它列出了我手机中的所有歌曲,并且我正在使用自定义列表视图。一切正常,除了 Searchview 显示在操作栏中,但它不起作用,就像我试图输入它时没有任何反应一样。我尝试搜索有关实现 searchview 的所有内容,并尝试自己解决问题,但没有任何效果。

这是我到目前为止所做的。

搜索菜单.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
    android:title="@string/Search"
    android:icon="@drawable/cast_ic_mini_controller_play"
    app:showAsAction="always"
    app:actionViewClass="android.support.v7.widget.SearchView" />

可搜索的.xml

<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint">

androidmanifest.xml

<activity
        android:name=".Music"
        android:label="@string/title_activity_music"
        android:parentActivityName=".backup_menu"
        android:theme="@style/AppTheme.NoActionBar">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.chill.leoj.burp.backup_menu" />
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable"
            />
    </activity>

这是我的自定义适配器,Songadapter

    class SongAdapter extends BaseAdapter implements Filterable {
    private ArrayList<SongInfo> _songs = new ArrayList<SongInfo>();
    private ArrayList<SongInfo> songsfilt = new ArrayList<SongInfo>();
    private ItemFilter itemFilter;
    private Context context;
    LayoutInflater inflater;
    int checkAccumulator;

    public SongAdapter(Context _context, ArrayList<SongInfo> songs) {
        this.context = _context;
        this._songs = songs;
        this.songsfilt = songs;
        checkAccumulator = 0;

        getFilter();

    }

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

    public Object getItem(int position) {
        return _songs.get(position);
    }

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

    @Override
    public Filter getFilter() {
        if (itemFilter == null) {
            itemFilter = new ItemFilter();
        }

        return itemFilter;

    }

    private class ViewHolder {

        protected CheckBox checkBox;
        private TextView tvSongName;
        private TextView tvSongArtist;


    }

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



        ViewHolder viewHolder = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.row_songs, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
            viewHolder.tvSongName = (TextView) convertView.findViewById(R.id.tvSongName);
            viewHolder.tvSongArtist = (TextView) convertView.findViewById(R.id.tvArtistName);
            viewHolder.checkBox.setOnCheckedChangeListener(null);


            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }


        viewHolder.tvSongName.setText(_songs.get(position).getSongname());
        viewHolder.tvSongArtist.setText(_songs.get(position).getArtistname());

        viewHolder.checkBox.setOnCheckedChangeListener(null);
        viewHolder.checkBox.setChecked(_songs.get(position).isSelected());

        viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                count = (isChecked) ? count+1 : count - 1;


                if (!_songs.get(getPosition).isSelected()) {

                    _songs.get(getPosition).setSelected(true);
                    _songs.get(getPosition).setSelected(count > 0);
                    getChoice.setEnabled(true);
                    Log.e("URL", _songs.get(position).getSongUrl() + " ");

                } else {
                    _songs.get(getPosition).setSelected(false);
                    _songs.get(getPosition).setSelected(count < 1);
                    getChoice.setEnabled(false);

                }


            }


        });
        convertView.setTag(R.id.tvSongName, viewHolder.tvSongName);
        convertView.setTag(R.id.tvArtistName, viewHolder.tvSongArtist);
        convertView.setTag(R.id.checkBox, viewHolder.checkBox);

        viewHolder.checkBox.setTag(position); // This line is important.

        return convertView;
    }

    private class ItemFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if (constraint!=null && constraint.length()>0) {
                ArrayList<SongInfo> tempList = new ArrayList<SongInfo>();

                // search content in friend list
                for (SongInfo user : songsfilt) {
                    if (user.getSongname().toLowerCase().contains(constraint.toString().toLowerCase())) {
                        tempList.add(user);
                    }
                }

                filterResults.count = tempList.size();
                filterResults.values = tempList;
            } else {
                filterResults.count = songsfilt.size();
                filterResults.values = songsfilt;
            }

            return filterResults;
        }

        /**
         * Notify about filtered list to ui
         * @param constraint text
         * @param results filtered result
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            _songs = (ArrayList<SongInfo>) results.values;
            notifyDataSetChanged();
        }
    }

关于我的活动,Music.java

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search_menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchMenuItem = menu.findItem(R.id.search);
    searchView = (SearchView) searchMenuItem.getActionView();

    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setSubmitButtonEnabled(true);
    searchView.setOnQueryTextListener(this);

    return true;
}


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

@Override
public boolean onQueryTextChange(String newText) {
    songAdapter.getFilter().filter(newText);
    // use to enable search view popup text
    if (TextUtils.isEmpty(newText)) {
        listView.clearTextFilter();
    }
    else {
        listView.setFilterText(newText.toString());
    }
    return true;
}

需要你们的帮助。提前谢谢你!

【问题讨论】:

  • 您是说无法输入文字,还是可以输入文字但无法提交查询?
  • 我可以输入文本,但什么也没有发生,这是我的问题 :( 似乎它不起作用。我想要的是例如,当我在搜索视图中输入字母“A”时,列表视图将被更新并且它将列出所有以字母“A”开头的音乐。
  • 请帮帮我。

标签: java android listview searchview


【解决方案1】:

将 BaseAdapter 替换为 ArrayAdapter 并将歌曲传递给超类构造函数。然后删除您的 _songs 变量并通过超类 getItem() 方法访问它们。完成后,更改您的 publishResults() 方法以直接修改超类数据,例如:

protected void publishResults(CharSequence constraint, FilterResults results) {
    clear();
    addAll((List<SongInfo>)results.values);
    notifyDataSetInvalidated();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多