Listview multiple choice - android

I use a listview with multiple choice and I override the search method inside. I have a problem with the items in that during scrolling the position of items changed. The problem comes from the layout, I think, because when the layout includes only the listview, it works correctly. But, when I use the layout below, the positions of the items checked during scrolling get changed.
Can anyone help with that please?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/button1" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="Button" />
<ListView
android:id="#+id/MyListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/editText1" />
</RelativeLayout>

You need to set up an object in your adapter to keep track of the state of the checkboxes. You haven't shown your adapter code so I'll just pull an example from some of my code (this is using a cursor, it can be adapted to an ArrayAdapter)
In the custom adapter set an array:
private Cursor c;
public static int[] checked;
In your constructor set your cursor to the local var and call a method:
CursorAdapter_EditText.c = c;
initializeChecked();
The method (using 0 = not checked):
public static void initializeChecked() {
checked = new int[c.getCount()];
int i = 0;
while (i < c.getCount()) {
checked[i] = 0;
i++;
}
}
In your getView use the array to set the checkbox state:
checkBox = (CheckBox) view.findViewById(R.id.CheckBox);
if (checked(position) == 0) {
checkBox.setChecked(false);
} else {
checkBox.setChecked(true);
}
You'll need to add code in checkBox.setOnCheckedChangeListener also to change the state in the array when you change the state of the checkbox.

Related

Sorting a Recyclerview list dynamically

I have a recyclerview list that is a check list. I want it to be sorted based on date and if the checkbox is checked or not. So if the user is on the main screen he/she should see a sorted list based on date and if he/she clicks a checkbox, I want that item to go the bottom of the list.
I wrote a compareTo method in the model class:
public int compareTo(BucketItem o) {
if (this.isChecked && !o.isChecked){
return -1;
}else if(!this.isChecked && o.isChecked){
return 1;
}else if (this.isChecked && o.isChecked){
return 0;
}else{
return getDate().compareTo(o.getDate());
}
}
The layout looks for one item looks like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:weightSum="1">
<!--<TextView-->
<!--android:id="#+id/contact_name"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_weight="1"-->
<!--/>-->
<RelativeLayout
android:layout_height="52dp"
android:layout_width="wrap_content"
android:id="#+id/RelativeLayout1"
android:orientation="vertical"
android:layout_marginBottom="16dp"
android:layout_weight="0.95">
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_centerVertical="true"
android:clickable="true"
android:onClick="itemClicked"
/>
<TextView
android:id="#+id/bucket_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/checkBox1"
android:layout_centerVertical="true"
android:text="TextView"
android:clickable="true"
android:onClick="editItem"/>
<TextView
android:text="TextView"
android:id="#+id/bucket_des"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="#+id/bucket_name"
android:layout_toEndOf="#+id/checkBox1" />
</RelativeLayout>
</LinearLayout>
My main question is where do I put the Collections.sort(list) so that it gets called every time a new item gets added to the list or a checkbox gets checked?
Create a method in your Adapter class and put Collections.sort(list) followed by notifyDataSetChanged in that class.
void update(){
Collections.sort(list);
notifyDataSetChanged();
}
Now call this method whenever any new item is added or checkbox is checked/un-checked.
CheckBox checkBox1;
checkBox1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
adapter.update();
}
});
I think you don't need to think about sorting the recycler view, instead you should sort the dataset with your required event and notify the recycler view by calling yourAdapter.notifyDataSetChanged()

ListView Delete Icon

I am trying to fire a event when a user click the delete icon in the list , But I could not able to do it.I am using a simple cursor adapter with setviewbinder to display items in the list.In the setviewBinder method I set the textview layout clicklistener to be null that's why, view is not clicked when a user click in the textview.When a user is swipe in the list immediately delete icon is appeared.I need to fire a click event in the deleteIcon.Currently, when a user is clicked the delete icon, the whole view is clickable.I need to achieve when a user is clicked the delete icon, need to fired the event, only in the delete icon.
public boolean setViewValue(final View view, final Cursor data, int columnIndex) {
LinearLayout layoutTaskView=(LinearLayout)view.findViewById(R.id.layoutTaskView),
layoutTaskDelete = (LinearLayout) view.findViewById(R.id.LayoutDeleteTask);
boolean crossed = Boolean.valueOf(data.getString(columnIndex));
if(crossed){
icon.setImageState(new int[] { android.R.attr.state_checked }, true);
text1.setPaintFlags(text1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
text2.setPaintFlags(text2.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
layoutTaskView.setOnClickListener(null);
}
}
Layout Xml File
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/layoutTaskView"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:padding="15dp" >
<TextView
android:id="#+id/taskTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/taskName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:paddingLeft="10dp"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/LayoutDeleteTask"
android:clickable="false">
<ImageView
android:id="#android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:padding="15dp"
android:src="#drawable/checkmark" />
</LinearLayout>
</LinearLayout>
ListView xml
<com.myexample.CrossView
android:id="#+id/crossview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</com.myexample.CrossView>
Adapter Code
String[] from = new String []
{
DatabaseHelper.COLUMN_CATEGORY,DatabaseHelper.COLUMN_TASKNAME,
DatabaseHelper.COLUMN_CROSSED};
int[] to = new int[] {R.id.taskTime,R.id.taskName, android.R.id.content};
adapter = new SimpleCursorAdapter(context, R.layout.layout_list_item, data, from, to, 0);
adapter.setViewBinder(new CrossBinder());
lv.setAdapter(adapter);
public void onItemClick(AdapterView<?> parent, View v, final int position, final long id) {
ImageView icon = (ImageView)v.findViewById(android.R.id.icon);
icon.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(v.getId() == android.R.id.icon){
}
}
}
You need to use android:descendantFocusability = "afterDescendants" parameter to root layout of list item. In your case, the root LinearLayout.
For more information check this link.
EDIT : remove android:clickable="false" from your LinearLayout containing ImageView. Put android:clickable="true" in ImageView. Moreover, you can use ImageButton instead ImageView.
P.S. I have suggested to use android:descendantFocusability in main parent LinearLayout.
Create custom adapter like that answer Custom adapter for a list of items that have multiple child items?
This answer give tutorial link to create custom dapters for listview.

Creating a multi selectable custom ListView

I am trying to modify my ListView so that it:
Contains an image
Contains a text description (fileName)
Contains a check box.
The list should be multi selectable. And I should be able to loop through all the checked checkboxes and get the description.
Currently, I can display an ordinary ListView with check boxes.
ArrayAdapter<String> ad = new ArrayAdapter<String>(HelloDropboxActivity.this, android.R.layout.simple_list_item_multiple_choice,fileName);
mTestListOutput.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mTestListOutput.setAdapter(ad);
Using the onClick of a Button - I can loop through the checked boxes and get the text into an ArrayList like this:
ArrayList<String> dbLinks = new ArrayList<String>();
int cntChoice = mTestListOutput.getCount();
SparseBooleanArray sparseBooleanArray = mTestListOutput.getCheckedItemPositions();
for(int i = 0; i < cntChoice; i++)
{
if(sparseBooleanArray.get(i) == true)
{
dbLinks.add(mTestListOutput.getItemAtPosition(i).toString());
}
}
I am retreving an ArrayList of :
private ArrayList paths;
So how can I tie these together to create a custom ListView?
I have looked at many examples and tried to modify them but I am getting nowhere.
Here I have attampted to create the Layout of a list row in my list_row.xnl:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<!-- Thumbnail image -->
<LinearLayout android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip">
<ImageView
android:id="#+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip"
/>
</LinearLayout>
<!-- File Name -->
<TextView
android:id="#+id/filename"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/title"
android:textColor="#343434"
android:textSize="10dip"
android:layout_marginTop="1dip"
android:layout_toRightOf="#+id/thumbnail"
android:text="Just gona stand there and ..." />
</RelativeLayout>
I think the problem that are having is that when the listitem is selected, it is actually being selected but you can't see any difference because the root view must implement 'Checkable'. There is way to make this work although its more complicated that I think it should be.
First of all, you need to add a the following class. This is a checkable LinearLayout that should relay the calls from the checkable interface through to the checkbox within it. It should be easy to modify this for whatever view group you want to use.
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private CheckBox _checkbox;
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
// find checked text view
int childCount = getChildCount();
for (int i = 0; i < childCount; ++i) {
View v = getChildAt(i);
if (v instanceof CheckBox) {
_checkbox = (CheckBox) v;
}
}
}
public boolean isChecked() {
return _checkbox != null ? _checkbox.isChecked() : false;
}
public void setChecked(boolean checked) {
if (_checkbox != null) {
_checkbox.setChecked(checked);
}
}
public void toggle() {
if (_checkbox != null) {
_checkbox.toggle();
}
}
}
Next define the layout of that you want to use for each item, using the CheckableLinearLayout above:
<com.myPackage.CheckableLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<CheckBox
android:id="#+id/checkBox1"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox" />
<TextView
android:id="#+id/textView1"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<ImageView
android:id="#+id/imageView1"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/background_iv" />
</com.myPackage.CheckableLinearLayout>
Then, alter the line that creates the Adapter so that the ID of the layout above is used instead.

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);
}
});

Categories

Resources