Reputation: 1139
I've read several tutorials about the use of a simple filter for a ListActivity but I just can't figure out why it doesn't work for me. The TextWatcher's onTextChanged() method is executed with the correct string to be searched for....but then nothing happens. I think the problem might be the custom adapter but how can I make it work?
Maybe you could have a 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 the playlist.xml file is:
<?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 every row within 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>
Upvotes: 4
Views: 3087
Reputation: 10190
Read the source code of ArrayFilter
in ArrayAdapter
class to learn from the way the developers of Android tackle this problem.
The classArrayFilter
is a custom Filter
class, whose instance is used and returned by the getFilter
method. I'm sure you will have all your answers if you go through it.
Upvotes: 0
Reputation: 15434
I think standard filter from array adapter filters only those List
(array) of objects, which you pass it in constructor. But you override methods getCount
getItem
and etc, so adapter doesn't use list you passed in constructor. But when you call getFilter().filter(s)
it filters this list.
So you have class EfficientAdapter
, it extends ArrayAdapter
.
When you create EfficientAdapter
- ArrayAdapter's part created and initialized too. In constructor you passed array of strings and ArrayAdapter's part stores them. Standard filter will filter them instead of your Settings.playlist list.
What you can do - not to use Settings.playlist (and not override getItem
...), but use only list you passed in constructor. I think then it should work.
Internally ArrayAdapter has 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;
Internal ArrayAdapter's filter -ArrayFilter
, filters mOriginalValues
and add all values, that matches keeps in mObjects
, and then ArrayAdapter 'shows' mObjects
.
See source code of ArrayAdapter
(and ArrayFilter
) to better undestand what getFilter().filter(s)
does in your case.
Upvotes: 5