Keep listview item selected even if view changes - android

I have a listview in fragment.
When I select a listview item, it gets highlighted and then I open another fragment.
Now, what I want is, when I move back to previous fragment, the list item should stay selected.
How can I do that?

I have implemented like
add this two methods in your Adapter
private int selectedIndex = ListView.NO_ID;
public int getSelectedIndex() {
return selectedIndex;
}
public void setSelectedIndex(int index) {
this.selectedIndex = index;
// Re-draw the list by informing the view of the changes
notifyDataSetChanged();
}
and in your Adapter getView(...) do
// Highlight the selected item in the list
if (selectedIndex != -1 && selectedIndex == position) {
YourView.setBackgroundResource(R.color.lightred);
}
and implement in Fragment in setOnItemClickListener onItemClick(...) like
adapter.setSelectedIndex(position);
save this selected value in some preferences and when you come back again call in Fragment on resume(...)
adapter.setSelectedIndex(selectedIndex);

OK let's do this
declare one field in your adapter say
private int selectedPosition=-1;
now create a setter for this
private void setSelectedPosition(int position)
{
selectedPosition=position;
}
Now in your getView method
if(position==selectedPosition)
{
listItemView.setSelected(true);
//OR
listItemView.setBackgroundColor(<Some Color>);
}
Now after setting the adapter when user tap and your OnItmeSelected called
adapter.setSelectedPosition(<your desired selected item position>);
adapter.notifyDataSetChanged();

Related

Disable click on ListView Row with condition

Good morning,
I have a ListView in a first activity (main_activity), when I click on a selected item, I have a new activity (details_activity) that opens with more informations and details, and the user had to check it, then the (details_activity) is closed and back to the main_activity with the same list.
I want to disable the click on listView's rows that are already checked by the user.
I tried to get the position from main_activity to details_activity to use it in SQL to get the informations, it's working.
Then I sent it back, in the main_activity I used this code:
mPrr = getSharedPreferences("reponse",Context.MODE_PRIVATE);
int IDs = mPrr.getInt("ID",-1);
String rep =mPrr.getString("reponse","");
if(IDs != -1) {
lst.getChildAt(IDs).setFocusable(false);
}
Is there any help please?
Create a ArrayList in adapter than whenever perform click on that row check that row position if position not in list than add position to the array list and perform click else nothing to do.
private ArrayList<String> positionClicked = new ArrayList<>();
public void onBindViewHolder(final MyViewHolder holder, final int position) {
if (!positionClicked.contains(String.valueOf(position))) {
positionClicked.add(String.valueOf(position));
//perform Click
}else {
//
}
}
Write setClickable(false) instead of setFocusable(false);
Create custom ArrayAdapter, find the position of item you want to disable click and #Overide isEnabled method
#Override
public boolean isEnabled(int position) {
if(position == positionYouWannaDisableClick)
return false;
return true;
}

Add selected position in RecyclerView to a set and highlight those position

I have a recyclerView and have implemented onLongClick listener on the items. The Adapter is in the same class as the Activity.
I created a set: public Set<Integer> multiplePositions as instance variable of the Activity class and am initialising it in onCreate() method as multiplePositions = new TreeSet<>().Coming to my Adapter class in the onBindViewHolder method I created a click listener as follows:
holder.textCardView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Adapter.this.onLongClick(holder, position);
return true;
}
});
holder.textCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
As you can see I am calling the method onLongClick. My onLongClick method looks like this:
public void onLongClick(ViewHolder holder, int position) {
multiplePositions.add(position);
for(Integer i : multiplePositions) {
Log.e("set", ""+i);
}
holder.textCardView.setBackgroundResource(R.color.long_press);
}
Here, whenever an item clicked I am adding the position in the Set but I don't know how do I iterate through this set and set the background color of all the item at the positions in the set.
I am aware that this can be achieved by creating a boolean variable isSelected in the model class but if I go with this method then other functionalities of my code won't work.
My main concern is if I scroll the recyclerView up or down then color of the selected positions should not disappear. The unselection part will be done in setOnClickListener().
Use SparseBoolean array to store the positions of the items clicked in the reyclerview.Check the answer in this link
https://stackoverflow.com/questions/46336645/hilighted-selected-items-colour-changes-when-not-in-view-in-recyclerview/46336844#46336844
Check here the purpose of using SparseBoolean array
https://stackoverflow.com/questions/18822708/what-is-the-clear-purpose-of-sparsebooleanarray-i-referred-official-android
EDIT:
Use SparseBooleanArray to keep track of selected items in recycler view adapter
Initialize the SparseBooleanArray as private memeber variable
private SparseBooleanArray mClickedItems=new SparseBooleanArray();
Inside your click function while clicking textCardView make the item position as true.
holder.textCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mClickedItems.put(position,true);
notifyDataSetChanged();
}
});
Then in the onBindViewHolder check if the position is already selected or not like this
if(mClickedItems.get(position)==true){
//Show selected color
holder.textCardView.setBackgroundResource(ContextCompat.getColor(holder.textCardView.getContext(),R.drawable.selected));
}else {
//show unselected color
holder.textCardView.setBackgroundResource(ContextCompat.getColor(holder.textCardView.getContext(),R.drawable.unselected));
}

How to reset recyclerView position item views to original state after refreshing adapter

I have a RecyclerView with rows that have views that when clicked will be disabled for that row position.
The problem is after I update the adapter like this:
adapterData.clear();
adapterData.addAll(refreshedAdapterData);
notifyDataSetChanged();
After refreshing the data, the disabled views at the previous recycler position still remain disabled even though the data is refreshed.
How can I reset the views to the original state after refreshing adapter data.
Use below code.
adapterData.clear();
adapterData.addAll(refreshedAdapterData);
adapter.notifyDataSetChanged();
OR
recyclerView.invalidate();
When you call notifyDataSetChanged(), the onBindViewHolder() method of every view is called. So you could add something like this in the onBindViewHolder() of your Adapter method:
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
if (refreshedAdapterData.get(position).isInDefaultState()) {
//set Default View Values
} else {
//the code you already have
}
}
I have resolved this by putting a conditional statement inside onBindViewHolder method instructing all positions to reset the disabled views if data meets the required conditions for a refreshed data.
#Christoph Mayr, thanks for your comments. It helped point me in the right direction.
I cleared the data then notify change but the selected checkbox doesn't reset but just moves up one position. Let say I selected item #1 , move out of the RecyclerView, came back and it will auto select item #0.
So, I created new adapter again at onResume(), i worked for me but i don't know if it's the right way to handle this situation.
#Override
public void onResume() {
super.onResume();
if(selectedItems != null && selectedItems.size() > 0){
selectedItems.clear(); // if no selected items before then no need to reset anything
if(adapter != null && recyclerView != null){
// to remove the checked box
adapter = null;
adapter = new MyAdapter(items, new MyAdapter.MyAdapterListener() {
#Override
public void onSelected(int pos) {
selectedItems.add(items.get(pos));
}
#Override
public void onUnSelected(int pos) {
selectedItems.remove(items.get(pos));
}
});
recyclerView.setAdapter(adapter);
}
}
}

Android RecyclerView select first Item

I'm using a RecyclerView to implement a NavigationDrawer.
I got click events working, but I can't figure out how to have the first item selected on App start and following that keep the selected item higlighted even if the drawer is not shown.
All I've been able to find is multi-selection in RecyclerView.
I actually just implemented this in an app I am working on. So this method worked:
First create a variable to track the current selected position at the top of your adapter:
private int selectedItem;
Then in your Adapter constructor initiate the selectedItem value you would like:
public NavDrawerMenuListAdapter(Context context, List<NavDrawerItem> data, NavDrawerMenuListViewHolder.NavDrawerMenuClickInterface listener) {
this.context = context;
mLayoutInflater = LayoutInflater.from(context);
this.navDrawerItems = data;
this.listener = listener;
selectedItem = 0;
}
Here I use 0 as this is the first item in my menu.
Then in your onBindViewHolder(NavDrawerMenuListViewHolder holder, int position) just check whether your selectedItem == position and set the background of some view to a seleted background like so:
if (selectedItem == position) {
holder.single_title_textview.setTextColor(0xff86872b);
holder.nav_drawer_item_holder.setBackgroundColor(Color.DKGRAY);
}
Here I set the text color to green and give the Realativelayout parent a gray background on start. You can, of course, customize this in any way you like.
To implement a selection of an item and keep the state I use the following method:
public void selectTaskListItem(int pos) {
int previousItem = selectedItem;
selectedItem = pos;
notifyItemChanged(previousItem);
notifyItemChanged(pos);
}
This method I usually call from the OnClick() method.
Hope this helps!.

ListView.getChildAt(validPosition) returns null

When user clicks on item of ListView I show Edit button at this item of list. lastSelectedPosition has the position of the list item that was clicked last.
code:
public class MainActivity extends Activity {
private ListView listView;
private MyAdapter adapter;
// static - If the activity is re-created, the data
// about list items remain.
private static List<String> items = loadItems();
private MyItemClickListener listener = new MyItemClickListener();
private int lastSelectedPosition = ListView.INVALID_POSITION;
#Override
protected void onCreate(Bundle savedInstanceState) {
listView = (ListView) findViewById(R.id.myListView);
adapter = new MyAdapter(R.layout.my_item, items);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setOnItemClickListener(listener);
if (savedInstanceState != null) {
// Is recreating the activity because
// of the change screen orientation.
lastSelectedPosition = savedInstanceState.getInt("lastSelectedPos");
if (lastSelectedPosition != ListView.INVALID_POSITION) {
// !!! getChildAt() always returns null !!!
View listItem = listView.getChildAt(lastSelectedPosition);
View editButton = listItem.findViewById(R.id.editButton);
// Only selected list item has visible EditButton,
// other list items have not
editButton.setVisibility(View.VISIBLE);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// Is destroying the activity because
// of the change screen orientation.
outState.putInt("lastSelectedPos", lastSelectedPosition);
}
// Other methods
}
I think that getChildAt() always returns null in Activity.onCreate(), because at that moment the list is not yet fully developed. How I can get View of list item to show Edit button on it?
And sorry for my English.
Thanks
Your adapter needs to know about this selected position so it can be rendered properly in getView(). Just modify the constructor for your adapter to take the int, and update that int value whenever the onclick is called. In general, you should always have all the information you need to recreate the state of your list items within your adapter.
I think it is because you didn't change your lastSelectedPosition's value when user click on item in your listview. Just implement your onItemClickListener like the following code snippet. And change your lastSelectedPosition's value on this. And remove your
private MyItemClickListener listener = new MyItemClickListener();
line.
I think the value of lastSelectedPosition is couldn't changed until you define your listener variable. And also I didn't know where you define your listener variable.
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
lastSelectedPosition = arg2
}
});
I hope this will help you.

Categories

Resources