2015-06-18 87 views
0

我需要包含一個搜索功能供用戶通過listview進行搜索。將搜索功能添加到SimpleAdapter時出現NullPointerException

這是我MainActivity.java

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     // URL to the JSON data 
     String strUrl = "http://10.0.2.2/get_stores.php"; 

     // Creating a new non-ui thread task to download json data 
     DownloadTask downloadTask = new DownloadTask(); 

     // Starting the download process 
     downloadTask.execute(strUrl); 

     // Getting a reference to ListView of activity_main 
     mListView = (ListView) findViewById(R.id.list); 
     searchBox = (EditText)findViewById(R.id.searchBox); 
    } 

    /** A method to download json data from url */ 
    private String downloadUrl(String strUrl) throws IOException { 
     String data = ""; 
     InputStream iStream = null; 
     try{ 
      URL url = new URL(strUrl); 

      // Creating an http connection to communicate with url 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 

      // Connecting to url 
      urlConnection.connect(); 

      // Reading data from url 
      iStream = urlConnection.getInputStream(); 

      BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); 

      StringBuffer sb = new StringBuffer(); 

      String line = ""; 
      while((line = br.readLine()) != null){ 
       sb.append(line); 
      } 

      data = sb.toString(); 

      br.close(); 

     }catch(Exception e){ 
      Log.d("Exception:", e.toString()); 
     }finally{ 
      iStream.close(); 
     } 

     return data; 
    } 

    /** AsyncTask to download json data */ 
    private class DownloadTask extends AsyncTask<String, Integer, String>{ 
     String data = null; 
     @Override 
     protected String doInBackground(String... url) { 
      try{ 
       data = downloadUrl(url[0]); 
      }catch(Exception e){ 
       Log.d("Background Task",e.toString()); 
      } 
      return data; 
     } 

     @Override 
     protected void onPostExecute(String result) { 

      // The parsing of the xml data is done in a non-ui thread 
      ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask(); 

      // Start parsing xml data 
      listViewLoaderTask.execute(result); 
     } 
    } 

    /** AsyncTask to parse json data and load ListView */ 
    private class ListViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter>{ 

     JSONObject jObject; 
     // Doing the parsing of xml data in a non-ui thread 
     @Override 
     protected SimpleAdapter doInBackground(String... strJson) { 
      try{ 
       jObject = new JSONObject(strJson[0]); 
       StoreJSONParser countryJsonParser = new StoreJSONParser(); 
       countryJsonParser.parse(jObject); 
      }catch(Exception e){ 
       Log.d("JSON Exception1",e.toString()); 
      } 

      // Instantiating json parser class 
      StoreJSONParser countryJsonParser = new StoreJSONParser(); 

      // A list object to store the parsed countries list 
      List<HashMap<String, Object>> countries = null; 

      try{ 
       // Getting the parsed data as a List construct 
       countries = countryJsonParser.parse(jObject); 
      }catch(Exception e){ 
       Log.d("Exception",e.toString()); 
      } 

      // Keys used in Hashmap 
      String[] from = { "country","flag","details"}; 

      // Ids of views in listview_layout 
      int[] to = { R.id.storename,R.id.icon,R.id.details}; 

      // Instantiating an adapter to store each items 
      // R.layout.listview_layout defines the layout of each item 
      adapter = new SimpleAdapter(getBaseContext(), countries, R.layout.restaurant_list, from, to); 
      return adapter; 
     } 

     /** Invoked by the Android on "doInBackground" is executed */ 
     @Override 
     protected void onPostExecute(SimpleAdapter adapter) { 

      // Setting adapter for the listview 
      mListView.setAdapter(adapter); 
      met_search(); 

      for(int i=0;i<adapter.getCount();i++){ 
       HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(i); 
       String imgUrl = (String) hm.get("flag_path"); 
       ImageLoaderTask imageLoaderTask = new ImageLoaderTask(); 

       HashMap<String, Object> hmDownload = new HashMap<String, Object>(); 
       hm.put("flag_path",imgUrl); 
       hm.put("position", i); 

       // Starting ImageLoaderTask to download and populate image in the listview 
       imageLoaderTask.execute(hm); 
      } 
     } 
    } 

    /** AsyncTask to download and load an image in ListView */ 
    private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>>{ 

     @Override 
     protected HashMap<String, Object> doInBackground(HashMap<String, Object>... hm) { 

      InputStream iStream=null; 
      String imgUrl = (String) hm[0].get("flag_path"); 
      int position = (Integer) hm[0].get("position"); 

      URL url; 
      try { 
       url = new URL(imgUrl); 

       // Creating an http connection to communicate with url 
       HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 

       // Connecting to url 
       urlConnection.connect(); 

       // Reading data from url 
       iStream = urlConnection.getInputStream(); 

       // Getting Caching directory 
       File cacheDirectory = getBaseContext().getCacheDir(); 

       // Temporary file to store the downloaded image 
       File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+position+".png"); 

       // The FileOutputStream to the temporary file 
       FileOutputStream fOutStream = new FileOutputStream(tmpFile); 

       // Creating a bitmap from the downloaded inputstream 
       Bitmap b = BitmapFactory.decodeStream(iStream); 

       // Writing the bitmap to the temporary file as png file 
       b.compress(Bitmap.CompressFormat.PNG,100, fOutStream); 

       // Flush the FileOutputStream 
       fOutStream.flush(); 

       //Close the FileOutputStream 
       fOutStream.close(); 

       // Create a hashmap object to store image path and its position in the listview 
       HashMap<String, Object> hmBitmap = new HashMap<String, Object>(); 

       // Storing the path to the temporary image file 
       hmBitmap.put("flag",tmpFile.getPath()); 

       // Storing the position of the image in the listview 
       hmBitmap.put("position",position); 

       // Returning the HashMap object containing the image path and position 
       return hmBitmap; 

      }catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(HashMap<String, Object> result) { 
      // Getting the path to the downloaded image 
      String path = (String) result.get("flag"); 

      // Getting the position of the downloaded image 
      int position = (Integer) result.get("position"); 

      // Getting adapter of the listview 
      SimpleAdapter adapter = (SimpleAdapter) mListView.getAdapter(); 

      // Getting the hashmap object at the specified position of the listview 
      HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(position); 

      // Overwriting the existing path in the adapter 
      hm.put("flag",path); 

      // Noticing listview about the dataset changes 
      adapter.notifyDataSetChanged(); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     //getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    private void met_search() { 
     // TODO Auto-generated method stub 
     /** 
     * Enabling Search Filter 
     * */ 

     searchBox.addTextChangedListener(new TextWatcher() { 

      public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 

      } 

      public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
              int arg3) { 
       // TODO Auto-generated method stub 

      } 

      public void afterTextChanged(Editable arg0) { 
       // TODO Auto-generated method stub 
       MainActivity.this.adapter.getFilter().filter(arg0); 
      } 
     }); 
    } 

這是JSONParser.java

public class StoreJSONParser { 
    // Receives a JSONObject and returns a list 
    public List<HashMap<String,Object>> parse(JSONObject jObject){ 

     JSONArray jCountries = null; 
     try { 
      // Retrieves all the elements in the 'countries' array 
      jCountries = jObject.getJSONArray("storelistfood"); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     // Invoking getCountries with the array of json object 
     // where each json object represent a country 
     return getCountries(jCountries); 
    } 

    private List<HashMap<String, Object>> getCountries(JSONArray jCountries){ 
     int countryCount = jCountries.length(); 
     List<HashMap<String, Object>> countryList = new ArrayList<HashMap<String,Object>>(); 
     HashMap<String, Object> country = null; 

     // Taking each country, parses and adds to list object 
     for(int i=0; i<countryCount;i++){ 
      try { 
       // Call getCountry with country JSON object to parse the country 
       country = getCountry((JSONObject)jCountries.get(i)); 
       countryList.add(country); 

      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 

     return countryList; 
    } 

    // Parsing the Country JSON object 
    private HashMap<String, Object> getCountry(JSONObject jCountry){ 

     HashMap<String, Object> country = new HashMap<String, Object>(); 
     String countryName = ""; 
     String flag=""; 
     /*String language = ""; 
     String capital = ""; 
     String currencyCode = ""; 
     String currencyName = "";*/ 

     try { 
      countryName = jCountry.getString("STORENAME"); 
      flag = jCountry.getString("logo"); 
      /*language = jCountry.getString("language"); 
      capital = jCountry.getString("capital"); 
      currencyCode = jCountry.getJSONObject("currency").getString("code"); 
      currencyName = jCountry.getJSONObject("currency").getString("currencyname");*/ 

      /*String details =  "Language : " + language + "\n"; + 
        "Capital : " + capital + "\n" + 
        "Currency : " + currencyName + "(" + currencyCode + ")";*/ 

      country.put("country", countryName); 
      country.put("flag", R.drawable.ninety_six); 
      country.put("flag_path", flag); 
      //country.put("details", details); 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return country; 
    } 

這是我從logcat中得到錯誤

java.lang.NullPointerException 
      at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93) 
      at android.widget.AdapterView.checkFocus(AdapterView.java:713) 
      at android.widget.AdapterView$AdapterDataSetObserver.onInvalidated(AdapterView.java:836) 
      at android.widget.AbsListView$AdapterDataSetObserver.onInvalidated(AbsListView.java:6288) 
      at android.database.DataSetObservable.notifyInvalidated(DataSetObservable.java:50) 
      at android.widget.BaseAdapter.notifyDataSetInvalidated(BaseAdapter.java:59) 
      at android.widget.SimpleAdapter$SimpleFilter.publishResults(SimpleAdapter.java:383) 
      at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282) 

我只需要用戶通過提供的edittext框來搜索列表視圖。我已經嘗試了谷歌的許多解決方案,但它不適合我的情況。

+1

確保'adapter'不爲空,然後執行'getCount將()' –

+0

@VickyThakor的適配器不爲空,它不起作用。 – SOFT1234

回答

0

你得到的NPE由這個原因引起:

at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93) 

這基本上說,項目的背後是SimpleAdapternull

確保您的JSON解析器退貨商品不爲空,在該行檢查您的MainActivity

try{ 
    if(countryJsonParser.parse(jObject) != null) { 
     countries = countryJsonParser.parse(jObject); 
    } 
}catch(Exception e){ 
    Log.d("Exception",e.toString()); 
} 
+0

它仍然在logcat中給出相同的錯誤 – SOFT1234

相關問題