1

コードに検索フィルターを実装しようとしていますが、現在問題が発生しています。私が受け取っているエラーは次のとおりです。

ArrayList は CustomApapter にキャストできません

ArrayList の代わりに CustomAdapter 内で List を使用しているため、このエラーが発生していることはわかっています。問題は、正しく動作させるために修正する方法がわからないことです。

カスタムアダプター

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 をこの手動コピーのサイズにオーバーライドします。

内部データ コピーを使用したサンプルの 1 つとして、こちらを参照してください。

最初の選択肢 (私にとって最も正気) では、getView で getItem を使用して、元のデータセットではなく内部データセットからレコードを取得します。getCount をオーバーライドしないでください。publishResults では、clear を使用してから (addAll) を追加して、フィルタリングされたデータをコピーします。

2 番目の方法として、コンストラクターのデータを、filteredData などにコピーし、データの代わりに getView()、getCount()、および publishResults でfilteredData を使用します。performFiltering をそのままにしておく

于 2013-05-20T22:23:30.957 に答える