我一直无法让我的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数组中的空引用有关......
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)
答案 0 :(得分:0)
您不需要创建两个适配器并一次又一次地初始化它们。只创建一个适配器并使用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();
}