ListActvity过滤器用于自定义ArrayAdapter

时间:2011-05-23 18:37:21

标签: java android

我已经阅读了几个关于使用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>

2 个答案:

答案 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方法使用和返回。如果你经历过,我相信你会得到你所有的答案。

相关问题