2016-01-30 78 views
0

我一直遇到問題,試圖讓我的搜索框工作,以搜索適當的行列表視圖,然後根據需要顯示。搜索ListView時遇到的問題(Android)

基本上,當我在搜索框鍵入,無論是應用程序崩潰或從各種文件給我的「空對象引用」錯誤(ListView.java,TextView.java等)

我懷疑它有一個在EditText和從JSON值創建的數組之間比較字符串方面缺乏經驗。顯示listview很好,搜索它一直是一個令人沮喪的障礙。希望有任何幫助可能,謝謝!

我的代碼段有如下,

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); 
    } 
} 

} 

也越來越下面的錯誤,這做得到令人沮喪,但我認爲這與我的廣告中的空引用有關apter或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

你忘了初始化'RigsTemp'數組 – Rehan

+0

我會推薦在你的適配器中實現可過濾接口 – kopikaokao

回答

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(); 
} 
+0

Hello Rehan,th爲迴應。我已經嘗試過您的解決方案,但它仍然無法正常工作,所以我嘗試使用日誌打印和Logct來檢查文本框。這個問題實際上似乎是equalsIgnoreCase,它似乎不起作用。在解決有關此功能的錯誤方面有任何幫助或經驗? –

+0

你好Rehan,對不起,代碼確實有效。感謝您的指導! –

+0

@AjitDenis我已經更新了答案。您可以將'String searchString = s.toString();'更改爲'String searchString = myFilter.getText()。toString();'所以它將使用在EditText中輸入的所有文本進行搜索。 – Rehan