搜索ListView(Android)的问题(Issues with Searching ListView (Android))

我一直在努力让我的Searchbox工作来搜索Listview中的相应行,然后根据需要进行显示。

基本上,当我输入搜索框时,应用程序崩溃或从各种文件(ListView.java,TextView.java等)给出“空对象引用”错误

我怀疑它与在比较EditText和从JSON值创建的数组之间的字符串方面缺乏经验有很大关系。 显示列表视图很好,搜索它是一个令人沮丧的障碍。 非常感谢任何可能的帮助,谢谢!

我的代码部分如下,

ListViewActivity.java

package com.example.myapplication; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.util.Log; import android.text.Editable; import android.text.TextWatcher; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; import com.example.myapplication.WaterWellRigsJsonUrl; import com.example.myapplication.Rig; public class ListViewActivity extends Activity { private ListView listview; private ArrayList<Rig> Rigs; private ArrayList<Rig> RigsTemp; private ArrayAdapter<Rig> adapter; private ArrayAdapter<Rig> adapter2; private EditText et; String searchString = ""; private final static String TAG = ListViewActivity.class.getSimpleName(); private final static String url = "http://www.world-rigs.com/waterwellrigs/json.php"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); listview = (ListView) findViewById(R.id.listview); setListViewAdapter(); getDataFromInternet(); final EditText myFilter = (EditText) findViewById(R.id.myFilter); myFilter.addTextChangedListener(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); String searchString = s.toString(); if (s.length() > 0) { for (int i = 0; i < Rigs.size();i++) { if (searchString.equalsIgnoreCase(Rigs.get(i).getName())) { Rig rigtemp = new Rig(); rigtemp.setName(Rigs.get(i).getName()); rigtemp.setImageUrl(Rigs.get(i).getImageUrl()); rigtemp.setRigId(Rigs.get(i).getRigId()); RigsTemp.add(rigtemp); Log.e("myTag2", "value:" + RigsTemp.size()); } } } adapter2 = new CustomListViewAdapter(ListViewActivity.this, R.layout.item_listview, RigsTemp); listview.setAdapter(adapter2); } }); } private void getDataFromInternet() { new WaterWellRigsJsonUrl(this, url).execute(); } private void setListViewAdapter() { Rigs = new ArrayList<Rig>(); adapter = new CustomListViewAdapter(this, R.layout.item_listview, Rigs); listview.setAdapter(adapter); listview.setTextFilterEnabled(true); } //parse response data after asynctask finished public void parseJsonResponse(String result) { Log.i(TAG, result); try { JSONObject json = new JSONObject(result); JSONArray jArray = new JSONArray(json.getString("rig_array")); for (int i = 0; i < jArray.length(); i++) { JSONObject jObject = jArray.getJSONObject(i); Rig rig = new Rig(); rig.setName(jObject.getString("name")); rig.setImageUrl(jObject.getString("image")); rig.setRigId(jObject.getString("rigid")); Rigs.add(rig); Log.e("myTag", Rigs.get(i).getRigId()); } adapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); } } }

CustomListViewAdapter.java

package com.example.myapplication; import java.util.List; import android.app.Activity; import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.example.myapplication.Rig; import com.loopj.android.image.SmartImageView; import com.squareup.picasso.Picasso; public class CustomListViewAdapter extends ArrayAdapter<Rig> { private Activity activity; public CustomListViewAdapter(Activity activity, int resource, List<Rig> rigs) { super(activity, resource, rigs); this.activity = activity; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; LayoutInflater inflater = (LayoutInflater) activity .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); // If holder not exist then locate all view from UI file. if (convertView == null) { // inflate UI from XML file convertView = inflater.inflate(R.layout.item_listview, parent, false); // get all UI view holder = new ViewHolder(convertView); // set tag for holder convertView.setTag(holder); } else { // if holder created, get tag from view holder = (ViewHolder) convertView.getTag(); } Rig rig = getItem(position); holder.name.setText(rig.getName()); holder.authorName.setText("WR" + rig.getRigId()); Picasso.with(activity).load(rig.getImageUrl()).into(holder.image); return convertView; } private static class ViewHolder { private TextView name; private TextView authorName; private ImageView image; public ViewHolder(View v) { name = (TextView) v.findViewById(R.id.title); image = (SmartImageView) v.findViewById(R.id.thumbnail); // SmartImageView image = (SmartImageView) v.findViewById(R.id.my_image); authorName = (TextView) v.findViewById(R.id.author); } } }

还得到以下错误,这确实令人沮丧,但我认为它与我的Adapter或RigsTemp数组中的null引用有关,同时搜索...

01-30 13:17:45.300 16835-16835/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.myapplication, PID: 16835 java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330) at android.widget.ListView.setAdapter(ListView.java:487) at com.example.myapplication.ListViewActivity$1.onTextChanged(ListViewActivity.java:84) at android.widget.TextView.sendOnTextChanged(TextView.java:7663) at android.widget.TextView.handleTextChanged(TextView.java:7723) at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9440) at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:964) at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:515) at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:454) at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:33) at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:685) at android.view.inputmethod.BaseInputConnection.setComposingText(BaseInputConnection.java:445) at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:340) at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

I have been having trouble trying to get my Searchbox working to search the Listview for appropriate rows, and then displaying as required.

Basically, when I type in the searchbox, either the app crashed or gives me 'null object reference' errors from various files (ListView.java, TextView.java etc..)

I suspect it has a lot to do with inexperience on comparing strings between the EditText and the array created from JSON values. Displaying the listview is fine, searching it has been a frustrating hurdle. Would appreciate any help possible, thanks!

My code sections are as below,

ListViewActivity.java

package com.example.myapplication; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.util.Log; import android.text.Editable; import android.text.TextWatcher; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; import com.example.myapplication.WaterWellRigsJsonUrl; import com.example.myapplication.Rig; public class ListViewActivity extends Activity { private ListView listview; private ArrayList<Rig> Rigs; private ArrayList<Rig> RigsTemp; private ArrayAdapter<Rig> adapter; private ArrayAdapter<Rig> adapter2; private EditText et; String searchString = ""; private final static String TAG = ListViewActivity.class.getSimpleName(); private final static String url = "http://www.world-rigs.com/waterwellrigs/json.php"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); listview = (ListView) findViewById(R.id.listview); setListViewAdapter(); getDataFromInternet(); final EditText myFilter = (EditText) findViewById(R.id.myFilter); myFilter.addTextChangedListener(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); String searchString = s.toString(); if (s.length() > 0) { for (int i = 0; i < Rigs.size();i++) { if (searchString.equalsIgnoreCase(Rigs.get(i).getName())) { Rig rigtemp = new Rig(); rigtemp.setName(Rigs.get(i).getName()); rigtemp.setImageUrl(Rigs.get(i).getImageUrl()); rigtemp.setRigId(Rigs.get(i).getRigId()); RigsTemp.add(rigtemp); Log.e("myTag2", "value:" + RigsTemp.size()); } } } adapter2 = new CustomListViewAdapter(ListViewActivity.this, R.layout.item_listview, RigsTemp); listview.setAdapter(adapter2); } }); } private void getDataFromInternet() { new WaterWellRigsJsonUrl(this, url).execute(); } private void setListViewAdapter() { Rigs = new ArrayList<Rig>(); adapter = new CustomListViewAdapter(this, R.layout.item_listview, Rigs); listview.setAdapter(adapter); listview.setTextFilterEnabled(true); } //parse response data after asynctask finished public void parseJsonResponse(String result) { Log.i(TAG, result); try { JSONObject json = new JSONObject(result); JSONArray jArray = new JSONArray(json.getString("rig_array")); for (int i = 0; i < jArray.length(); i++) { JSONObject jObject = jArray.getJSONObject(i); Rig rig = new Rig(); rig.setName(jObject.getString("name")); rig.setImageUrl(jObject.getString("image")); rig.setRigId(jObject.getString("rigid")); Rigs.add(rig); Log.e("myTag", Rigs.get(i).getRigId()); } adapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); } } }

CustomListViewAdapter.java

package com.example.myapplication; import java.util.List; import android.app.Activity; import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.example.myapplication.Rig; import com.loopj.android.image.SmartImageView; import com.squareup.picasso.Picasso; public class CustomListViewAdapter extends ArrayAdapter<Rig> { private Activity activity; public CustomListViewAdapter(Activity activity, int resource, List<Rig> rigs) { super(activity, resource, rigs); this.activity = activity; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; LayoutInflater inflater = (LayoutInflater) activity .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); // If holder not exist then locate all view from UI file. if (convertView == null) { // inflate UI from XML file convertView = inflater.inflate(R.layout.item_listview, parent, false); // get all UI view holder = new ViewHolder(convertView); // set tag for holder convertView.setTag(holder); } else { // if holder created, get tag from view holder = (ViewHolder) convertView.getTag(); } Rig rig = getItem(position); holder.name.setText(rig.getName()); holder.authorName.setText("WR" + rig.getRigId()); Picasso.with(activity).load(rig.getImageUrl()).into(holder.image); return convertView; } private static class ViewHolder { private TextView name; private TextView authorName; private ImageView image; public ViewHolder(View v) { name = (TextView) v.findViewById(R.id.title); image = (SmartImageView) v.findViewById(R.id.thumbnail); // SmartImageView image = (SmartImageView) v.findViewById(R.id.my_image); authorName = (TextView) v.findViewById(R.id.author); } } }

Also getting the following errors, which do get frustrating but I think it has something to do with null reference in my Adapter or RigsTemp array while searching...

01-30 13:17:45.300 16835-16835/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.myapplication, PID: 16835 java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330) at android.widget.ListView.setAdapter(ListView.java:487) at com.example.myapplication.ListViewActivity$1.onTextChanged(ListViewActivity.java:84) at android.widget.TextView.sendOnTextChanged(TextView.java:7663) at android.widget.TextView.handleTextChanged(TextView.java:7723) at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9440) at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:964) at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:515) at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:454) at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:33) at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:685) at android.view.inputmethod.BaseInputConnection.setComposingText(BaseInputConnection.java:445) at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:340) at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

最满意答案

您不需要创建两个适配器并一次又一次地初始化它们。 只创建一个适配器并使用notifyDataSetChanged更改数据并更新ListView

private ArrayList<Rig> RigsTemp; private ArrayAdapter<Rig> adapter;

更改您的功能如下:

private void setListViewAdapter() { Rigs = new ArrayList<Rig>(); RigsTemp = new ArrayList<Rig>(); adapter = new CustomListViewAdapter(ListViewActivity.this, R.layout.item_listview, RigsTemp); listview.setAdapter(adapter); listview.setTextFilterEnabled(true); }

并使用以下代码更改TextWatcher代码:

public void onTextChanged(CharSequence s, int start, int before, int count) { String searchString = myFilter.getText().toString(); RigsTemp.clear(); if (s.length() > 0) { for (int i = 0; i < Rigs.size(); i++) { if (searchString.equalsIgnoreCase(Rigs.get(i).getName())) { Rig rigtemp = new Rig(); rigtemp.setName(Rigs.get(i).getName()); rigtemp.setImageUrl(Rigs.get(i).getImageUrl()); rigtemp.setRigId(Rigs.get(i).getRigId()); RigsTemp.add(rigtemp); } } } else { // Only if you want to show all results when user has not entered anything in EditText // Else remove this line to show empty ListView at start RigsTemp.addAll(Rigs); } adapter.notifyDataSetChanged(); }

You don't need to create two adapters and initialize them again and again. Create just one adapter and use notifyDataSetChanged to change data and update ListView

private ArrayList<Rig> RigsTemp; private ArrayAdapter<Rig> adapter;

Change your function as follows:

private void setListViewAdapter() { Rigs = new ArrayList<Rig>(); RigsTemp = new ArrayList<Rig>(); adapter = new CustomListViewAdapter(ListViewActivity.this, R.layout.item_listview, RigsTemp); listview.setAdapter(adapter); listview.setTextFilterEnabled(true); }

And Change the TextWatcher code with following code:

public void onTextChanged(CharSequence s, int start, int before, int count) { String searchString = myFilter.getText().toString(); RigsTemp.clear(); if (s.length() > 0) { for (int i = 0; i < Rigs.size(); i++) { if (searchString.equalsIgnoreCase(Rigs.get(i).getName())) { Rig rigtemp = new Rig(); rigtemp.setName(Rigs.get(i).getName()); rigtemp.setImageUrl(Rigs.get(i).getImageUrl()); rigtemp.setRigId(Rigs.get(i).getRigId()); RigsTemp.add(rigtemp); } } } else { // Only if you want to show all results when user has not entered anything in EditText // Else remove this line to show empty ListView at start RigsTemp.addAll(Rigs); } adapter.notifyDataSetChanged(); }

更多推荐