2011-05-23 134 views
4

我已经阅读了几个关于对ListActivity使用简单过滤器的教程,但我无法弄清楚它为什么不适合我。 TextWatcher的onTextChanged()方法使用正确的字符串进行搜索,但是没有任何反应。我认为问题可能是自定义适配器,但我怎样才能使它工作?自定义ArrayAdapter的ListActvity过滤器

也许你可以看看它:) 谢谢!

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> 

回答

5

我认为标准过滤器只有那些对象的List(数组),你在构造函数中传递它。但是你覆盖方法getCountgetItem等,所以适配器不使用你在构造函数中传递的列表。但是,当您拨打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,过滤器和所有值相加,匹配保持在mObjects,然后ArrayAdapter '显示' mObjects

请参阅source codeArrayAdapter(和ArrayFilter),以更好地解决您的问题getFilter().filter(s)

+0

非常感谢! :)过滤工作正常,但现在我总是得到一个UnsupportedOperationException当我调用adapter.clear()从ListActivity中删除所有元素: – martin 2011-05-24 18:48:59

0

阅读ArrayAdapter类中的source code of ArrayFilter来学习Android开发人员解决此问题的方式。

ArrayFilter是自定义Filter类,其实例由getFilter方法使用并返回。如果你经历过,我相信你会得到你所有的答案。