Reputation: 81
So, what I want is to individually disable a button for the concerned item in the ListView when clicked on the button itself. This should work for multiple buttons as well.
I tried many places for solutions but didn't get a good enough answer.
What's happening is when i click on a button in the listview, i see other buttons getting clicked automatically when i scroll down to see other buttons which is quite weird and not helping the situation.
This is the Adapter.
public class ListViewAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
private StringBuilder user_id;
private Button sendReq;
private ListViewAdapter adapter;
private JSONArray peopleArray;
private int selectedIndex;
private ViewHolder viewHolder;
private static boolean[] buttonsClicked;
private View rowView;
public ListViewAdapter(ArrayList<String> list, Context context,String user_id,JSONArray jsonArray) {
this.user_id = new StringBuilder(user_id.toString());
this.list = list;
this.context = context;
peopleArray = jsonArray;
selectedIndex = -1;
this.adapter = this;
buttonsClicked = new boolean[list.size()];
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int pos) {
return list.get(pos);
}
@Override
public long getItemId(int pos) {
//return list.get(pos).getId();
//just return 0 if your list items do not have an Id variable.
return 0;
}
@Override
public boolean isEnabled(int position){
return false;
}
static class ViewHolder{
public TextView ItemText;
public Button ItemButton;
}
public void setSelectedIndex(int index){
selectedIndex = index;
notifyDataSetChanged();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.my_custom_list_layout, null);
//configure view holder
viewHolder = new ViewHolder();
viewHolder.ItemText = (TextView) rowView.findViewById(R.id.list_item_text);
viewHolder.ItemButton = (Button) rowView.findViewById(R.id.list_item_button);
rowView.setTag(viewHolder);
}
else {
//fill data
viewHolder = (ViewHolder) rowView.getTag();
}
//Handle TextView and display string from your list
TextView listItemText = (TextView)rowView.findViewById(R.id.list_item_text);
listItemText.setText(list.get(position));
//Handle buttons and add onClickListeners
sendReq = (Button) rowView.findViewById(R.id.list_item_button);
viewHolder.ItemButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
//do something
//list.remove(position); //or some other task
Log.d("Button position: ", " " + position);
((Button)v).setEnabled(false);
notifyDataSetChanged();
}
});
return rowView;
}
}
This is the layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:weightSum="100"
android:orientation="horizontal">
<ImageView
android:id="@+id/list_item_image"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="20"
android:src="@drawable/default_picture"/>
<TextView
android:id="@+id/list_item_text"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:gravity="center"
android:layout_weight="50"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="@+id/list_item_button"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="30"
android:text="Send Req"
android:focusable="false"/>
</LinearLayout>
This is how I am using the adapter in an activity
arrayList.add("Never");
arrayList.add("let");
arrayList.add("anyone");
arrayList.add("make");
arrayList.add("you");
arrayList.add("that");
arrayList.add("you");
arrayList.add("have");
arrayList.add("limits");
myAdapter = new ListViewAdapter(arrayList,this,"",jsonArray);
listview.setAdapter(myAdapter);
Upvotes: 3
Views: 275
Reputation: 95656
When you click a button, it will disable one Button
. Then, when you scroll, that Button
will get recycled and reused by other items. You never reenable that Button
, so after a while, scrolling up and down, all your Button
s will be disabled.
This isn't the correct way to do this. You cannot make changes in any View
based on some action that the user makes (like clicking a button) because the View
s in a ListView
all get recycled and reused for different list items. When the user takes some action you need to change your data. In getView()
you need to use the data to set the state of the View
s.
In your case, you could do something like this:
private boolean[] enabled
array as a member variable in the adapter.Initialize the array in your adapter constructor like this:
enabled = new boolean[list.size()];
// Enable all items
for (int k = 0; k < enabled.length; k++) {
enabled[k] = true;
}
In your onClick()
method, do this instead of disabling the Button
:
enabled[position] = false;
notifyDataSetChanged();
In getView()
, set the Button
enabled state based on your data like this:
viewHolder.ItemButton.setEnabled(enabled[position]);
Upvotes: 2