Focus lost on refresh in recyclerview - android

guys I am developing android TV app so I used recyclerview horizontally and vertically and I used a method to refresh adapter of vertical recyclerview by using adapter.notifyDataSetChanged() but I am getting one problem.
1. It's focus is being gone and on press any D-pad key it is not working only right key is working
2. I used adapter.notifyItemRangeChanged(0, categoryDataList.size()) but I have still one problem that it's focus is going on first element of layout otherwise last of layout.
So Please help me as soon as possible.
Thanks in advance.

Of course item will lose focus. Because no view to get focus when you refresh RecyclerView by calling method notify*Changed.
There is an imperfect way to keep focus in RecyclerView when you call notifyDatasetChanged().
Override method getItemId(), give a stable id to each item:
#Override public long getItemId(int position) { return position; }
Set has StableId:
adapter.setHasStableIds(true);
Now basically you can keep focus in a concrete item when call notifyDatasetChange, if not, disable animator:
mRecyclerView.setItemAnimator(null);
about stable id:Android: How to make an adapter with stable ids?
about disable animator:How to implement ItemAnimator of RecyclerView to disable the animation of notifyItemChanged
about the reason of step3 in google code:
https://code.google.com/p/android/issues/detail?id=204277
Good luck!

Use
notifyItemRangeInserted(position,size);
if you are inserting items.

Related

Accessibility focus lost while deleting items in recyclerview android

I am new to accessibility workarounds in android, please help me fix the issue with losing focus while deleting any item from recycler view. I used the code below for this, but it doesn't seem to be working.
Override method getItemId(), give a stable id to each item:
#Override
public long getItemId(int position) {
return position;
}
Set has StableId:
adapter.setHasStableIds(true);
Now basically you can keep focus in a concrete item when call notifyDatasetChange, if not, disable animator:
mRecyclerView.setItemAnimator(null);
from here
But it's not working. I just need the way around how we can keep the focus after deleting the item from recycler view. Thanks.

How to know if RecyclerView item is partially visible or completely visible when user click on it?

I need to enable click listener on RecyclerView item only if it is completely visible otherwise click listener should not work. Is there any way to detect whether an adapter item is completely visible or not when user click on it?
What you are looking for can be found here
You could make some logic using LayoutManager api to get last completely visible item position in RecyclerView onScrolled method:
((LinearLayoutManager) vYourRecycler.getLayoutManager()).findLastCompletelyVisibleItemPosition();
From the documentation: Returns the adapter position of the last fully visible view. This position does not include adapter changes that were dispatched after the last layout pass.

Prevent swipe to delete recyclerview item

I want to catch a vertical swipe in an horizontal RecyclerView. Each item is simply a CircleImageView.
I found many resources on internet (like Drag and swipe with RecyclerView, Android - Swipe to delete RecyclerView) but those solutions ends deleting the item. I don't know if the term swipe requires also that the item is deleted or not.
What I want to achieve is to catch the swipe action on an item in the RecyclerView, but without delete the item itself from the RecyclerView.
I think that a good idea is to override the method onChildDraw() like suggested here: How to detect if Recyclerview item is being swiped?, but I can't understand how to achieve the behaviour I want.
My idea is: while the user swipes an item, the item itself moves in that direction; when the user end the touch event, the item has to come back to the original position (maybe changing the background color).
EDIT 1:
How to have swipe to delete and swipe to archive in two colours in Recyclerview Android probably can help, but it doesn't achieve the behaviour that I need. The item has to come back to the original position.
Your RecyclerView has RecyclerView.Adapter attached to it. The adapter determines what information that the RecyclerView can see and display. So, if item number 10, out of a 100-item backing array (managed by you) is swiped, the adapter can report that the array now contains 99 items and not ever present the swiped item to the RecyclerView. That way the item appears to be deleted but is maintained internally and still accessible programmatically. How you manage that internal state is up to you and dependent upon your implementation.
If, however you want to not remove the item from the screen but just change its appearance, I think that you would need to look at the method onItemDismiss that actually removes the item and notifies the adapter of the data change.
public void onItemDismiss(int position) {
mItems.remove(position);
notifyItemRemoved(position);
}
It is here that you would make the change. The item would stay in the adapter. You would also need to flag that position as "swiped" in case the view holders are recycle so you can maintain the visual "swiped" state.
public void onItemDismiss(int position) {
// Change background color, etc.
}
Take a look at code that has a "swipe to delete" function with "undo" for some ideas. Here is an example with a dialog that is called before deletion actually occurs if "Cancel" is clicked. There are many other examples of "undo" available. What you are trying to do can be considered to be an immediate and implicit "undo" with a visual change to the background.
If you want to have the item move back into position after a swipe, the following should work:
public void onItemDismiss(int position) {
notifyItemChanged(position);
}

Change the recyclerview's focus to certain item position?

So I have a standard RecyclerView that takes a list of posts and displays them to the user. My problem is when the user comes into the activity, I want to be able to change the focus to a particular post.
Ex. User A sees that he has a notification that of someone has liked his/her post. He/she clicks that notification, and it loads the activity of user's post, and then the focus changes to the position of the post that had bee liked.
I pass in the postID to the activity using an intent. I then run the Recycler View, and onBindHolder i try to see if the post's ID matches to the postID I sent in via intent. If it does, I now set the activity's variable postFocusPosition to the position of that post.
Now I'm stuck on what that magic method i need to call in RecyclerView class to actually change the focus to that item position!
Hope someone can help enlighten me on that magic line(s) of code that changes focus!
recyclerView.setAdapter(adapter);// set adapter on recyclerview
recyclerView.scrollToPosition(mSkipTo); //use to focus the item with index
adapter.notifyDataSetChanged();
mProgressDialog.dismiss();
For smooth scrolling effect and to avoid any resizing issue of recyclerview items, you can use
recyclerView.smoothScrollToPosition(itemposition); //you can get this position, from your adapter class through an interface method
As with "scrollToPosition", I was facing resizing issue of recyclerview items.
Note : You could use this method for both horizontal and vertical recyclerview.
just use this
recyclerView.scrollToPosition(position);

RecyclerView: Highlight selected item

I have implemented a RecyclerView and I have set it up to use CAB. But how can I highlight the selected items? If a certain position I checked I stored in a SparseBooleanArray.
My first thought was to store the specific View containg all the elements in my ViewHolder and then in onBindViewHolder set the background somehow to: ?android:attr/activatedBackgroundIndicator
But how can I do that? Is that a useful approach?
I finally solved this by simply adding some minor things:
First of all, the items of the RecyclerView have to use this as background:
android:background="?android:attr/activatedBackgroundIndicator"
Then for the RecyclerView simply call:
setSelected(true); on the indiviual views.
If you want to change the View itself, you need to dispatch adapter.notifyItemChanged(position) and in return, recycler view will call onBind method where you can set the background.
If you don't need to update the view itself, I would suggest using an item decorator.

Categories

Resources