删除所选ListView内容时出现问题

时间:2011-06-17 05:35:51

标签: android android-listview

我正在尝试从ListView中删除所选项目,问题是当我删除所选内容并刷新适配器时剩余内容的位置发生变化,因此在某些时候再次删除内容给出IndexOutOfBoundsException。有谁能告诉我如何解决这个问题?

以下是我删除所选项目的代码。

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

    View view = null;
    if (convertView == null) {
        LayoutInflater inflator = mActivity.getLayoutInflater();
        view = inflator.inflate(R.layout.main, null);

        final ViewHolder viewholder = new ViewHolder();
        viewholder.tvTitle = (TextView) view.findViewById(R.id.txttitle);
        viewholder.imgdelete = (ImageButton) view.findViewById(R.id.imgdelete);


        viewholder.imgdelete.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                    list.remove(position);
                    notifyDataSetChanged();
            }
        });
        view.setTag(viewholder);
    }
    else
    {
        view  = convertView;
    }

    ViewHolder viewholder = (ViewHolder) view.getTag();
    viewholder.tvTitle.setText(list.get(position).getmTitle());

            return view;
}

这是我的Logcat错误

     06-17 13:01:41.715: ERROR/AndroidRuntime(4284): FATAL EXCEPTION: main
06-17 13:01:41.715: ERROR/AndroidRuntime(4284): java.lang.IndexOutOfBoundsException: Invalid index 5, size is 5
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at java.util.ArrayList.remove(ArrayList.java:406)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at com.list.AdapterClass$1.onClick(AdapterClass.java:66)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at android.view.View.performClick(View.java:2408)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at android.view.View$PerformClick.run(View.java:8816)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at android.os.Handler.handleCallback(Handler.java:587)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at android.os.Handler.dispatchMessage(Handler.java:92)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at android.os.Looper.loop(Looper.java:123)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at android.app.ActivityThread.main(ActivityThread.java:4627)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at java.lang.reflect.Method.invokeNative(Native Method)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at java.lang.reflect.Method.invoke(Method.java:521)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):     at dalvik.system.NativeStart.main(Native Method)

7 个答案:

答案 0 :(得分:3)

尝试使用BaseAdapter而不是ArrayAdapter。因为BaseAdapter在使用自定义视图时效果最佳。

以下是示例代码..

public class AdapterClass extends BaseAdapter{

        List<MyModelClass> list;
        Activity mActivity;

        public AdapterClass(Activity context,List<MyModelClass> objects)
        {
                this.list = objects;
                this.mActivity = context;
        }

        static class ViewHolder{
                protected TextView tvTitle;
                protected ImageButton imgdelete;
        }
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {


                final ViewHolder viewholder;
                if (convertView == null) 
                {
                        viewholder = new ViewHolder();
                        LayoutInflater inflator = mActivity.getLayoutInflater();
                        convertView = inflator.inflate(R.layout.mainn, null);
                        viewholder.tvTitle = (TextView) convertView.findViewById(R.id.txttitle);
                        viewholder.imgdelete = (ImageButton) convertView.findViewById(R.id.imgdelete);
                        convertView.setTag(viewholder);
                }
                else
                {
                    viewholder = (ViewHolder)convertView.getTag();
                }
                    viewholder.imgdelete.setOnClickListener(new OnClickListener() {

                            @Override
                            public void onClick(View v) {

                                    System.out.println("position - " + position + " size - "+ list.size());
                                    list.remove(position);
                                    notifyDataSetChanged();
                                    Toast.makeText(mActivity, "deleted", Toast.LENGTH_LONG).show();
                            }
                    });

                viewholder.tvTitle.setText(list.get(position).getmTitle());
                return convertView;
        }
        @Override
        public int getCount() {
            return list.size();
        }
        @Override
        public Object getItem(int position) {
            return position;
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
}

答案 1 :(得分:1)

删除所选列表...

1)删除notifyDataSetChanged();

2)将位置本身的参数放到list.remove(position);

OR:

按照以下步骤操作:

1)在列表视图中选中一个复选框。绝对是动态列表并在适配器视图中显示。

2)在公共视图中getView()      holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                String updateall;
                DBConnect sts1 = new DBConnect(getApplicationContext(), "your database name");


                if(holder.checkBox.isChecked()){

                    updateall = "UPDATE Sever_Contain SET setcheck = 'true' WHERE id ="+cupos;
                    System.out.println(updateall);              

                }else{

                    updateall = "UPDATE Sever_Contain SET setcheck = 'false' WHERE id ="+cupos;
                    System.out.println(updateall);
                }
                    sts1.execNonQuery(updateall);                   
                    System.out.println(map);
                    sts1.close();
            }
        });

3)关于删除点击事件只需添加:      del.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            String deleteall = "DELETE from Sever_Contain where setcheck='true'";
            if(sts.isOpen()==false)
                sts.openDataBase();

                sts.execNonQuery(deleteall);                    
                sts.close();

        }
    });

4)从哪里开始这个Intent创建onResume()方法来更新它。

这会对你有帮助。

答案 2 :(得分:0)

使用处理程序更新列表视图

private Handler handler=new Handler()
{
        public void handleMessage(Message msg) {
        ArrayAdapter aa=new ArrayAdapter<String>(nextScreen.this,android.R.layout.test_list_item,mArray);
        list.setAdapter(aa);
        aa.notifyDataSetChanged();
        list.invalidate();              
}

};

如果你想更新listview,请调用像这样的处理程序

handler.sendEmptyMessage(0);

答案 3 :(得分:0)

在这里使用Handler的概念。 Step1 声明一个常量 private static final byte UPDATE_LIST = 100;

Step2 只需按一下按钮

即可调用处理程序
viewholder.imgdelete.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                    Message msg = new Message();
                msg.what = UPDATE_LIST;
                msg.arg1 = position
                updateListHandler.sendMessage(msg);
            }
        });

Step3 定义处理程序

private Handler updateListHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case UPDATE_LIST:
            int position = msg.arg1;
                list.remove(position);
                arrayAdapter.notifyDataSetChanged();
                break;

            }
            ;
        };
    };

How to divide and load a ListView in multiple parts?

中查看我的回复

由于 迪帕克

答案 4 :(得分:0)

几天前我遇到了同样的问题并问了同样的问题。 Here is the link to that question.这肯定对你有帮助。

答案 5 :(得分:0)

当我需要从listview中删除一个元素时,我所做的是:在listview的onclick中,只需从字符串数组中删除该项(使用它填充listview),然后调用类似这样的内容:

listview.setAdapter(new ArrayAdapter<String>(this,R.layout.listviewactivity ,your_string_array));

就像一个魅力,不需要处理任何索引超出限制的兴奋...希望它有所帮助:)

答案 6 :(得分:0)

尝试:

 viewholder.imgdelete.setTag(position);
    viewholder.imgdelete.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

                list.remove((Integer)v.getTag());
                notifyDataSetChanged();
        }
    });

您应该从位置参数中删除最终关键字。