自定义列表视图中的Android Searchview无法正常运行

时间:2017-09-03 22:06:23

标签: java android listview searchview

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

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

searchmenu.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" />

searchable.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();
        }
    }

在我的Activity,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;
}

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

1 个答案:

答案 0 :(得分:1)

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

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