Reputation: 462
Hi i get my data from a server and pass them in my Custom Adapter to populate my ListView. Below is my custom Adapter code:
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;
}
I want when i click on the deny button that row to be removed. What should i change in my code to get this fixed?
Upvotes: 0
Views: 1081
Reputation: 2937
Don't create a new AppointmentAdapter
inside the AppointmentAdapter
. When you try to notifyDataSetChanged()
after you removed a row you then notify the wrong adapter. You notify the newly constructed adapter which is not the one that has changed data. (The newly constructed ones are not attached to the listview either so they couldn't make sure the notifications reach that anyway.)
You should remember that only a single adapter is needed to work together with the a ListView which has multiple item Views. You construct one adapter per item view but that wont work. The adapter is supposed to cooperate with the ListView and not with the item views.
There are many things I would do different with your code and I think you should implement the View Holder pattern. You can read about it here.
update
Instead of calling adapter.notifyDataSetChanged()
you have to call it on this
. Where this
should be the adapter where you just removed the row. Because you are using anonymous (non-static) inner classes for the View.OnClickListener
you can reach the outer class by using AppointmentAdapter.this
, which is the adapter that you want.
Try 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();
}
});
By the way, I agree with Willis that the lines where you clear out your data and reload it seems just wrong. So I threw them out too.
Upvotes: 1
Reputation: 5336
What is the purpose of the following two calls?:
data.clear();
data.addAll(data);
To remove an element from your ListView
simply call data.remove(position)
and then update the Adapter
(adapter.notifyDataSetChanged()
). See if that works.
Upvotes: 1