2013-10-31 125 views
0

我想通過以下tutorial製作自定義列表適配器。當我的對象從我的JSON數據中獲取項目並將其添加到列表中時,我遇到了麻煩。我已經能夠使用簡單的列表適配器和哈希映射。我想擺脫簡單的列表適配器和散列映射。這裏是我的堆棧跟蹤:自定義列表適配器不工作JSON到Android列表

10-31 13:17:19.985: E/AndroidRuntime(15047): FATAL EXCEPTION: main 
10-31 13:17:19.985: E/AndroidRuntime(15047): java.lang.NullPointerException 
10-31 13:17:19.985: E/AndroidRuntime(15047): at com.almyz125.ammobot.MainActivity$ViewHolder.<init>(MainActivity.java:62) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at com.almyz125.ammobot.MainActivity$FancyAdapter.getView(MainActivity.java:44) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.AbsListView.obtainView(AbsListView.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.ListView.measureHeightOfChildren(ListView.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.ListView.onMeasure(ListView.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.View.measure(View.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.RelativeLayout.measureChild(RelativeLayout.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.View.measure(View.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.FrameLayout.onMeasure(FrameLayout.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.View.measure(View.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.View.measure(View.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.widget.FrameLayout.onMeasure(FrameLayout.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.View.measure(View.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.Choreographer$CallbackRecord.run(Choreographer.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.Choreographer.doCallbacks(Choreographer.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.Choreographer.doFrame(Choreographer.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.os.Handler.handleCallback(Handler.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.os.Handler.dispatchMessage(Handler.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.os.Looper.loop(Looper.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at android.app.ActivityThread.main(ActivityThread.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at java.lang.reflect.Method.invokeNative(Native Method) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at java.lang.reflect.Method.invoke(Method.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115) 
10-31 13:17:19.985: E/AndroidRuntime(15047): at dalvik.system.NativeStart.main(Native Method) 

這裏是我的main_activity:

package com.almyz125.ammobot; 

import java.util.ArrayList; 

import org.json.JSONArray; 
import org.json.JSONObject; 

import android.app.Activity; 
import android.app.ProgressDialog; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

    private String apiURLBase, ammoCat; 
    private ProgressDialog pDialog; 
    ArrayList<Ammo> arrayJSONList = new ArrayList<Ammo>(); 
    private JSONArray ammos; 
    private FancyAdapter fa = null; 

    public class Ammo { 
     public String href; 
     public String desc; 
     public String stock; 
     public String price; 
     public String rd; 
    } 

    public class FancyAdapter extends ArrayAdapter<Ammo> { 
     FancyAdapter() { 
      super(MainActivity.this, android.R.layout.simple_list_item_1, 
        arrayJSONList); 
     } 

     public View getView(int position, View convertView, ViewGroup parent) { 
      ViewHolder holder = new ViewHolder(convertView); 

      if (convertView == null) { 
       LayoutInflater inflater = getLayoutInflater(); 
       convertView = inflater.inflate(R.layout.row, null); 
      } else { 
       holder = (ViewHolder) convertView.getTag(); 
      } 
      holder.populateFrom(arrayJSONList.get(position)); 
      return (convertView); 
     } 
    } 

    public class ViewHolder { 
     public TextView desc = null, href = null, round = null, 
       stock = null, price = null; 

     ViewHolder(View row) { 
      desc = (TextView) row.findViewById(R.id.desc); 
      href = (TextView) row.findViewById(R.id.href); 
      round = (TextView) row.findViewById(R.id.rd); 
      stock = (TextView) row.findViewById(R.id.stock); 
      price = (TextView) row.findViewById(R.id.price); 
     } 

     void populateFrom(Ammo r) { 
      desc.setText(r.desc); 
      href.setText(r.href); 
      round.setText(r.rd); 
      stock.setText(r.stock); 
      price.setText(r.price); 
     } 

    } 

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

     apiURLBase = getString(R.string.api_base_url); 
     ammoCat = "22lr"; 

     new GetJSONTask().execute(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    private class GetJSONTask extends AsyncTask<String, Void, ArrayList<Ammo>> { 


     @Override 
     protected void onPreExecute() { 
      if (pDialog != null) { 
       pDialog.dismiss(); 
      } 

      pDialog = new ProgressDialog(MainActivity.this); 
      pDialog.setMessage("Please wait.."); 
      pDialog.setIndeterminate(true); 
      pDialog.setCancelable(false); 
      pDialog.show(); 
     } 

     @Override 
     protected void onPostExecute(ArrayList<Ammo> valid) { 
      if (pDialog != null) { 
       pDialog.dismiss(); 
      } 

          ListView lv = (ListView)findViewById(R.id.mainList); 
      fa = new FancyAdapter(); 
      lv.setAdapter(fa); 

     } 

     @Override 
     protected ArrayList<Ammo> doInBackground(String... arg0) { 

      try { 
       JSONParser jParser = new JSONParser(); 
       JSONObject json = jParser.getJSONFromUrl(apiURLBase + ammoCat); 
       ammos = json.getJSONArray(ammoCat); 

       //System.out.println(ammos.toString()); 

       for (int i = 0; i < ammos.length(); i++) { 
        JSONObject json_data = ammos.getJSONObject(i); 

        Ammo resultRow = new Ammo(); 
        resultRow.desc = json_data.getString("desc"); 
        resultRow.href = json_data.getString("href"); 
        resultRow.price = json_data.getString("price"); 
        resultRow.stock = json_data.getString("stock"); 
        resultRow.rd = json_data.getString("rd"); 

        arrayJSONList.add(resultRow); 
       } 

      } catch (Exception e) { 
       Log.e(ammoCat, "Error:", e); 
      } 

      return arrayJSONList; 
     } 

    } 

} 

這裏是我的JSON解析器類:

package com.almyz125.ammobot; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.util.Log; 

public class JSONParser { 

    static InputStream is = null; 
    static JSONObject jObj = null; 
    static String json = ""; 

    // constructor 
    public JSONParser() { 

    } 

    public JSONObject getJSONFromUrl(String url) { 

     // Making HTTP request 
     try { 
      // defaultHttpClient 
      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpPost httpPost = new HttpPost(url); 

      HttpResponse httpResponse = httpClient.execute(httpPost); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      is = httpEntity.getContent();   

     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        is, "iso-8859-1"), 8); 
      StringBuilder sb = new StringBuilder(); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
      is.close(); 
      json = sb.toString(); 
     } catch (Exception e) { 
      Log.e("Buffer Error", "Error converting result " + e.toString()); 
     } 

     // try parse the string to a JSON object 
     try { 
      jObj = new JSONObject(json); 
     } catch (JSONException e) { 
      Log.e("JSON Parser", "Error parsing data " + e.toString()); 
     } 

     // return JSON String 
     return jObj; 

    } 
} 

錯誤是從管線62來這是該類:

public class ViewHolder { 
    public TextView desc = null, href = null, round = null, 
      stock = null, price = null; 

    ViewHolder(View row) { 
     desc = (TextView) row.findViewById(R.id.desc); 
     href = (TextView) row.findViewById(R.id.href); 
     round = (TextView) row.findViewById(R.id.rd); 
     stock = (TextView) row.findViewById(R.id.stock); 
     price = (TextView) row.findViewById(R.id.price); 
    } 

    void populateFrom(Ammo r) { 
     desc.setText(r.desc); 
     href.setText(r.href); 
     round.setText(r.rd); 
     stock.setText(r.stock); 
     price.setText(r.price); 
    } 

} 

and this li NE:

desc = (TextView) row.findViewById(R.id.desc); 

新適配器類:

public class FancyAdapter extends ArrayAdapter<Ammo> { 
    FancyAdapter() { 
     super(MainActivity.this, android.R.layout.simple_list_item_1, 
       arrayJSONList); 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 

     if (convertView == null) { 
      LayoutInflater inflater = getLayoutInflater(); 
      convertView = inflater.inflate(R.layout.row, null); 
      holder = new ViewHolder(convertView); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     holder.populateFrom(arrayJSONList.get(position)); 
     return (convertView); 
    } 
} 

我現在得到這個堆棧:

10-31 13:30:27.065: E/AndroidRuntime(16085): FATAL EXCEPTION: main 
10-31 13:30:27.065: E/AndroidRuntime(16085): java.lang.NullPointerException 
10-31 13:30:27.065: E/AndroidRuntime(16085): at com.almyz125.ammobot.MainActivity$FancyAdapter.getView(MainActivity.java:53) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.AbsListView.obtainView(AbsListView.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.ListView.measureHeightOfChildren(ListView.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.ListView.onMeasure(ListView.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.View.measure(View.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.RelativeLayout.measureChild(RelativeLayout.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.View.measure(View.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.FrameLayout.onMeasure(FrameLayout.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.View.measure(View.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.View.measure(View.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.widget.FrameLayout.onMeasure(FrameLayout.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.View.measure(View.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.Choreographer$CallbackRecord.run(Choreographer.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.Choreographer.doCallbacks(Choreographer.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.Choreographer.doFrame(Choreographer.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.os.Handler.handleCallback(Handler.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.os.Handler.dispatchMessage(Handler.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.os.Looper.loop(Looper.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at android.app.ActivityThread.main(ActivityThread.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at java.lang.reflect.Method.invokeNative(Native Method) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at java.lang.reflect.Method.invoke(Method.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115) 
10-31 13:30:27.065: E/AndroidRuntime(16085): at dalvik.system.NativeStart.main(Native Method) 

的錯誤似乎是在這裏:

holder.populateFrom(arrayJSONList.get(position)); 

仍在上述線路上發生錯誤。

這裏是我現在的GET觀點:

public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 

     if (convertView == null) { 
      LayoutInflater inflater = getLayoutInflater(); 
      convertView = inflater.inflate(R.layout.row, null); 
      convertView.setTag(holder); 
      holder = new ViewHolder(convertView); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     holder.populateFrom(arrayJSONList.get(position)); 
     return (convertView); 
    } 
+0

'MainActivity.java當你將有一個NullPointerException:62'什麼呢? – njzk2

+0

desc =(TextView)row.findViewById(R.id.desc); – almyz125

回答

0

嘗試在onPostExecute設置適配器,因爲你無法更新從輔助線程的用戶界面。

@Override 
     protected void onPostExecute(ArrayList<Ammo> valid) { 
      if (pDialog != null) { 
       pDialog.dismiss(); 
      } 
      ListView lv = (ListView)findViewById(R.id.mainList); 
      fa = new FancyAdapter(); 
      lv.setAdapter(fa); 
     } 

編輯: - 定義象下面

public class Ammo { 
    public String href; 
    public String desc; 
    public String stock; 
    public String price; 
    public String rd; 

    public Ammo(String href, String desc, String stock, String price, String rd) { 
     this.href = href; 
     this.desc = desc; 
     this.stock = stock; 
     this.price = price; 
     this.rd = rd; 
    } 

    public String getHref() { 
     return href; 
    } 

    public String getDesc() { 
     return desc; 
    } 

    public String getStock() { 
     return stock; 
    } 

    public String getPrice() { 
     return price; 
    } 

    public String getRd() { 
     return rd; 
    } 

} 
+0

我做到了,現在我的堆棧跟蹤更小。我會在上面張貼它。 – almyz125

+0

@ almyz125現在有什麼問題? –

+0

我編輯的主要帖子,新的堆棧跟蹤是在現場舊的,我改變了主要活動onPostExecute,以顯示我現在如何運行它。 – almyz125

0

ViewHolder holder = new ViewHolder(convertView);

在這一行,convertView可以爲空Ammo類。你需要在if區塊內移動這條線,在你膨脹後convertView = inflater.inflate(R.layout.row, null);

+0

我做到了這一點,我現在得到了第53行的錯誤,我編輯了信息的主要帖子。 – almyz125

+0

查看喬納森的答案。你不會把持有人放在視圖的標籤中,因此無法用getTag取回。 – njzk2

0

由於njzk2說你必須在創建視圖後移動ViewHolder holder = new ViewHolder(convertView);

而且你還必須設置convertView.setTag(holder);,否則前往holder = (ViewHolder) convertView.getTag();

public View getView(int position, View convertView, ViewGroup parent) 
    { 
     if (convertView == null) { 
      LayoutInflater inflater = getLayoutInflater(); 
      convertView = inflater.inflate(R.layout.row, null); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     ViewHolder holder = new ViewHolder(convertView); 
     convertView.setTag(holder); 

     holder.populateFrom(arrayJSONList.get(position)); 
     return (convertView); 
    } 
+0

剛剛嘗試過,我仍然收到第54行的錯誤:holder.populateFrom(arrayJSONList.get(position)); 我編輯了主帖。 – almyz125

+0

逆行:convertView.setTag(holder)和holder = new ViewHolder(convertView); – nsvir

+0

我用代碼編輯了我的答案 –

相關問題