从onClickListener中的自定义适配器创建的ListView中删除行

时间:2015-01-17 20:13:40

标签: android listview android-listview arraylist android-custom-view

您好我从服务器获取数据并将其传递到我的自定义适配器中以填充我的ListView。以下是我的自定义适配器代码:

public class AppointmentAdapter extends BaseAdapter {

private AppointmentAdapter adapter;
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
HashMap<String, String> todo = new HashMap<String, String>();
 // String confirmation;
RelativeLayout confirm_corner;


public AppointmentAdapter(Activity a, ArrayList<HashMap<String,        String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    //imageLoader=new ImageLoader(activity.getApplicationContext());
}

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

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}



public View getView(final int position, View convertView, ViewGroup parent) {
    //View vi=convertView;
    //if(convertView==null)
       final View  vi = inflater.inflate(R.layout.appointments_list_item, null);
    adapter = new AppointmentAdapter(activity,data);
    TextView aid = (TextView)vi.findViewById(R.id.aid); // id
    TextView apptitle = (TextView)vi.findViewById(R.id.apptitle); // title
    TextView starts_date = (TextView)vi.findViewById(R.id.starts_date); // created_at
    TextView starts_time = (TextView)vi.findViewById(R.id.starts_time);
    TextView contact = (TextView)vi.findViewById(R.id.contact);
    TextView confirmation = (TextView)vi.findViewById(R.id.confirmation);
    confirm_corner = (RelativeLayout)vi.findViewById(R.id.confirm_corner);

    //CheckBox check = (CheckBox)vi.findViewById(R.id.tododone); // checkbox


    todo = data.get(position);

    // Setting all values in listview
    aid.setText(todo.get(AppointmentsFragment.TAG_AID));
    apptitle.setText(todo.get(AppointmentsFragment.TAG_APPTITLE));
    starts_date.setText(todo.get(AppointmentsFragment.TAG_STARTDATE));
    starts_time.setText(todo.get(AppointmentsFragment.TAG_STARTTIME));
    contact.setText(todo.get(AppointmentsFragment.TAG_CONTACT));
    confirmation.setText(todo.get(AppointmentsFragment.TAG_CONFIRMATION));
    String test = todo.get(AppointmentsFragment.TAG_USER_EMAIL);
    //Handle buttons and add onClickListeners
    ImageView accept = (ImageView)vi.findViewById(R.id.accept);
    ImageView deny = (ImageView)vi.findViewById(R.id.deny);
    //String test = confirmation.getText().toString();
    //&& (!test.equals(MainActivity.user_email))
    Log.d("CONFIRMATION: ", MainActivity.user_email);
    if (confirmation.getText().toString().equals("pending")  ){
        Log.d("PASS CONFIRMATION: ", confirmation.getText().toString());
        confirm_corner.setVisibility(View.VISIBLE);
    }

    accept.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) { 
            //do something
            confirm_corner = (RelativeLayout)vi.findViewById(R.id.confirm_corner);
            Log.d("Button accept: ", MainActivity.user_email);
            new Confirm_appointment().execute();
            //vi.setBackgroundColor(Color.RED);
            confirm_corner.setVisibility(View.GONE);


        }
    });
    deny.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) { 
            //do something
            Log.d("Button deny: ", MainActivity.user_email);
            new Deny_appointment().execute();
            confirm_corner.setVisibility(View.INVISIBLE);
            //adapter = new AppointmentAdapter(this,data);
            data.remove(position);
            data.clear();
            data.addAll(data); 
            adapter.notifyDataSetChanged();
        }
    });


    return vi;
}

我希望当我点击要删除的行的拒绝按钮时。我应该在代码中更改什么来修复此问题?

2 个答案:

答案 0 :(得分:1)

以下两个电话的目的是什么?:

data.clear();
data.addAll(data); 

要从ListView删除元素,只需致电data.remove(position),然后更新Adapteradapter.notifyDataSetChanged())。看看是否有效。

答案 1 :(得分:1)

请勿在{{1​​}}内创建新的AppointmentAdapter。当您在删除行后尝试AppointmentAdapter时,您会通知错误的适配器。您通知新构造的适配器,该适配器不是已更改数据的适配器。 (新构建的那些没有附加到列表视图,因此他们无法确保通知到达那个。)

您应该记住,只需要一个适配器就可以与具有多个项目视图的ListView一起使用。您为每个项目视图构建一个适配器,但这不起作用。适配器应与ListView配合使用,而不与项目视图配合使用。

我会对你的代码做很多不同的事情,我认为你应该实现View Holder模式。你可以阅读它here

<强>更新

您必须在notifyDataSetChanged()上调用adapter.notifyDataSetChanged(),而不是致电this。其中this应该是您刚刚删除该行的适配器。因为您使用View.OnClickListener的匿名(非静态)内部类,所以可以使用AppointmentAdapter.this来访问外部类,这是您想要的适配器。

试试这个:

deny.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) { 
        //do something
        Log.d("Button deny: ", MainActivity.user_email);
        new Deny_appointment().execute();
        confirm_corner.setVisibility(View.INVISIBLE);
        AppointmentAdapter.this.data.remove(position);
        AppointmentAdapter.this.notifyDataSetChanged();
    }
});

顺便说一句,我同意Willis的说法,那就是你清理数据并重新加载数据的行似乎是错误的。所以我也把它们扔掉了。