2013-07-02 109 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)); 
相关问题