Remember selected state of RadioButton inside a list - android

I have a ListView with several items so that these will be re-used during scrolling.
An item is composed by a couple of TextViews and a RadioGroup, containing 3 RadioButtons.
The issue I'm having is that when I select for example a RadioButton for each of the 5 items, when I scroll the list down and back up again, the selection I did in the beginning is not being saved (which means no RadioButton or the wrong one will be shown as selected) while it can also happen that some RadioButtons will appear as selected even if I never tapped on those.
I'm trying to save the checkedId of the selection in a list but without luck.
Following my code:
public View getView(int position, View convertView, ViewGroup parent) {
...
int questionID = question.getQuestionID();
if (mappedSelectedAnswer.containsKey(questionID)) {
radioGroup.check(mappedSelectedAnswer.get(questionID));
} else {
radioGroup.check(-1);
}
...
}
And the RadioGroupListener
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId != -1) {
mappedSelectedAnswer.put(questionID, checkedId);
}
...
});
mappedSelectedAnswer is a List with key questionID, value the checkedId
As anyone have any suggestion to this issue?
Thanks

you might need to declare all of them into separate RadioGroup to select them for each Item. I hope it will help you.
Thanks

You need three things
1- A List to store the selected ID of each RadioGroup
2- A listener in the RadioGroup to set/reset the selected id when u tab on it
3- The adapter will check this list when creating the view and select the item that you saved in the listener

For Example:
<RadioGroup
android:id="#+id/group"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Standard Taxi (upto 4 passengers)"
android:id="#+id/standardTaxi"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:onClick="radio"
android:checked="true" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Wagon(upto 4 passengers)"
android:id="#+id/wagon"
android:layout_below="#+id/standardTaxi"
android:layout_alignParentStart="true"
android:onClick="radio"
android:checked="false" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Wheelchair Accessible Taxi"
android:id="#+id/wheelchair"
android:layout_below="#+id/wagon"
android:layout_alignParentStart="true"
android:onClick="radio"
android:checked="false" />
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Van/Maxi(5-11 passengers)"
android:id="#+id/van"
android:layout_centerVertical="true"
android:onClick="radio"
android:layout_alignParentStart="true"
android:checked="false" />
</RadioGroup>

Related

Radio Button setChecked/setSelected not working

I have a list view with a text and 3 radio button. If i select any radio button, and scroll the list the radio button gets un-selected. I am maintaining the ID of items for which radio button is selected and in adapter Getview setting the required radio button to be selected. On debugging, it's executing statement setChecked(true) but the radio button is still unchecked. I tried setSelected(true) and setting through radio group ((RadioButton)holder.rg.getChildAt(2)).setChecked(true); but nothing seem to be working.
XML:
<TextView
android:id="#+id/refill_product_name"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="#string/hello_world"
android:textColor="#android:color/black"
android:textStyle="normal"
android:textSize="#dimen/item_sub_heading"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_marginStart="#dimen/activity_horizontal_margin"/>
<RadioGroup
android:id="#+id/refill_product_rg"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<RadioButton
android:id="#+id/refill_product_regular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/regular"
android:textColor="#android:color/black"
android:textStyle="bold"
android:buttonTint="#color/primary"/>
<RadioButton
android:id="#+id/refill_product_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/small"
android:textColor="#android:color/black"
android:textStyle="bold"
android:layout_marginLeft="#dimen/radio_btn_margin"
android:buttonTint="#color/primary"/>
<RadioButton
android:id="#+id/refill_product_extra_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/extra_small"
android:textColor="#android:color/black"
android:textStyle="bold"
android:layout_marginLeft="#dimen/radio_btn_margin"
android:buttonTint="#color/primary"/>
</RadioGroup>
Adapter Code:
private class ViewHolder {
TextView productName;
RadioButton regularBtn, smallBtn, extraSmallBtn;
RadioGroup rg;
}
GetView Method in Adapter
holder.rg.clearCheck();
if (mAppSession.getSelRefillProducts() != null) {
for (RefillProduct pr : mAppSession.getSelRefillProducts()) {
if (pr.getProductId() == rf.getProductId()) {
if (pr.getSize().equals("R")) {
((RadioButton)holder.rg.getChildAt(0)).setChecked(true);
} else if (pr.getSize().equals("S")) {
holder.smallBtn.setSelected(true);
} else if (pr.getSize().equals("XS")) {
((RadioButton)holder.rg.getChildAt(2)).setChecked(true);
}
}
}
}
I am not sure if I am missing something, but setChecked or setSelected is not working. Please advise.
Try this, before setting radio button to checked, clear all the checks in the radio group:
yourRadioGroup.clearCheck();
yourRadioButton.setChecked(true);
I solved this by removing if (convertView == null) and the else part from getView method in adapter.
else {
holder = (ViewHolder) convertView.getTag();
It is an expected behavior of ListView since it reuses the View for each item. Consider tracking the checkbox checked state using a SparseBoolArray. Check out this link: Getting the state of a checkbox inside of a listview

keyboard reset radiogroup value

I have a custom ListView with a radiogroup in each row.
When I change the checked radio button, I call a dialog with some edittext fields (using the onCheckedChanged() method). But, when i focused an edittext to write something, I lose all the checked radiobuttons which are covered by keyboard, and the group returns to the default option selected.
can someone help me?
List adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ContractItemHolder cih = new ContractItemHolder();
if (row == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(R.layout.row_proposals_item, parent, false);
cih.setTvItemTitle((TextView)row.findViewById(R.id.textViewItemTitle));
cih.setRgItemStatus((RadioGroup)row.findViewById(R.id.radioGroupStatus));
row.setTag(cih);
}else {
cih=(ContractItemHolder)row.getTag();
}
final ContractItem ci = list.get(position);
cih.getRgItemStatus().setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
groupSel = group;
int selected = group.getCheckedRadioButtonId();
Dialog d;
switch (selected) {
case R.id.radioAccepted:
d = createDialog(context, ACCEPTED_CODE, ci, selected);
d.show();
break;
case R.id.radioRefused:
d = createDialog(context, REFUSED_CODE, ci, selected);
d.show();
break;
default:
break;
}
}
});
cih.getTvItemTitle().setText(ci.getDescItem());
return row;
}
List item layout (the row..)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:gravity="center">
<TextView
android:id="#+id/textViewItemTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Large Text"
android:layout_weight="3"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<RadioGroup
android:id="#+id/radioGroupStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1"
android:showDividers="middle">
<RadioButton
android:id="#+id/radioNull"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Non Proposto"
android:checked="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<RadioButton
android:id="#+id/radioPending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="In trattativa"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Blue"/>
<RadioButton
android:id="#+id/radioAccepted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Accettato"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Green"/>
<RadioButton
android:id="#+id/radioRefused"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rifiutato"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/Red"/>
</RadioGroup>
</LinearLayout>
Dialog impl
private Dialog createDialog(Context context, final int code, ContractItem item,final int selected){ //type: refused, accepted
d = new Dialog(context);
d.setTitle(item.getDescItem());
d.setContentView(R.layout.layout_dialog_prop);
d.getWindow().setLayout(900, LayoutParams.WRAP_CONTENT);
d.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Button btnOK = (Button)d.findViewById(R.id.buttonPropOK);
Button btnCancel = (Button)d.findViewById(R.id.buttonPropCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.dismiss();
}
});
btnOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
d.dismiss();
}
});
return d;
}
Dialog layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="50dp" >
<EditText
android:id="#+id/editTextDiscount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="Sconto proposto"
android:inputType="number"
android:textAppearance="?android:attr/textAppearanceLarge" >
<requestFocus />
</EditText>
<Spinner
android:id="#+id/spinnerScuse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:visibility="gone" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:ems="10"
android:gravity="top"
android:hint="Note"
android:inputType="textMultiLine"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<View
android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="30dp"
android:background="#android:color/holo_blue_light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/buttonPropCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Annulla"
android:textColor="#android:color/holo_blue_light" />
<View
android:id="#+id/view1"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light" />
<Button
android:id="#+id/buttonPropOK"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Ok"
android:textColor="#android:color/holo_blue_light" />
</LinearLayout>
</LinearLayout>
You are partially aware of the list-item view recycling process.
The ListView component doesn't generate view for each item in the list. So, there won't be 15 of them in your case. There will be just as many as can fit on the screen. When you scroll the list, the old items, which are no longer visible, are recycled. The getView is then called with convertView != null and the adapter is giving you an opportunity to update this recycled item view. This is done for performance reasons - just imagine an adapter having 10000 items (not a rare thing in commercial applications). Should it create all 10000 list item views? Imagine the performance you would have while scrolling such a list...
In your getView() code, you update an item view only partially - you always set item title in this line:
cih.getTvItemTitle().setText(ci.getDescItem());
When an fresh item view is created (i.e. the convertView == null) the radio group has a default selection, which may be fine in your case.
However, when the item view is recycled (i.e. the convertView != null), then you:
set a change listener in this line:
cih.getRgItemStatus().setOnCheckedChangeListener(...);
set item title:
cih.getTvItemTitle().setText(ci.getDescItem());
But you never set the checked radio group item. That means, it will have a value which was last set for this instance of item view - not for that position. You should store that information - probably in ContractItem, update it when the radio group item is selected and finally - retrieve it when convertView != null and set selected item of the radio group to the correct value.
You probably see this defect when you open up a dialog - the visible area of a ListView becomes smaller as the soft keyboard opens. This causes the ListView to remove unnecessary (technically: no longer visible) item views. When you hide the soft keyboard, the ListView area becomes larger again thus causing it to create missing item views. Unfortunately, you don't save and restore the last selected item of the radio group and so, after creation the newly visible items have the default item selected in the radio group.

Custom Single choice ListView

I want to make a custom List View having Two TextViews and a radio Button in a single row. And on listitem click the radio button state should be toggle. I cannot use Simple Adapter here.
I have already asked that question Single choice ListView custom Row Layout but don't find any satisfactory solution.
What I am currently doing is I am using simple_list_item_single_choice and putting data of both TextViews in a single one separated by some white spaces. But here it is getting worse (shown in the image below).
What I want is to fix the location of size and price and make list view as single choice.
XML Layout for the list can be something like:
**<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<TextView
android:id="#+id/tv_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="15sp"
android:width="200dp" />
<TextView
android:id="#+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="15sp"
android:width="70dp" />
<RadioButton
android:id="#+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>**
How to make custom adapter for that?
I had a similar situation but fixed that easily. Try this:
Extend ListActivity and set your custom list adapter
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //if you need title to be hidden
setContentView(R.layout.activity_add_to_cart_select_service_plan);
setListAdapter(adapter);
}
Create a field to store selected index position in adapter
int selectedIndex = -1;
Provide an interface to it
public void setSelectedIndex(int index){
selectedIndex = index;
}
Set the checked state to true or false based on the selected index inside getView()
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RadioButton rbSelect = (RadioButton) convertView
.findViewById(R.id.radio1);
if(selectedIndex == position){
rbSelect.setChecked(true);
}
else{
rbSelect.setChecked(false);
}
}
Set radio button focusable and clickable attribs to 'false'
<RadioButton
android:id="#+id/radio1"
android:checked="false"
android:focusable="false"
android:clickable="false"
/>
Set listview descendantFocusability attrib to 'beforeDescendants'
<ListView
android:id="#android:id/list"
android:choiceMode="singleChoice"
android:descendantFocusability="beforeDescendants"
/>
Override onListItemClick
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
adapter.setSelectedIndex(position);
adapter.notifyDataSetChanged();
}
That's it..run and check
I've been searching for an answer to this problem all morning, and the most useful thing I've found so far is this article.
While I haven't implemented the solution it suggests yet, it sounds like it's on the right track.
Basically, the single-choice ListView expects the widgets you provide it with to implement the Checkable interface. LinearLayout and others don't. So you need to create a custom layout that inherits LinearLayout (or whatever layout you want to use for your items) and implements the necessary interface.
Handled a similar issue with a Hack (Not a perfect solution..but still works..)
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < parent.getCount() ; i ++)
{
View v = parent.getChildAt(i);
RadioButton radio = (RadioButton) v.findViewById(R.id.radio);
radio.setChecked(false);
}
RadioButton radio = (RadioButton) view.findViewById(R.id.radio);
radio.setChecked(true);
}
});
Try setting the android:choiceMode attribute of the ListView
<ListView
...
android:choiceMode="singleChoice" />
**
<TextView
android:id="#+id/tv_size"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="15sp"
android:width="200dp" />
<TextView
android:id="#+id/tv_price"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="15sp"
android:width="70dp" />
<RadioButton
android:id="#+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
**

Android ListView with RadioButton in singleChoice mode and a custom row layout

I have a ListView, which is in single-choice mode. All I want is to display a RadioButton to the side, that when clicked highlights to say it is selected, and when a different one is clicked that one goes back to unselected and the new one becomes selected. Why is this so hard? This should not be this complicated. I've spent DAYS looking for an appropriate answer to this and I have found nothing, so I'm asking hopefully clearly and concisely.
My layout for the listview (R.layout.view_orders):
<?xml version="1.0" encoding="utf-8"?>
<ListView
android:choiceMode="singleChoice"
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#drawable/list_divider"
android:dividerHeight="1px"
android:focusable="false"
android:focusableInTouchMode="false"
android:cacheColorHint="#00000000">
</ListView>
My custom row (R.layout.orders_row):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res/com.xxx.xxxxxx"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="6dip">
<com.xxx.xxxxxx.VerticalLabelView
app:text="SHORT"
app:textColor="#666"
app:textSize="14sp"
android:id="#+id/state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />
<TextView
android:id="#+id/quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/state"
android:layout_centerVertical="true"
android:gravity="center"
android:textSize="40sp"
android:layout_margin="2dip"
android:minWidth="30dip"
android:textColor="#555" />
<RelativeLayout
android:layout_toRightOf="#id/quantity"
android:layout_centerVertical="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/instrument"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#333"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
/>
<TextView
android:id="#+id/deets"
android:layout_below="#id/instrument"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#888"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
/>
</RelativeLayout>
<RadioButton
android:id="#+id/selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
My onCreate() method:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.view_orders);
client = new Client(handler);
ola = new OrdersAdapter(this, R.layout.orders_row, Orders);
setListAdapter(ola);
final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading);
panel = (PositionsPanel) findViewById(R.id.panel);
Utility.showProgressBar(loading);
client.Connect("orders");
}
Now everything underlying works as expected, you click on a radiobutton, and through its tag, I can appropriately select that item from the list and manipulate it how I want. However, when the first radio button is clicked, the last one will be selected. Click that same radio button again, and it is now selected as well. Click it once more and nothing happens, both the last and the first are selected. Now I click any other one on the list, it gets selected like expected. Click any one of the selected radio buttons and nothing happens, the radio button remains selected.
I have tried using the following in onCreate():
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.view_orders);
client = new Client(handler);
ola = new OrdersAdapter(this, android.R.layout.simple_list_item_single_choice, Orders);
setListAdapter(ola);
final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading);
panel = (PositionsPanel) findViewById(R.id.panel);
Utility.showProgressBar(loading);
client.Connect("orders");
}
and that just shows no radio buttons at all. AWESOME.
Now maybe (read: most likely), I'm just dense and can't figure this out, but I've seen this question asked a lot with no real answer. Lots of references to other tutorials or the Commonsware guy's book. However, the comments are old now and his repository has changed so much, that those are no longer correct answers.
So, does anyone have any idea how to get the expected functionality out of this? Or failing that, just pass me along with the Gmail app's source code. :)
Do bear in mind that in the ListView row items are RECYCLED. This is likely to explain why actions on one row are affecting another. Dig around in Mark's book and you'll find coverage of this.
If you're using an adapter with the list, you can use getView() on an adapter to add a click handler to each row as it's created/recycled, and make sure the state is managed correctly as the row items are created and recycled.
My approach is to store the state in my own data structure, and then use getView() to mirror that in the UI as the user scrolls up and down the ListView. There may be a better solution, but that works for me.
Simple solution:
Add this line in the RadioButton layout of your xml file:
<RadioButton
...
android:onClick="onClickRadioButton"
...
/>
Then in the activity class that uses the ListView, add the following:
private RadioButton listRadioButton = null;
int listIndex = -1;
public void onClickRadioButton(View v) {
View vMain = ((View) v.getParent());
// getParent() must be added 'n' times,
// where 'n' is the number of RadioButtons' nested parents
// in your case is one.
// uncheck previous checked button.
if (listRadioButton != null) listRadioButton.setChecked(false);
// assign to the variable the new one
listRadioButton = (RadioButton) v;
// find if the new one is checked or not, and set "listIndex"
if (listRadioButton.isChecked()) {
listIndex = ((ViewGroup) vMain.getParent()).indexOfChild(vMain);
} else {
listRadioButton = null;
listIndex = -1;
}
}
With this simple code only one RadioButton is checked.
If you touch the one that is already checked, then it returns to the unchecked mode.
"listIndex" is tracking the checked item, -1 if none.
If you want to keep always one checked, then code in onClickRadioButton should be:
public void onClickRadioButton(View v) {
View vMain = ((View) v.getParent());
int newIndex = ((ViewGroup) vMain.getParent()).indexOfChild(vMain);
if (listIndex == newIndex) return;
if (listRadioButton != null) {
listRadioButton.setChecked(false);
}
listRadioButton = (RadioButton) v;
listIndex = newIndex;
}
My Name Is Gourab Singha. I solved This Issue. I have Written This Code to solve it. I hope this helps you all. Thanks. I require 3 hours for this.
public void add_option_to_list(View v){
LinearLayout ll = (LinearLayout)v.getParent();
LinearLayout ll_helper = null;
LinearLayout ll2 = (LinearLayout)ll.getParent();
LinearLayout ll3 = (LinearLayout)ll2.getParent();
ListView ll4 = (ListView)ll3.getParent();
//RadioButton rb1= (RadioButton)ll.getChildAt(1);
Toast.makeText(getApplicationContext(), ", "+ll4.getChildCount(), Toast.LENGTH_LONG).show();
//ll.findViewById(R.id.radio_option_button)
for(int k=0;k<ll4.getChildCount();k++){
ll3 = (LinearLayout)ll4.getChildAt(k);
ll2 = (LinearLayout)ll3.getChildAt(0);
ll_helper = (LinearLayout)ll2.getChildAt(0);
RadioButton rb1 = (RadioButton)ll_helper.getChildAt(1);
if(rb1.isChecked())
rb1.setChecked(false);
}
RadioButton rb1 = (RadioButton)ll.getChildAt(1);
rb1.setChecked(true);
//Toast.makeText(getApplicationContext(), ""+((TextView)ll.getChildAt(4)).getText().toString(), Toast.LENGTH_LONG).show();
}
The XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Category Name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<RadioButton
android:id="#+id/radio_option_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="add_option_to_list"
android:text="" />
<TextView
android:id="#+id/option_name"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="3dp"
android:layout_weight="5.35"
android:text="Category Name"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/option_price"
android:layout_width="76dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:gravity="right"
android:text="$0.00"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/option_unit_price"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:gravity="right"
android:text="$0.00"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
I've just had a similar problem. It seemed that it was related to views recycling. But I added Log's everywhere and noticed that the recycling handling was fine.
The problem was RadioButtons handling. I was using:
if(answer == DBAdapter.YES){
rbYes.setChecked(true);
rbNo.setChecked(false);
}
else if(answer == DBAdapter.NO){
rbYes.setChecked(false);
rbNo.setChecked(true);
}
else{
rbYes.setChecked(false);
rbNo.setChecked(false);
}
and the correct way of doing it is:
if(answer == DBAdapter.YES){
rbYes.setChecked(true);
}
else if(answer == DBAdapter.NO){
rbNo.setChecked(true);
}
else{
RadioGroup rg = (RadioGroup)(holder.answerView);
rg.clearCheck();
}
You can achieve much more simple, follow this. It was tried in MarshMallow
1)Have a CheckedTextView :
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:padding="10dp"
android:textAppearance="?android:attr/textAppearanceMedium">
ListChoiceIndicatorSingle will display RadioButton.
ListChoiceIndicatorMultiple will display CheckBox
Don't forgot to put choiceMode:Single in your ListView.
Inside the adapter
viewHolder.radioBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("called", "called");
if(position != mSelectedPosition && mSelectedRB != null){
mSelectedRB.setChecked(false);
}
mSelectedPosition = position;
mSelectedRB = (RadioButton)v;
}
});
viewHolder.radioBtn.setText(mList[position]);
if(mSelectedPosition != position){
viewHolder.radioBtn.setChecked(false);
}else{
viewHolder.radioBtn.setChecked(true);
if(mSelectedRB != null && viewHolder.radioBtn != mSelectedRB){
mSelectedRB = viewHolder.radioBtn;
}
}
add style to the radio button
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/tick" android:state_checked="true"/>
<item android:drawable="#drawable/untick" android:state_checked="false"/>
</selector>
and in the xml use the radio button style
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RadioButton
android:id="#+id/radioBtn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:button="#null"
android:checked="true"
android:drawablePadding="30dp"
android:drawableRight="#drawable/checkmark"
android:text="first" />
</RelativeLayout>
On your adapter:
public void setChecked(View v, int position) {
ViewGroup parent = ((ViewGroup) v.getParent()); // linear layout
for (int x = 0; x < parent.getChildCount() ; x++) {
View cv = parent.getChildAt(x);
((RadioButton)cv.findViewById(R.id.checkbox)).setChecked(false); // your checkbox/radiobtt id
}
RadioButton radio = (RadioButton)v.findViewById(R.id.checkbox);
radio.setChecked(true);
}
On your activity/fragment:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
((ModelNameAdapter)adapter).setChecked(view, position);
}
});

ListView with clickable/editable widget

Is it possible to use a OnItemClickListener on a ListView when the Items layout has a clickable/editable widget (RadioButton,EditText, or CheckBox)?
You might want to take a look at this issue. Having a focusable item in a row of a ListView causes the OnItemClickListener NOT to be invoked. However, that does not mean you cannot have focusable/clickable items in a row, there are some workarounds like this one.
Also, you can take a look at the Call Logs screen. It has a ListView with clickable item(the call icon on the right).
See Source code here
Quoting comment #31 in the link mentioned by Samuh (which solved the problem for me):
In fact you can add it to the layout XML (if inflated by one): android:descendantFocusability="blocksDescendants".
Adding here JIC that webpage is down in the future.
If any row item of list contains focusable or clickable view then OnItemClickListener won't work.
row item must be having param like android:descendantFocusability="blocksDescendants"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical" >
// your other widgets here
</LinearLayout>
Tried many complex solutions, but this was the simplest one that worked:
Just use android:focusable="false" as in:
<CheckBox
android:id="#+id/fav_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false" />
Two best solution
Add android:descendantFocusability="beforeDescendants" to listView
in xml OR
Set given two attributes to false
like
android:focusable="false"
android:focusableInTouchMode="false"
Then it will handle the listView row item child(Button,EditText etc) events instead of listView.setOnItemClick .
I fixed my problem different , in my item I have more than one LinearLayout
so if you give id to your linearayout and setOnclickListener in adapter class it will work, only original effect of touching will dissapear.
but this link Making a LinearLayout act like an Button is usefull to make linearlaout act like button on click
item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp">
<TextView
android:id="#+id/txt_item_followers_name"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center|start"
android:paddingLeft="15dp"
android:text="Ali"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/imageView"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/txt_item_followers_name"
android:layout_marginLeft="10dp"
android:src="#drawable/puan_icon" />
<TextView
android:id="#+id/txt_item_followers_mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView"
android:layout_toEndOf="#+id/imageView"
android:background="#color/red_400"
android:paddingLeft="10dp"
android:text="25.5"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:id="#+id/linear_one"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/txt_item_followers_name"
android:background="#color/red_400"
android:orientation="vertical">
<ImageView
android:id="#+id/btn_item_followers_2b_follow"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_marginLeft="10dp"
android:src="#drawable/follow_buton" />
</LinearLayout>
</RelativeLayout>
inside getView method
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.deneme, null);
final Followers2 myObj = myList.get(position);
LinearLayout linear_one = (LinearLayout) view.findViewById(R.id.linear_one); // HERE WE DOMUNÄ°CATE IT
linear_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(parentActivity, "One Two", Toast.LENGTH_SHORT).show();
}
});
TextView name = (TextView) view.findViewById(R.id.txt_item_followers_name);
TextView mark = (TextView) view.findViewById(R.id.txt_item_followers_mark);
final ImageView btn_follow = (ImageView) view.findViewById(R.id.btn_item_followers_2b_follow);
name.setText(myObj.getName());
mark.setText(myObj.getScore());
/* if (myObj.isFollow() == true) {
btn_follow.setImageResource(R.drawable.following_buton);
} else {
btn_follow.setImageResource(R.drawable.follow_buton);
}
btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Followers2 myObj = myList.get(position);
if (myObj.isFollow() == true) {
btn_follow.setImageResource(R.drawable.following_buton);
} else {
btn_follow.setImageResource(R.drawable.follow_buton);
}
}
});*/
return view;
}

Categories

Resources