OnOptionsItemSelected中的空指针异常

时间:2014-12-24 13:54:56

标签: java android eclipse

单击操作栏上的删除图标时,我试图从列表视图中删除多个已检查的行。但是,我得到这些nullpointerexception,我认为问题将在适配器和dbHelper,因为我只声明它们,但我不知道我怎么能解决这个问题。

public class MainActivity extends ActionBarActivity {

    public static TaskerDbHelper dbHelper;
    public static ListView listviewTasks;
    public static List<Task> arrayTasks;
    public static TaskAdapter adapter;

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

       dbHelper = new TaskerDbHelper(this);
       arrayTasks = dbHelper.getAllTasks();

    listviewTasks = (ListView) findViewById(R.id.Tasks_onDate);
    adapter = new TaskAdapter(this,arrayTasks);
    listviewTasks.setAdapter(adapter);

    listviewTasks.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            // TODO Auto-generated method stub
            Intent detailIntent = new Intent(MainActivity.this, DetailTaskActivity.class);
            detailIntent.putExtra("rowID", (int)id);
            startActivity(detailIntent);
        }
    });

    @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 super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.

        switch(item.getItemId()){
        case R.id.action_search:
            return true;
        case R.id.action_add:
            Intent Addintent = new Intent(MainActivity.this, AddTaskActivity.class);
            startActivity(Addintent);
            return true;
        case R.id.action_delete:
            SparseBooleanArray checkedItems = listviewTasks.getCheckedItemPositions();
            for (int i = 0; i < checkedItems.size(); i++){
                if(checkedItems.valueAt(i)){
                    dbHelper.deleteTask((int)adapter.getItemId(i));
                }
            }
            listviewTasks.invalidateViews();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }

    }
}

并且日志是  http://i.stack.imgur.com/OqLuN.png

2 个答案:

答案 0 :(得分:0)

我的猜测是使用扩展的ArrayAdapter。对于我来说,这对于多次点击 - >删除列表视图来说就像是一种魅力。

我宣布这一切都是这样的:

    arrayAdapter = new ListAdapter(this,R.layout.list_item, **YOUR LIST**);
    listview.setAdapter(arrayAdapter);
    listview.setCacheColorHint(Color.TRANSPARENT);
    selectedItems = new ArrayList<Integer>();
    listview.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // TODO Auto-generated method stub
             ArrayList<Integer> selectedIds = arrayAdapter.selectedid;
             Integer pos = new Integer(position);
             if(selectedIds.contains(pos)) {
                 selectedIds.remove(pos);
             }
             else {
                 selectedIds.add(pos);
             }

             arrayAdapter.notifyDataSetChanged();
        }

    });

我上课了。

public class ListAdapter extends ArrayAdapter<ChartItem> {

        Context context;

        protected ArrayList<**YOUR LIST ITEM**> list;
        LayoutInflater inflater;
        ArrayList<Integer> selectedid;

        public ListAdapter(Context context, int layoutResourceId ,ArrayList<ChartItem> ticket) {
            super(context,layoutResourceId,ticket);
            selectedid = new ArrayList<Integer>();
            this.list = **ARRAY YOU WANT TO LIST**;
            this.inflater = LayoutInflater.from(context);
            this.context = context;
        }

        public int getCount() {
            return list.size();
        }

        public ChartItem getItem(int position) {
            return list.get(position);
        }


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

                holder = new ViewHolder();
                convertView = this.inflater.inflate(R.layout.list_item, parent, false);

                holder.name = (TextView) convertView.findViewById(R.id.rowTextView);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            ChartItem item = list.get(position);
            TextView tv = (TextView) convertView.findViewById(R.id.rowTextView);
            tv.setText(item.getName());
            TextView tv2 = (TextView) convertView.findViewById(R.id.rowTextView2);
            tv2.setText(String.valueOf(item.getPrice()));
            if(selectedid.contains(position)){
                tv.setBackgroundColor(Color.DKGRAY);
                tv.setTextColor(Color.WHITE);
            }
            else{
                tv.setBackgroundColor(Color.TRANSPARENT);
                tv.setTextColor(Color.BLACK);
            }
            return convertView;
        }

        private class ViewHolder {
            TextView name;
        }
    }

我真的遇到了麻烦,我认为到目前为止这是最好的方法。 如果您需要更多帮助,或者对此代码段有疑问,请与我们联系!

答案 1 :(得分:0)

实际上,checkedItems为null。 我其实想达到这样的目的。因此,当用户检查行时,他们可能会删除或将其标记为已完成

http://i.stack.imgur.com/k4jKT.png

我通过下面的其他方法解决它。

case R.id.action_delete:
        for(int i = 0; i < arrayTasks.size();i++){
            if((CheckBox)listviewTasks.getChildAt(i).findViewById(R.id.selected) != null){

                CheckBox cBox=(CheckBox)listviewTasks.getChildAt(i).findViewById(R.id.selected);

                if(cBox.isChecked()){
                    dbHelper.deleteTask((int)adapter.getItemId(i));
                }
             }
            }  
        adapter.notifyDataSetChanged();
        return true;

我改变了onoptionitemselected函数的action_delete。

[1]: