[英]ListActvity filter for custom ArrayAdapter
我已经阅读了几篇关于为 ListActivity 使用简单过滤器的教程,但我就是不明白为什么它对我不起作用。 使用要搜索的正确字符串执行 TextWatcher 的 onTextChanged() 方法....但是没有任何反应。 我认为问题可能出在自定义适配器上,但我怎样才能让它工作呢?
也许你可以看看它:)谢谢!
package com.RemoteControl;
import com.RemoteControl.R;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
public class RemoteControlPlaylist extends ListActivity {
static Handler error_class_Handler;
static Handler viewHandler;
static EfficientAdapter adapter = null;
private static EditText filterText = null;
static class EfficientAdapter extends ArrayAdapter<String> {
public EfficientAdapter(Context context, int textViewResourceId, int playlistTitle, String[] objects) {
super(context, textViewResourceId, playlistTitle, objects);
mInflater = LayoutInflater.from(context);
}
private LayoutInflater mInflater;
@Override
public int getCount() {
return Settings.playlistlength;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.listview, null);
holder.text = (TextView) convertView.findViewById(R.string.playlist_title);
holder.image = (ImageView) convertView.findViewById(R.string.playlist_play);
holder.queue = (TextView) convertView.findViewById(R.string.playlist_queue);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
static class ViewHolder {
TextView text, queue;
ImageView image;
}
@Override
public String getItem(int position) {
return Settings.playlist[position];
}
}
private static TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}
};
void initialize()
{
adapter = new EfficientAdapter(this, R.layout.listview, R.string.playlist_title, Settings.playlist);
setListAdapter(adapter);
filterText = (EditText) findViewById(R.string.search_box);
filterText.addTextChangedListener(filterTextWatcher);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playlist);
getListView().setTextFilterEnabled(true);
initialize();
error_class_Handler = new Handler();
viewHandler = new Handler();
getListView().setFastScrollEnabled(true);
}
@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}
}
其中 playlist.xml 文件是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<EditText android:id="@+string/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="type to filter"
android:inputType="text"
android:maxLines="1"/>
<ListView android:id="@+android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
</LinearLayout>
ListView 中的每一行都是一个 listview.xml 元素:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+string/playlist_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<!-- some layout stuff --> />
<ImageView
android:id="@+string/playlist_play"
android:src="@drawable/playlist_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<!-- some layout stuff --> />
<TextView
android:id="@+string/playlist_queue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<!-- some layout stuff --> />
</RelativeLayout>
我认为来自数组适配器的标准过滤器仅过滤那些您在构造函数中传递的对象List
(数组)。 但是您覆盖了getCount
getItem
等方法,因此适配器不使用您在构造函数中传递的列表。 但是当您调用getFilter().filter(s)
时,它会过滤此列表。
所以你有 class EfficientAdapter
,它扩展了ArrayAdapter
。 当您创建EfficientAdapter
- ArrayAdapter 的部分也已创建和初始化。 在构造函数中,您传递了字符串数组,而 ArrayAdapter 的部分存储了它们。 标准过滤器将过滤它们而不是您的 Settings.playlist 列表。 你可以做什么 - 不要使用 Settings.playlist (而不是覆盖getItem
...),而只使用你在构造函数中传递的列表。 我认为它应该工作。
ArrayAdapter 内部有以下字段:
/**
* Contains the list of objects that represent the data of this ArrayAdapter.
* The content of this list is referred to as "the array" in the documentation.
*/
private List<T> mObjects;
private ArrayList<T> mOriginalValues;
内部 ArrayAdapter 的过滤器 - ArrayFilter
过滤mOriginalValues
并添加所有匹配的值,保留在mObjects
中,然后 ArrayAdapter '显示' mObjects
。
请参阅ArrayAdapter
(和ArrayFilter
)的源代码,以更好地了解getFilter().filter(s)
在您的情况下的作用。
阅读ArrayAdapter
class 中的ArrayFilter
源代码,了解 Android 的开发人员解决此问题的方法。
class ArrayFilter
是一个自定义的Filter
class,它的实例由getFilter
方法使用和返回。 如果你通过它,我相信你会得到所有的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.