2013-07-02 146 views
1

我正在創建ListView,每行有兩個元素(一個用於打開第二行以刪除行)。我已經在主要活動中我定製的ListView創建這樣的:notifyDataSetChanged()導致NullPointerException

ArrayList<String> names = Devices.getInstance().getNameList(); 

final StableArrayAdapter adapter = new StableArrayAdapter(this,listViewResourceId,names); 
final ListView listview = (ListView) findViewById(R.id.listView1); 
listview.setAdapter(adapter); 

我自己ArrayAdapter:

private class StableArrayAdapter extends ArrayAdapter<String> { 

    HashMap<String, Integer> mIdMap = new HashMap<String, Integer>(); 
    private final Activity mContext; 

    public StableArrayAdapter(Activity context, int textViewResourceId, List<String> objects) { 
     super(context, textViewResourceId, objects); 
     mContext = context; 
     for (int i = 0; i < objects.size(); ++i) { 
     mIdMap.put(objects.get(i), i); 
     } 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = null; 
     if (convertView == null) { 
     LayoutInflater inflator = mContext.getLayoutInflater(); 
     view = inflator.inflate(R.layout.row, null); 
     final ViewHolder viewHolder = new ViewHolder(); 
     viewHolder.text = (TextView) view.findViewById(R.id.label); 
     viewHolder.text.setText(getItem(position)); 
     viewHolder.button = (ImageButton) view.findViewById(R.id.del); 
     viewHolder.button.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO dodanie zapytania o usuniecie 
       StableArrayAdapter.this.mIdMap.remove(getItem(position)); 
       StableArrayAdapter.this.notifyDataSetChanged(); 
       //((BaseAdapter) ((ListView)findViewById(R.id.listView1)).getAdapter()).notifyDataSetChanged(); 
      } 

     }); 
     view.setTag(viewHolder); 
     } 

     return view; 
    } 

    @Override 
    public long getItemId(int position) { 
     String item = getItem(position); 
     return mIdMap.get(item); 
    } 

    @Override 
    public boolean hasStableIds() { 
     return true; 
    } 

    } 

問題是,當我試圖通過使用刪除按鈕來刪除行(其在點擊監聽器在上面)有在notifyDataSetChanged()行上的NullPointerException。我試着做非匿名類(用於OnClickListener),或從OnCreate切換到類字段的本地字段,但沒有任何工作 - 我想我正在做一些愚蠢的事情,但現在我是盲目的,不能看到此代碼中的任何內容。

在此先感謝幫助!

堆棧跟蹤:

07-02 10:24:26.604: E/AndroidRuntime(2109): FATAL EXCEPTION: main 
07-02 10:24:26.604: E/AndroidRuntime(2109): java.lang.NullPointerException 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.AbsListView.obtainView(AbsListView.java:2253) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.ListView.makeAndAddView(ListView.java:1769) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.ListView.fillSpecific(ListView.java:1318) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.ListView.layoutChildren(ListView.java:1600) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.AbsListView.onLayout(AbsListView.java:2102) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.View.layout(View.java:13754) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1420) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.View.layout(View.java:13754) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.View.layout(View.java:13754) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.View.layout(View.java:13754) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.View.layout(View.java:13754) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.View.layout(View.java:13754) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1866) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1687) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.Choreographer.doCallbacks(Choreographer.java:555) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.Choreographer.doFrame(Choreographer.java:525) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.os.Handler.handleCallback(Handler.java:615) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.os.Handler.dispatchMessage(Handler.java:92) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.os.Looper.loop(Looper.java:137) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at android.app.ActivityThread.main(ActivityThread.java:4745) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at java.lang.reflect.Method.invoke(Method.java:511) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
07-02 10:24:26.604: E/AndroidRuntime(2109):  at dalvik.system.NativeStart.main(Native Method) 
+0

我們能否看到一個堆棧跟蹤? – Tom

+0

當然對不起,忘了這個:) – lagoru

+0

你的適配器類在活動類或單獨的java文件? –

回答

1

你在裏面if (convertView == null) {}塊做的一切。只能用這個來膨脹和存儲持有人的意見。設置文本並單擊此塊以外的偵聽器,以便它們適用於每個視圖,重新循環或不重新循環。

實施例:

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 

    //--init if not re-cycled-- 
    if (convertView == null) { 
     convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, parent, false); 
     convertView.setTag(new ViewHolder(
       (TextView) convertView.findViewById(R.id.label), 
       (ImageButton) convertView.findViewById(R.id.del) 
     )); 
    } 

    //--data to set-- 
    String item = getItem(position); 

    View.OnClickListener listener = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      StableArrayAdapter.this.mIdMap.remove(getItem(position)); 
      StableArrayAdapter.this.notifyDataSetChanged(); 
     } 
    }; 

    //--set data-- 
    ViewHolder holder = (ViewHolder) convertView.getTag(); 
    holder.text.setText(item); 
    holder.button.setOnClickListener(listener); 
    return convertView; 
} 

private static class ViewHolder{ 
    public final TextView text; 
    public final Button button; 

    private ViewHolder(TextView text, Button button) { 
     this.text = text; 
     this.button = button; 
    } 
} 
+0

後我改爲這樣: – lagoru

+0

@lagoru看例子。 –

+0

對不起,讓你等待迴應 - 我不得不去阿克。還是同樣的問題,其他的東西,但感謝您的幫助。 – lagoru

1

嘗試此,

@Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
//  View view = null;   remove this line 
     if (convertView == null) { 
     LayoutInflater inflator = mContext.getLayoutInflater(); 
     view = inflator.inflate(R.layout.row, null); 
     } 
    final ViewHolder viewHolder = new ViewHolder(); 
    viewHolder.text = (TextView) convertView.findViewById(R.id.label); 
    viewHolder.text.setText(getItem(position)); 
    viewHolder.button = (ImageButton) convertView.findViewById(R.id.del); 
    viewHolder.button.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      // TODO dodanie zapytania o usuniecie 
      StableArrayAdapter.this.mIdMap.remove(getItem(position)); 
      StableArrayAdapter.this.notifyDataSetChanged(); 
      //((BaseAdapter) ((ListView)findViewById(R.id.listView1)).getAdapter()).notifyDataSetChanged(); 
     } 

    }); 
    view.setTag(viewHolder); 
    } 

    return view; 
} 
+0

也無法正常工作,但感謝您的幫助。 – lagoru

+0

現在檢查我的編輯答案我認爲你必須改變viewHolder.text =(TextView)View.findViewById(R.id.label);行 –

+0

問題是在程序的另一部分 - 但感謝幫助:) – lagoru

0

問題當然是愚蠢的,我試圖通過從只容器刪除它刪除行,沒有關於整個類StableArrayAdapter適當通知,而不是(在OnClickListener中):

StableArrayAdapter.this.mIdMap.remove(getItem(position)); 

我應該使用這個:

StableArrayAdapter.this.remove(getItem(position)); 
相關問題