
Above shown is my custom listview with TextViews and RadioGroup. Based on whether the item status is "pending" or "served" I update the pending items-TextView (in red, on top). Everything is working as expected, and I am able to retain the RadioGroup selections on scroll.
However, when I scroll, the pending Items TextView does not retain its value. It changes whenever the list scrolls. Here is my getView method.
public View getView(final int position, View convertView, ViewGroup parent)
{
System.out.println(" --- position ---"+position+" --- isChecked[position] --- "+isChecked[position]);
ViewHolder viewHolder = null;
if(convertView == null)
{
convertView = layoutInflater.inflate(R.layout.order_status_listview_row, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder)convertView.getTag();
convertView.setTag(viewHolder);
}
viewHolder.itemName = (TextView)convertView.findViewById(R.id.textview_order_status_item_name);
viewHolder.itemQuantity = (TextView)convertView.findViewById(R.id.textview_order_status_item_quantity);
viewHolder.radioGroup = (RadioGroup)convertView.findViewById(R.id.radiogroup_order_status_dialog);
// isUserChanged[position] = false;
viewHolder.radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId)
{
// if(isUserChanged[position])
{
switch(checkedId)
{
case R.id.radiobutton_served:
System.out.println(" --- radiobutton_served ---"+" position "+position+" isChecked[position] "+isChecked[position]);
count--;
// countView.setText(DataHelper.getAppropriateCountValue(count));
isChecked[position] = true;
break;
case R.id.radiobutton_pending:
System.out.println(" --- radiobutton_pending ---"+" position "+position+" isChecked[position] "+isChecked[position]);
isChecked[position] = false;
count++;
// countView.setText(DataHelper.getAppropriateCountValue(count));
break;
}
countView.setText(DataHelper.getAppropriateCountValue(count));
}
// isUserChanged[position] = false;
}
});
viewHolder.radioGroup.setOnClickListener(new OnClickListener()
{
public void onClick(View view)
{
// isUserChanged[position] = true;
}
});
viewHolder.itemName.setText(orderList.get(position).getDishName());
viewHolder.itemQuantity.setText(orderList.get(position).getDishQuantity());
// change selection state for item checked when selection for radioButton changes
if(isChecked[position])
viewHolder.radioGroup.check(R.id.radiobutton_served);
else
viewHolder.radioGroup.check(R.id.radiobutton_pending);
return convertView;
}
I think I got it. Whenever you scroll, you change the values or your radiobuttons with your
if(isChecked[position])
viewHolder.radioGroup.check(R.id.radiobutton_served);
else
viewHolder.radioGroup.check(R.id.radiobutton_pending);
But you set a listener BEFORE you call that. So the listener is called each time.
Try this instead:
viewHolder.radioGroup.setOnCheckedChangeListener(null);
if(isChecked[position])
viewHolder.radioGroup.check(R.id.radiobutton_served);
else
viewHolder.radioGroup.check(R.id.radiobutton_pending);
viewHolder.radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId)
{
// if(isUserChanged[position])
{
switch(checkedId)
{
case R.id.radiobutton_served:
System.out.println(" --- radiobutton_served ---"+" position "+position+" isChecked[position] "+isChecked[position]);
count--;
// countView.setText(DataHelper.getAppropriateCountValue(count));
isChecked[position] = true;
break;
case R.id.radiobutton_pending:
System.out.println(" --- radiobutton_pending ---"+" position "+position+" isChecked[position] "+isChecked[position]);
isChecked[position] = false;
count++;
// countView.setText(DataHelper.getAppropriateCountValue(count));
break;
}
countView.setText(DataHelper.getAppropriateCountValue(count));
}
// isUserChanged[position] = false;
}
});
Hope this will help you.
Dya, I made a small example.
My Activity
contains a TextView
and a ListView
. The ListView is filled with 20 objects (RowObject) which have their own layout (row.xml). The code is pretty straight forward so you will have no problem reading it and understanding it.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/mTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0" />
<ListView
android:id="@+id/mListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/mTextView" >
</ListView>
</RelativeLayout>
row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RadioGroup
android:id="@+id/mRadioGroup"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RadioButton
android:id="@+id/mRadio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="radio1" />
<RadioButton
android:id="@+id/mRadio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="radio2" />
</RadioGroup>
</LinearLayout>
RowObject
public class RowObject {
private int ID;
private boolean firstChecked; // else second checked
public RowObject(int iD, boolean firstChecked) {
super();
ID = iD;
this.firstChecked = firstChecked;
}
public boolean isFirstChecked() {
return firstChecked;
}
public void setFirstChecked(boolean firstChecked) {
this.firstChecked = firstChecked;
}
}
MainActivity
public class MainActivity extends Activity {
private TextView mCountTextView;
private ArrayList<RowObject> mSource;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSource = new ArrayList<RowObject>();
for (int i = 0; i < 20; i++) {
mSource.add(new RowObject(i, false));
}
mCountTextView = (TextView) findViewById(R.id.mTextView);
ListView mListView = (ListView) findViewById(R.id.mListView);
mListView.setAdapter(new RadioButtonAdapter(getApplicationContext(), mSource));
}
private class RadioButtonAdapter extends ArrayAdapter<RowObject> {
class ViewHolder {
RadioGroup rbGroup;
RadioButton btn1;
RadioButton btn2;
}
private LayoutInflater mInflater;
public RadioButtonAdapter(Context context, ArrayList<RowObject> mSource) {
super(context, R.layout.row, mSource);
mInflater = LayoutInflater.from(context);
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.rbGroup = (RadioGroup) convertView.findViewById(R.id.mRadioGroup);
holder.btn1 = (RadioButton) convertView.findViewById(R.id.mRadio1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.rbGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.mRadio1:
mSource.get(position).setFirstChecked(true);
break;
case R.id.mRadio2:
mSource.get(position).setFirstChecked(false);
break;
}
mCountTextView.setText("There are " + getNumberOfFirstCheckedViews() + " first buttons selected");
}
});
if (mSource.get(position).isFirstChecked()) {
holder.btn1.setChecked(true);
holder.btn2.setChecked(false);
} else {
holder.btn1.setChecked(false);
holder.btn2.setChecked(true);
}
return convertView;
}
private int getNumberOfFirstCheckedViews() {
int count = 0;
for (RowObject object : mSource) {
if (object.isFirstChecked()) {
count++;
}
}
return count;
}
}
}
来源:https://stackoverflow.com/questions/11625990/listview-with-radiogroup-in-each-row