Reputation: 1166
I have a ListView that contains 5 rows with 5 button:
When I click on first button, I replace it text with "B".
Then, I click on second button, I replace it text with "B", but how can I replace the previous clicked button (the first) with "A"?
This is what really happen:
This is my code for the button click:
private int resource;
private LayoutInflater inflater;
ViewHolder holder;
private Context ctx;
public RingtoneAdapter(Context context, int resourceId, List<Ringtone> objects) {
super(context, resourceId, objects);
this.ctx = context;
resource = resourceId;
inflater = LayoutInflater.from(context);
}
public View getView(final int position, View v, ViewGroup parent) {
// Recuperiamo l'oggetti che dobbiamo inserire a questa posizione
final Ringtone ringtone = getItem(position);
if (v == null) {
v = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.btnPlay = (Button) v.findViewById(R.id.btnPlay);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Button btnadd = (Button) view;
btnadd.setText("B");
notifyDataSetChanged();
}
});
return v;
}
private static class ViewHolder {
Button btnPlay;
TextView txtTitolo;
TextView txtCategoria;
}
Upvotes: 2
Views: 130
Reputation: 4549
you need to reset the items which were not clicked,
btn.setText("B"); // if the item was clicked
btn.setText("A"); // for all other items
what you can do is, cycle through all elements setting the text for button like this btn.setText("A")
, once this is done call btn.setText("B")
you should be using OnItemClickListener
on the listview
, it is easy that way, as you are setting the value in view holder, it does not give you access to the other items in the listview
, but by using OnItemClickListener
you can cover all the elements in the listview
once you update things as you like call notifyDataSetChanged()
, As this can be done there is another way to look at the problem
ListView listView = (ListView) findViewById(R.id.ListViewTestSevenActivity_listView);
ArrayList<Item> items = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Item item = new Item("A");
items.add(item);
}
MyAdapter adapter = new MyAdapter(getApplicationContext(), R.layout.simple_list_item_1, items);
listView.setAdapter(adapter);
This will take care of initialization and rest of the code as you want it to work. code is also available on github
private class MyAdapter extends ArrayAdapter {
private Context a_context;
private ArrayList<Item> items;
private LayoutInflater a_layoutInflater;
public MyAdapter(Context context, int resource, ArrayList<Item> items) {
super(context, resource, items);
this.a_context = context;
this.items = items;
a_layoutInflater = LayoutInflater.from(this.a_context);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
row = a_layoutInflater.inflate(R.layout.single_item_listview_seven, parent, false);
holder = new ViewHolder();
holder.button = (Button) row.findViewById(R.id.ListViewTestSevenActivity_text_button);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Item item = items.get(position);
System.out.println("" + item.getText());
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (Item current_item : items) {
current_item.setText("A");
}
item.setText("B");
notifyDataSetChanged();
}
});
holder.button.setText("" + item.getText());
return row;
}
private class ViewHolder {
Button button;
}
}
private class Item {
String text;
public Item(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Upvotes: 0
Reputation: 6834
If I'm reading this correctly, you only want a single position to be 'selected' at a time. If that's the case, you could keep a reference to the selected position, and use the Adapter's functionality instead of having multiple buttons know about each other. e.g.
private int selectedPosition = -1;
@Override
public View getView(final int position, View convertView, ViewGroup parent){
// ... Your ViewHolder / Ringtone initialization
if(position == selectedPosition)
holder.btnPlay.setText("B");
else holder.btnPlay.setText("A");
holder.btnPlay.setOnClickListener(new View.OnClickListener(){
if(holder.btnPlay.getText().toString().equals("A"))
selectedPosition = position;
else selectedPosition = -1;
notifyDataSetChanged();
});
return convertView;
}
The key here is allowing notifyDataSetChanged()
to internally call your getView method, which then really only needs to know how to render the data in its current state, instead of dealing with the complex logic required to map between multiple Views.
Upvotes: 1