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
Related
I am implemeting multiple selection on GridManager using RecyclerView.
Here is my code inside adapter
imgStamps.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//First setting up isSelected() or not
if (imageList.get(getAdapterPosition()).isSelected()) {
imageList.get(getAdapterPosition()).setSelected(false);
} else {
imageList.get(getAdapterPosition()).setSelected(true);
}
//Setting blur image on Imageview onLongclick and resting on again press.
if (imageList.get(getAdapterPosition()).isSelected()) {
mCount++;
imgBlurr.setVisibility(View.VISIBLE);
} else {
mCount--;
imgBlurr.setVisibility(View.GONE);
}
mCommunicator.clicked(mCount, getAdapterPosition());
return true;
}
});
The above code is inside ViewHolder not onBindViewHolder.
If I am selectimg first image and scrolls down and then up the view gets reset.
Can the mistake or behaviour can be pointed out?
RecyclerView reuses your layout. Put your logic on onBindViewHolder method.
For more information explore this question
How to properly highlight selected item on RecyclerView?
RecyclerView will reused your item view when you scroll. To manager multi select you must have an array of selected position (or selected model). And onBindViewHolder, check position in this array to check item selected or not. For more details implement, please refer to : Multi selection in RecyclerView?
I am trying to set one button to enabled and a different one to disabled once it is clicked on the listView. There are 2 buttons and I am trying to change them in the onClick in the getView function of my adapter.
Here is the onCLick of one of them.
holder.upButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Event", "Up");
View parentRow = (View) v.getParent();
ImageButton uButton = (ImageButton) parentRow.findViewById(R.id.upImageView);
ListView listView = (ListView) parentRow.getParent();
final int position = listView.getPositionForView(parentRow);
if (activity.equals("Host"))
{
} else {
}
uButton.setEnabled(false);
}
});
thank you
If you try to change the view inside an onClick() function, it will not work.
You didn't post a lot of code, so I will just describe the correct code.
First, your adapter needs to model the enabled state of the two buttons. In other words, for each list item you need two booleans, one for each button.
In your view binding method, you need to access the two booleans and set the enabled state of each button based on its model boolean value.
In your onClick(), you need to flip the state of the two booleans and call notifyDataSetChanged() to refresh the list with the new button states.
In my project i have a recyclerView which contains at most 20 items. In the row template i have a text view and a button which is hidden initially and on the recyclerview item click the visibility of the button is toogled. The problem is when the button in the first row is shown and if it is scrolled out of the view and then scrolled back the button is invisible again without calling toogle visibility.How can i save the sate of objects in recycler view when it is scrolled out of the view
Your RecyclerView list items get their state from the objects in the List/Array they are based on the objects used by to your adapter class.
If you want to save a checked state you can add a boolean field to your object class to set and hold the value so that when your adapter, update this on click and set the visibility of the button accordingly.
Instead of Using Strings in your ArrayList use a simple object class to hold the String and an additional boolean value for the state of the button visibility.
Such a class could look like this
class Items {
String myString;
boolean visibility;
public String getMyString(){
return myString;
}
public boolean isVisible(){
return visibility;
}
public void setVisibility(boolean visibility){
this.visibility = visibility;
}
}
In your RecyclerView you will have a method to set the value of the list items, I've never used it but I believe it is called bindView? Here where you set the text value of your list item also set the visibility according to the value returned by item.getVisibility() and set it when you call the onClick method of your button.
Hope this is helpful.
You can use shared preference for this purpose
onRecyclerViewItemClick insert key value in share preference where key should be position and value should be true/false
and in your adapter implement if condition where item view created like
if(sharedpreferences.contains(String.valueof(position)) && sharedpreferences.getString(String.valueof(position), "").equals("true")){
//button visible
}
else{
// button gone/invisible
}
Hope this would help you
used a hash map to store states. when the button is clicked the hashmap is updated with the position by calling getPosition() and the visibility
public void onClick(View v) {
Btn.setVisibility(Btn.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
statesMap.put(getPosition(),Btn.getVisibility() == View.VISIBLE );
}
and then read the values from the hash map in
onBindViewHolder(MyViewHolder holder, int position)
by passing the position
holder.Btn.setVisibility(statesMap.get(position) != null && statesMap.get(position) != false ? View.VISIBLE : View.GONE);
I have a ExpandableListView in my activity that works properly. I set in my adapter a clickListener on RelativeLayout, so when I click on it, my group get expanded. My group list is a ArrayList, my children is a HashMap> where Integer is groupPosition of ArrayList. Children is a comment list that any user can see. The user can add a comment by EditText at end of comment list. My goal is to position at top of screen the groupView clicked. I tried to do this but my problem is:
My first group has 10 comments. If i expand the first group I can see them and the position of my group clicked is right. If I try to expand my fourth group, when the first is already expanded, the ExpandableListView position on my screen goes to the fourth children of first group and not on fourth group just expanded. After if I scroll down the list the fourth group is open, but I would to position on the fourth group and not on fourth children of first group. All works properly if I open only group without comments...
small part of method getGroupView:
scanCommFav=(RelativeLayout)v.findViewById(R.id.feedcell_scancommentfavorite);
scanCommFav.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v)
{
if(!isExp)
{
if(mess==0)
{
setIdx(idx);
addIndex(idx);
getCommentNoList();
}
else
{
callCommentScript(snapId);
setIdx(idx);
addIndex(idx);
}
}
else if(isExp)
{
setIdx(idx);
removeIndex(idx);
closeGroup(idx);
}
}
});
addIndex(idx) and removeIndex, add and remove in LinkedList the position of groups open. setIdx(idx) set to int variable the group position that I use for different purpose.
this is openGroup():
private void openGroup(int pos)
{
feedlistView.setSelectedGroup(pos);
}
this is closeGroup():
private void closeGroup(int idx)
{
feedlistView.collapseGroup(idx);
}
this is my listener:
feedlistView.setOnItemSelectedListener(new OnItemSelectedListener(){
#Override
public void onItemSelected(AdapterView<?> arg0, View view,int position, long id) {
if(ExpandableListView.getPackedPositionForGroup(position)==ExpandableListView.PACKED_POSITION_TYPE_GROUP)
{
int pos = feedlistView.getSelectedItemPosition();
feedlistView.expandGroup(pos);
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
I tried also to implement setOnGroupClickListener but doesn't works. Somebody has any idea?
Thanks
I solved saving Instance State and restoring Istance State every time I set my customer adapter to my Expandable ListView in this way:
Parcelable state = myExpList.onSaveIstanceState();
myExpList.setAdapter(myAdapter);
myExpList.onRestoreIstanceState();
after in my method openGroup(int position)
myExpList.expandGroup(position);
myExpList.setSelectedGroup(position);
I didn't use setOnItemSelectedListener.
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.