ListActvity Filter for Custom ArrayAdapter

I read a few tutorials about using a simple filter for ListActivity, but I just can not understand why it does not work for me. The TextWatcher onTextChanged () method executes with the correct search string .... but then nothing happens. I think the problem might be with the user adapter, but how can I make it work?

Maybe you could look at it :) Thanks!

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); } } 

where is the playlist.xml file:

 <?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> 

and each row in the ListView is a listview.xml element:

 <?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> 
+4
source share
2 answers

I think that the standard filter from the array adapter filters only those List (array) of objects that you pass in the constructor. But you are overriding the getCount methods getItem etc., so the adapter does not use the list that you passed in the constructor. But when you call getFilter().filter(s) , it filters this list.

So, you have the EfficientAdapter class, it extends the ArrayAdapter . When creating an EfficientAdapter , the created and initialized part of the ArrayAdapter. In the constructor you passed an array of strings, and the ArrayAdapter part stores them. A standard filter will filter them instead of the Settings.playlist. What you can do is not use Settings.playlist (and not override getItem ...), but use only the list that you passed in the constructor. I think it should work then.

The internal ArrayAdapter has the following fields:

 /** * 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; 

The ArrayAdapter's internal filter, ArrayFilter , filters mOriginalValues and adds all the values ​​that match the values ​​in mObjects , and then the ArrayAdapter shows' mObjects .

See the source code of the ArrayAdapter (and ArrayFilter ) for a better understanding of what getFilter().filter(s) does in your case.

+5
source

Read the source code of an ArrayFilter in an ArrayAdapter to find out how Android developers deal with this problem.

The ArrayFilter class is a regular Filter class, an instance of which is used and returned by the getFilter method. I am sure that you will have all your answers if you go through it.

0
source

All Articles