1

我正在尝试为我的代码实现搜索过滤器,但是目前我遇到了一些问题。我收到的错误是:

ArrayList 不能转换为 CustomAapter

我知道发生此错误是因为我在 CustomAdapter 中使用 List 而不是 ArrayList。问题是我不知道如何修复它以使其正常工作。

自定义适配器

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

public class CustomAdapter extends ArrayAdapter<Records> {

    Context context;
    int layoutResourceId;
    List<Records> data;

    private Filter fRecords;

    public CustomAdapter(Context context, int layoutResourceId, List<Records> data) {
        super(context, layoutResourceId, data);
        // TODO Auto-generated constructor stub
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        View row = convertView;
        DataHolder holder = null;

        if (row == null) {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new DataHolder();
            holder.dataName = (TextView)row.findViewById(R.id.dataName);
            holder.dataType = (TextView)row.findViewById(R.id.dataType);

            row.setTag(holder);
        } else {
            holder = (DataHolder)row.getTag();
        }

        Records records = data.get(position);
        holder.dataName.setText(records.getName());
        holder.dataType.setText(records.getType());

        return row;
    }

    private class RecordFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            //Implement filter logic
            if (constraint == null || constraint.length() == 0) {
                //No need for filter
                results.values = data;
                results.count = data.size();
            } else {
                //Need Filter
                List<Records> fRecords = new ArrayList<Records>();

                for (Records s : data) {
                    if (s.getName().toUpperCase().contains(constraint.toString().toUpperCase())) {
                        fRecords.add(s);
                    }
                }

                results.values = fRecords;
                results.count = fRecords.size();
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            //inform the adapter about the new list
            if (results.count == 0) {
                notifyDataSetInvalidated();
            } else {
                data = (List<Records>) results.values;
                notifyDataSetChanged();
            }

        }

    }

    @Override
    public Filter getFilter() {
        if (fRecords == null) {
            fRecords = new RecordFilter();
        }

        return fRecords;
    }

    static class DataHolder {
        TextView dataName;
        TextView dataType;
    }

}

数据布局

import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;

public class DataLayout extends Activity {
    private RecordsDataSource datasource;

    Button btnDataCancel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.data_layout);       

        datasource = new RecordsDataSource(this);
        datasource.open();

        final List<Records> values = datasource.getNameType();

        //use the SimpleCursorAdapter to show the
        //elements in a ListView
        //ArrayAdapter<Records> adapter = new ArrayAdapter<Records>(this, android.R.layout.simple_list_item_1, values);
        //setListAdapter(adapter);


        CustomAdapter adapter = new CustomAdapter(this, R.layout.data_layout_listview, values);
        final ListView listView1 = (ListView)findViewById(R.id.listView1);

        listView1.setAdapter(adapter);


        Button btnDataCancel = (Button)findViewById(R.id.btnDataCancel);

        //Cancel Button
        btnDataCancel.setOnClickListener(new View.OnClickListener() {

            public void onClick(View arg0) {
                //Starting a new Intent
                Intent goMain = new Intent(getApplicationContext(), MainActivity.class);

                startActivity(goMain);
                finish();
            }
        });

        //ListView onClick
        listView1.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Object o = listView1.getItemAtPosition(position);
                Records str =(Records)o;

                Intent rData = new Intent(DataLayout.this, RecordView.class);
                rData.putExtra("DataId", String.valueOf(str.getId()));
                DataLayout.this.startActivity(rData);
                //Toast.makeText(getBaseContext(), str.getName(), Toast.LENGTH_SHORT).show();
            }
        });

        //Filter Text
        EditText edtFilter = (EditText)findViewById(R.id.edtFilter);

        edtFilter.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                System.out.println("Text [" + s + "]");
                ((CustomAdapter) values).getFilter().filter(s.toString());

            }

        });
    }

    @Override
    protected void onResume() {
        datasource.open();
        super.onResume();
    }

    @Override
    protected void onPause() {
        datasource.close();
        super.onPause();
    }
}

Edit1:@alexei burmistrov 谢谢你的帮助,它现在抛出一个不同的错误。以下是日志:

05-20 22:54:39.275: E/AndroidRuntime(526): FATAL EXCEPTION: main
05-20 22:54:39.275: E/AndroidRuntime(526): java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
05-20 22:54:39.275: E/AndroidRuntime(526):  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
05-20 22:54:39.275: E/AndroidRuntime(526):  at java.util.ArrayList.get(ArrayList.java:308)
05-20 22:54:39.275: E/AndroidRuntime(526):  at com.pbear.drillmaster.CustomAdapter.getView(CustomAdapter.java:69)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.AbsListView.obtainView(AbsListView.java:1949)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.ListView.measureHeightOfChildren(ListView.java:1228)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.ListView.onMeasure(ListView.java:1139)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.View.measure(View.java:10828)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1284)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:613)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:519)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.View.measure(View.java:10828)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:267)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.View.measure(View.java:10828)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1284)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:613)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:519)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.View.measure(View.java:10828)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:267)
05-20 22:54:39.275: E/AndroidRuntime(526):  at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:1889)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.View.measure(View.java:10828)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.ViewRoot.performTraversals(ViewRoot.java:938)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.view.ViewRoot.handleMessage(ViewRoot.java:2040)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.os.Looper.loop(Looper.java:132)
05-20 22:54:39.275: E/AndroidRuntime(526):  at android.app.ActivityThread.main(ActivityThread.java:4123)
05-20 22:54:39.275: E/AndroidRuntime(526):  at java.lang.reflect.Method.invokeNative(Native Method)
05-20 22:54:39.275: E/AndroidRuntime(526):  at java.lang.reflect.Method.invoke(Method.java:491)
05-20 22:54:39.275: E/AndroidRuntime(526):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
05-20 22:54:39.275: E/AndroidRuntime(526):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
05-20 22:54:39.275: E/AndroidRuntime(526):  at dalvik.system.NativeStart.main(Native Method)

Edit2:感谢 alexei burmistrov 通过过滤澄清了很多概念。我终于让它工作了。

4

1 回答 1

0

您应该调用 getFilter().filter(...) 而不是在您的数据源(值)上,而是作为

adapter.getFilter().filter(s.toString();

不需要类型转换。

过滤数据时,永远不要修改原始数据集,在 publishResults 中使用适配器的 getItem 修改其内部副本,添加和清除方法或为 getView 使用手动数据副本。还将 getCount 覆盖到此手动副本的大小。

请参阅此处作为使用内部数据副本的示例之一。

对于第一个替代方案(对我来说最理智),在 getView 中使用 getItem 不是从原始数据集而是从内部数据集获取记录。不要覆盖 getCount。在 publishResults 中使用 clear 然后添加 (addAll) 来复制过滤后的数据。

对于第二种选择,将构造函数中的数据复制到filteredData,并在getView() getCount() 和publishResults 中使用filteredData 而不是数据。保持 performFiltering 不变

于 2013-05-20T22:23:30.957 回答