我已经阅读了几个关于使用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>
答案 0 :(得分:5)
我认为数组适配器的标准过滤器只过滤那些在构造函数中传递它的List
(数组)对象。但是您重写方法getCount
getItem
等,因此适配器不使用您在构造函数中传递的列表。但是,当您致电getFilter().filter(s)
时,会过滤此列表。
所以你有课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
的{{3}}(以及ArrayFilter
),以便更好地了解getFilter().filter(s)
在您的案例中所做的事情。
答案 1 :(得分:0)
阅读source code of ArrayFilter
课程中的ArrayAdapter
,了解Android开发人员解决此问题的方式。
类ArrayFilter
是一个自定义Filter
类,其实例由getFilter
方法使用和返回。如果你经历过,我相信你会得到你所有的答案。