搜索自定义 ListView Android 错误

Search on Custom ListView Android error

我有一个应用程序,我应该在其中实现自定义列表的搜索,所以当我在 edittext 上键入任何键时出现错误01-26 21:19:11.441: E/AndroidRuntime(5793): FATAL EXCEPTION: main 01-26 21:19:11.441: E/AndroidRuntime(5793): java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2 01-26 21:19:11.441: E/AndroidRuntime(5793): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) 01-26 21:19:11.441: E/AndroidRuntime(5793): at java.util.ArrayList.get(ArrayList.java:304) 01-26 21:19:11.441: E/AndroidRuntime(5793): at com.tutecentral.navigationdrawer.CustomList.getView(CustomList.java:52) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.AbsListView.obtainView(AbsListView.java:2054) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.ListView.measureHeightOfChildren(ListView.java:1476) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.ListView.onMeasure(ListView.java:1339) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5005) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.LinearLayout.measureVertical(LinearLayout.java:660) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5005) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:762) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5005) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.LinearLayout.measureVertical(LinearLayout.java:812) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5005) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293) 01-26 21:19:11.441: E/AndroidRuntime(5793): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2141) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.View.measure(View.java:12948) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1227) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2695) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.os.Handler.dispatchMessage(Handler.java:99) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.os.Looper.loop(Looper.java:156) 01-26 21:19:11.441: E/AndroidRuntime(5793): at android.app.ActivityThread.main(ActivityThread.java:4987) 01-26 21:19:11.441: E/AndroidRuntime(5793): at java.lang.reflect.Method.invokeNative(Native Method) 01-26 21:19:11.441: E/AndroidRuntime(5793): at java.lang.reflect.Method.invoke(Method.java:511) 01-26 21:19:11.441: E/AndroidRuntime(5793): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 01-26 21:19:11.441: E/AndroidRuntime(5793): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 01-26 21:19:11.441: E/AndroidRuntime(5793): at dalvik.system.NativeStart.main(Native Method)

我的activity:`

public class MyLibrary extends Fragment {
ListView listview;
List<ParseObject> ob;
ProgressDialog mProgressDialog;
ArrayAdapter<String> adapter2;
CustomList adapter;
EditText inputSearch;
int textlength = 0;

public MyLibrary() {

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Parse.initialize(getActivity(),
            "ASD",
            "ASD");
    ParseUser.enableAutomaticUser();
    ParseACL defaultACL = new ParseACL();
    defaultACL.setPublicReadAccess(true);
    ParseACL.setDefaultACL(defaultACL, true);
    View view = inflater.inflate(R.layout.getnewlay, container, false);

    new RemoteDataTask().execute();

    return view;
}

private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = new ProgressDialog(getActivity());
        mProgressDialog.setTitle("Parse.com Simple ListView Tutorial");
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Locate the class table named "Country" in Parse.com
        ParseQuery query = new ParseQuery("BookStore");
        query.orderByDescending("_created_at");
        try {
            ob = query.find();
            Log.e("Yes", "" + ob);

        } catch (ParseException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {

        listview = (ListView) getView().findViewById(R.id.listviewget);
        inputSearch = (EditText) getView().findViewById(R.id.inputSearch);
        adapter = new CustomList(getActivity(), ob);

        /*
         * ArrayAdapter<String>(getActivity(), R.layout.listview_item);
         */
        // Retrieve object "name" from Parse.com database
        for (ParseObject country : ob) {
            adapter.add((String) country.get("name"));
        }
        listview.setAdapter(adapter);
        inputSearch.addTextChangedListener(new TextWatcher() {
            ArrayList<String> text_sort = new ArrayList<String>();

            @Override
            public void afterTextChanged(Editable arg0) {

            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1,
                    int arg2, int arg3) {

            }

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2,
                    int arg3) {
            //adapter.getFilter().filter(cs.toString());
                String text = inputSearch.getText().toString()
                        .toLowerCase(Locale.getDefault());
                adapter.filter(text);
                /*
                 * adapter.getFilter().filter(cs.toString()); textlength =
                 * inputSearch.getText().length(); text_sort.clear();
                 */
                // image_sort.clear();

                /*
                 * for (int i = 0; i < text_sort.size(); i++) { if
                 * (textlength <= ob.get(i).size()) { if
                 * (edittext.getText().toString(). equalsIgnoreCase((String)
                 * text[i].subSequence(0, textlength))) {
                 * text_sort.add(text[i]); image_sort.add(image[i]); } }
                 */

            }
        });
        mProgressDialog.dismiss();

        /*
         * listview.setOnItemClickListener(new OnItemClickListener() {
         * 
         * @Override public void onItemClick(AdapterView<?> parent, View
         * view, int position, long id) { // Send single item click data to
         * SingleItemView Class // Intent i = new Intent(GetNewBooks.this,
         * // SingleItemView.class); // Pass data "name" followed by the
         * position // i.putExtra("name", ob.get(position).getString("name")
         * // .toString()); // Open SingleItemView.java Activity //
         * startActivity(i); } });
         */
    }
}


}

适应类:

public class CustomList extends ArrayAdapter < String > {
private finalActivity context;
/*private final String[] web;
private final String[] descr;
private final Integer[] imageId;
private final Integer[] imagId;*/
private List < ParseObject > ob = null;
//  private final String[] descr;
// public CustomList(Activity context, List<ParseObject>
// ob,List<ParseObject> ob2) {
// }
private ArrayList < ParseObject > arraylist;
public CustomList(Activity context, List < ParseObject > ob) {
    super(context, R.layout.list_single);
    this.ob = ob;
    this.context = context;
    this.arraylist = new ArrayList < ParseObject > ();
    this.arraylist.addAll(ob);
    //  this.descr = ob;
    /*this.descr = ob2;
    this.web = ob;
    this.imageId = imageId;
    this.imagId = imagId;*/
    // TODO Auto-generated constructor stub
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.list_single, null, true);
    TextView txtTitle = (TextView) rowView.findViewById(R.id.lname);
    //for(ParseObject i : ob) txtTitle.setText((CharSequence) i);
    txtTitle.setText(ob.get(position).get("name").toString());
    return rowView;
}

public void filter(String charText) {
    charText = charText.toLowerCase(Locale.getDefault());
    ob.clear();
    if (charText.length() == 0) {
        ob.addAll(arraylist);
    } else {
        for (ParseObject wp: arraylist) {
            if (((String) wp.get("name")).toLowerCase(Locale.getDefault())
                .contains(charText)
            ) {
                ob.add(wp);
            }
        }
    }
    notifyDataSetChanged();
}
}

当然有 IndexOutOfBoundsException 异常。为什么?
1。您的 CustomListString ArrayAdapter 并且您将适配器中的项目数初始化如下:

for (ParseObject country : ob) {
    adapter.add((String) country.get("name"));
}

--> 这意味着你的 adapterob.size() = 2 项,对吧?
2。在你 filter 你的适配器之后,你的 ob.size() 被改变了(我是客人,小于 2 项)但是,你的 String ArrayAdapter 没有改变(仍然有 2 项) --> getView() 函数将在行 txtTitle.setText(ob.get(position).get("name").toString());

中抛出

如果你想解决它改变你的 filter 如下:

 public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
ob.clear();
this.clear(); // clear the adapter too.

if (charText.length() == 0) {
    ob.addAll(arraylist);
} else {
    for (ParseObject wp: arraylist) {
        if (((String) wp.get("name")).toLowerCase(Locale.getDefault())
            .contains(charText)
        ) {
            ob.add(wp);
            this.add((String)wp.get("name")); // add item to your adapter.            
        }
    }
}
notifyDataSetChanged();
}

P/s: 你的适配器真的很丑。您应该在 getView 中学习如何重用。它将大大提高您的列表滚动性能。