I have a listview that contains a checkedtextview. My app moves from the top of the list view to the bottom. I want to check if the item is checked before calling an action. If it is not checked I want to move to the next item in the list.
E.g.
Item 1 - Checked
item 2 - Checked
Item 3 - Not Checked
Item 4 - Checked
So, I want the app to process as follows:
Item 1
Item 2
Item 4.
I am not sure how to access the checked status of the item from the listview position.
The logic that I want is as follows:
Is Current Item checked?
Yes:
Call action
No:
Move to next item.
Reloop to top of void.
I will need something in there to stop an infinite loop.
1.) First create an array, what indicates the items checked state in your adapter
(assuming you extend the BaseAdapter class for this purpose):
private boolean [] itemsChecked = new boolean [getCount()];
2.) Then create an OnCheckedChangeListener:
private OnCheckedChangeListener listener = new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton button, boolean checked)
{
Integer index = (Integer)button.getTag();
itemsChecked[index] = checked;
}
}
3.) In your adapters getView() method:
public View getView(int index, View view, ViewGroup parent)
{
/*...*/
CheckBox checkBox = /*get the checkbox*/;
checkbox.setTag(index);
checkBox.setOnCheckedChangeListener(listener);
/*...*/
}
4.) In the onClick() method:
public void onClick(View view)
{
//just get the boolean array somehow
boolean [] itemsChecked = adapter.getItemsCheckedArray();
for(int i=0; i<itemsChecked.length; i++)
{
if(itemsChecked[i])
{
//the i th item was checked
}
else
{
//it isnt checked
}
}
}
One solution will be to use an ArrayList of positions.
When the user check/uncheck a checkbox, add/remove accordingly the position in your ArrayList.
Then when the user is over, just iterate through the list to know which position have been selected.
Related
if (RFidList.size() >0){
for (String s: RFidList){
RFidTagValueList.remove(s);
}
}
mTimeAdapter.notifyDataSetChanged();
dialog.dismiss();
when choose multiple items in recyclerview checkbox not working / and am use private ArrayList<String> data = new ArrayList<>();
You can't move and delete from the list. The best option to do this is to have an array that will remember the state of the checkbox. Scrolling through your recycler view will always change the state of the checkbox and maybe won't remember it. The way to do this is to add an array of boolean
private boolean[] checkStates;
then inside your constructor of the adapter do this.
checkStates = new boolean[data.size()];
This way you'll create an array of boolean filled with FALSE value the same size your data array is. Now, inside your adapter when you are binding your view do this for the checkbox.
holder.checkbox.setChecked(checkStates[position]);
Also, don't use onCheckedChangeListener on checkbox inside adapter. This will be called even when you scroll and it will change whatever you are doing inside the function. What you can do is override onClick for the checkbox, but there is something tricky here. When you click the checkbox to check it, inside the onClick method the view will have the state as it is already checked so to follow this do it like this:
holder.checkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Checkbox c = (CheckBox) v;
checkStates[position] = c.isChecked();
}
});
I wrote this from my head and maybe there are some mistakes but you'll get the point. The animation of the check state will be handled you just need to handle changes inside the checkStates array.
Now your checkbox will always have the state it had before. After this, you can create a function to delete items from your data.
public void removeItems() {
ArrayList<YOUR-MODEL> items_to_delete = new ArrayList<>();
for (int i = 0; i < checkStates.length(); ++i) {
if (checkStates[i]) items_to_delete.add(data.get(i]);
}
data.removeAll(items_to_delete);
notifyDataSetChanged();
checkStates = new boolean[data.size()];
}
This works if your data is a type of ArrayList. I think this is the best way to go.
I have a horizontal recyclerview having radio button as recyclerview item. I have to select all other radio button as false without currently selected radio button. So I have done -
View.OnClickListener rbClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
RadioButton checked_rb = (RadioButton) v;
if (lastCheckedRB != null && lastCheckedRB != checked_rb) {
lastCheckedRB.setChecked(false);
}
lastCheckedRB = checked_rb;
}
};
mainHolder.radioBtnTrip.setOnClickListener(rbClick);
Its working fine when i have 4 to 5 items. But when it has more than 5 items then always multiple radio button is selected as true because of view recycle. Given photo indicate that first item is selected but also 10th radio button is selected when I scroll.
How to resolve the row item position issue. I must have to select only one radio button at a time and select all other radio button of recyclerview as false.
Override the method getItemViewType to format the viewholder in many different way based on the value ( or whatever ) of the view
#Override
public int getItemViewType(int position) {
// example
return 0;
}
then, in your onBindViewHolder method
#Override
public void onBindViewHolder(Adapter.ViewHolder viewHolder, int position) {
if( this.getItemViewType(position)==1){
// layout #1
}else{
// layout #2
}
}
Understand the way recyclerview or listview works
You have to store the checked status somewhere to update when the bindview is called , where you can set the checked status to true.
Listview or RecyclerView will reuse view from any index on scrolling.
Same view that you have selected before cannot be expected on the same index when your scrolling back.
A simple way to do this is to create a property in the respective model and then inside onBindViewHolder() set the radio buttons checked property according to the model
I have a ListView with a set of elements. When I click one of the I would like to disable all the others. If I click again on the selected item all the other items are enabled again.
I tried the different proposed solution without success. I hope someone can help me.
This is my code:
//action to take when a presentation is selected
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
//disable the other items when one is selected
if(position!=selectedPresentation){
for(int i=0;i<parent.getCount();i++){
if(i!=position)//disable all the items except the select one
parent.getChildAt(i).setEnabled(false);
}
selectedPresentation=position;
}else if(selectedPresentation==position){
//enable again all the items
for(int i=0;i<parent.getCount();i++){
parent.getChildAt(i).setEnabled(true);
}
selectedPresentation=-1;
}
Where selectedPresentation is a global variable storing the selected item. If no item is selected its value is -1.
Thank you for your help!
Make your own subclass of ArrayAdapter that has AreAllItemsEnabled() return false, and define isEnabled(int position) to return false for a given item in your the ones you want to disable.
In your custom ArrayAdapter overide isEnabled method as following
#Override
public boolean isEnabled(int position) {
return false;
}
other option
Don't implement onItemclickListener. This will not give you any update of item click. Only register onClick listener to views.
You may take another object of the List(Arraylist) which is populating elements in listview then on click copy the corresponding position data to new arraylist you made and then notifyDataSet and when you click again you populate listview with original list so it will apear again....Just do this trick it might work for you
parent.getChildeAt() only work for visible Item.
you should change something in adapter.
if make custom adapter then you can do some thing like #ṁᾶƔƏň ツ answer, but if you use default adapter you can change adapter's arraylist that before you pass it to adapter.
put boolean in it (in arraylist) and in on item click true/false it for all item.
I wrote this solution and seems it works fine!
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
//disable the other items when one is selected
Toast.makeText(context, "onClick called",Toast.LENGTH_SHORT).show(); // this will flash up twice
if(position!=selectedPresentation){
selectedPresentation=position;
for(int i=0;i<adapter.getCount();i++){
if(i!=position)//disable all the items except the select one
adapter.isEnabled(i);
}
}else if(selectedPresentation==position){
//enable again all the items
selectedPresentation=-1;
for(int i=0;i<adapter.getCount();i++){
adapter.isEnabled(i);
}
}
And in my adapter I wrote:
public boolean isEnabled(int position) {
if(selectedPresentation==-1 || selectedPresentation==position)
return true;
return false;
Now my concern is how to show the items in the listView as disabled
I have implemented custom list view with two rows (name and number) and it is checkable.
The list view has multiple select option.
Whenever user searches for a name, cursor will returned the new list of items. I can't keep track for items which has been selected earlier once adapter gets changed with the new cursor items.
For example user searches for name "Jo" it returns 10 items, in which i have selected 2 rows. Once i remove the search, the cursor and adapter gets changed. I am not able to mark the items checked.
I want to override default checkable items based on position( have to write own which has to make items checkable based on _id(contact id))
( I tried overriding onFinishInflate method. But it didn't help).
Any help appreciated.
Thanks in advance.
what you need is an object to have your check-box data persist your adapter and listview. A hashmap of boolean arrays should suffice.
private HashMap<String, boolean[]> contactMap;
I'd imagine that you could load this in some database method or something and you could have the person's name, like "Jo", as an identifier if need be. the array indexes would correspond to the checkboxes in each listview row as they appear. Then in your adapter which i'd imagine is a CursorAdapter, you could have the following:
private boolean[] contactObj;
public void setContactObj(boolean[] contactObj) {
this.contactObj = contactObj;
notifyDataSetChanged();
}
public boolean[] getContactObj() {
return contactObj;
}
#Override
public void bindView(View view, Context context, Cursor c) {
final int position = c.getPosition();
final CheckBox cb = (CheckBox) view.findViewById(R.id.checkbox);
cb.setChecked(contactObj[position]);
cb.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (cb.isChecked()) {
contactObj[position] = true;
} else {
contactObj[position] = false ;
}
}
});
}
Basically, you have an adapter that only has capacity for one boolean[] which is able to adjust the checkboxes in your listview, modify as the boolean[] as the checkbox is being clicked and then return it in the event that you still need it.
What I have: I have a ListView with custom rows, having a CheckBox & two TextViews in each row. I have a button for "Select All".
What i want: I want that when I click the button, all the CheckBox in ListView get checked/unchecked.
What is the problem: In OnClick of the "Select All" button. i am doing this:
public void OnClickSelectAllButton(View view)
{
ListView l = getListView();
int count = l.getCount();
for(int i=0; i<count; ++i)
{
ViewGroup row = (ViewGroup)l.getChildAt(i);
CheckBox check = (CheckBox) row.findViewById(R.id.checkBoxID);
check.setChecked(true); // true for select all and false for unselect all etc..
}
}
Here l.getChildAt(i) is giving me the visible items only. And when the index goes out of visible items, the problem occurs. I want to check all the CheckBox in List, not just the visible ones.
It will occur, because ListView adapter reuses views. The way you are trying to do is incorrect. I don't think you ever should access listview rows through listview children.
Introduce a variable in your activity, that will hold the current state (boolean checkAll). When the user presses the button, it must set "checkAll" to true, and call notifyDataSetChanged() (for arrayadapter), or requery() (for cursoradapter) on your ListView's adapter. In adapter's getView() method introduce a check for this flag, so if (checkAll) {check the check box}
have you looked this Correct way to check all checkboxes in ListView?
int count = getListAdapter().getCount();
I think you should run this long-running task off the UI thread.
When you click button in OnClickListener:
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < list.getAdapter().getCount(); i++) {
final int position = i;
mHandler.post(new Runnable() {
#Override
public void run() {
list.setItemChecked(pos, true);
}
});
}
}
}).start();
and in onCreate() :
this.mHandler = new Handler();
Each item in list view should be Checkable like CheckableRelativeLayout that implements Checkable interface.