I use adapter in RecyclerView. Each item contains a ProgressBar. Since progress speed is sometimes very high, a fragment permanently call notifyDataSetChanged(), which initiates update adapter. But there is one unpleasant feature: at this time ViewHolder doesn't respond to a click and user can't open the item, while progress speed will not decrease. Is it possible to solve this problem?
notifyDataSetChanged actually redraws the list for you. So click on the list item at that instant may actually refer to the content which was available before you refreshed the adapter contents. Hence its a good thing that click isn't enabled. Having said that, the refresh usually happens so quick that the user won't see a visible lag. Hence please go through you getView() method in the adapter if there is an intense or time taking process in the adapter implementation. Hope this helps! :)
Related
I have a problem regarding the back button feature together with RecyclerView, my goal is to emulate the behavior in the Contacts application, where you press and hold (long press) an item in the RecyclerView and a check box appears behind the item(s) (all of them). Then, when you press the back button, all the check boxes disappear.
Regarding the information I provided we can break the problem in two parts:
First, we need to solve the long click problem, which I suspect we can use
NotifyDataSetChanged() together with hiding the check boxes in the XML so that we can switch between checkbox.setVisibility(VISIBLE) and checkbox.setVisibility(GONE).
Lastly, and this is the hardest part for me, I would like that, when back button is pressed, all the check boxes disappear, instead of leaving the app.
Thank you in advance and sorry if the problem is not understandable, as this is the first time I am posting a problem and English is not my native language.
What you are describing is known as Contextual Action Mode.
You'll notice, that when you long press the item the toolbar (action bar) on top changes and shows the number of selected items and a set of action you can apply to the selected items.
Pressing the back button then cancels the action mode.
It is beyond Stackoverflow's scope to explain the whole action mode system, but you can simply search for it in the internet.
Here is a tutorial for beginners, for example.
I can give you a better answer if you post your code.
You'd probably want your adapter to contain a list of selected items. If the list has any elements, you show the checkboxes and check the ones that correspond to the list. If it is empty, you don't do that. You're correct about notifying data set changed. Long press on an item would add that item to this list. Then when your adapter re-laid out your items, it would show the checkboxes since that list would not be empty.
For the second issue, you'd want to override onBackPressed() in your activity. Then you can have some code like:
public void onBackPressed() {
if (adapter.hasItemsSelected()) {
adapter.clearSelection()
} else {
super.onBackPressed()
}
}
You'll need to write these adapter methods. hasItemsSelected should check to see if there are elements in the selected items list and clearSelection should clear the list and notify data set changed.
I have list/rows of checkboxes inside recycle view. In my case, the user can only select 3 checkboxes out of many. As soon as the user selects the third checkbox, I want to disable rest of the checkboxes in different rows.
I am capturing selecting/deselecting checkboxes inside adapter class.
As far as I know, I can enable/disable checkboxes inside onBindViewHolder class.
But in my case, I want to enable/disable checkboxes, after they have been rendered.
One of the approaches I can think is, to call notifyDataSetChanged(); from Activity class and then rerender all the recycled view.
But I hope there is the better way than doing this, inside the adapter class itself.
ps: I am new to android/java.
notifyDataSetChanged() will defently work in your case.
Please note that you don't have to call this method from the Activity.
You can call it internally within your adapter after the third checkbox was selected.
From the top of my head, One way to do this would be to store the "checked" positions indide an array within the adapter, then inside onBindViewHolder() check to see if the current position should be enabled or disabled.
In your model class you can have a boolean variable that decide whether the item should be enabled or not and another boolean variable to keep track of the checked state, or if the item is checked or not. In onBindViewHolder check the variable to enable or disable the item.Keep track of the selected items and then after every check and uncheck, check if the selected items exceeds the limit. Then loop through your items and then check if the item is checked or not. if the item is not checked set the value to false and after the loop send a notifyDataSetChanged() and in onBindViewHolder() check for the value and enable or disable the item/checkbox
You can use SparseBooleanArray to record all the changes for each item based on their positions.
You can use the following method in RecyclerView adapter:
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)
Read more at RecyclerView.Adapter.
Only use notifyDataSetChanged() as the last resort. Because calling notifyDataSetChanged() will force the views to rebind and relayout. As in the documentation says:
void notifyDataSetChanged ()
Notify any registered observers that the data set has changed.
There are two different classes of data change events, item changes
and structural changes. Item changes are when a single item has its
data updated but no positional changes have occurred. Structural
changes are when items are inserted, removed or moved within the data
set.
This event does not specify what about the data set has changed,
forcing any observers to assume that all existing items and structure
may no longer be valid. LayoutManagers will be forced to fully rebind
and relayout all visible views.
RecyclerView will attempt to synthesize visible structural change
events for adapters that report that they have stable IDs when this
method is used. This can help for the purposes of animation and visual
object persistence but individual item views will still need to be
rebound and relaid out.
If you are writing an adapter it will always be more efficient to use
the more specific change events if you can. Rely on
notifyDataSetChanged() as a last resort.
Hi everyone.
I've come up with an idea for an Android App, and I was thinking how to turn my thoughts into something working. I know how to program for Android even though I'm not that advanced as you might see, so I wanted some tips from you guys who I'm sure will be able to help.
Idea
I was thinking about an App to organize stuff, see your objects on a list and be able to add, move or remove them from the list.
Thoughts
I first thought I needed a RecyclerViewto display each item. Then I thought every item itself might be a box, and so be containing other items inside: this brought me to think of a sort of "nested" system of RecyclerViews. Before going too deep into this system I had to clarify each item should have been a Class, each of which should have had a RecyclerView assigned.
Question
I was wondering how I could make this "nested" system of RecyclerViews. I thought about making a RecyclerView an object, because I need each RecyclerView to display, function and be always the same in any screen of any item. But I don't know what the best way is.
Should I make it an object? How do I create a new RecyclerView through a button so the user can first tap an item and then, eventually, tap a button (inside the item details view for instance) to make it a box item and so create and open a RecyclerView when tapped?
P.S.
It may seem like multiple questions but it actually is only one: how to add and display a RecycerView when I tap a button inside a details screen of an item, of course automatically (have a reference to that RecyclerView).
You have to create the RecyclerView that holds your items list, let's call it rv_list, this RecyclerView has an adapter that takes each item and adapts it to an xml layout row_item.xml that you should define. Now to make an item itself display its own recyclerview you should put a recyclerview inside row_item.xml and populate it when adapting that item to rv_list inside the method onBindViewHolder.
Here's my problem: I have an app that has an activity with a listview inside it. This activity is recursive, when you click on an item on the list it takes you to the same activity with different items in the listview. A lot of the code is within the ArrayAdaptor for the listview.
When moving forward through the activities the new ones call getView() when creating the listview rows. But when stepping back (pressing back closing the current instance of the activity and moving back to the previous one) these already existent activities don't call getView() so my rows don't get updated.
So I need , onResume, to call getView for the rows. I've tried adding notifyDataSetChanged(),requestLayout() and invalidate() on onResume, doesn't work. getView just doesn't get called.
I've searched for answers to my problem, did not find any. I'm sure there are a million ways to improve my app if I re-write it from the ground up, that's not gonna happen any time soon. I just have a few days to finish this, I'm quite desperate. Please help.
I have an app that uses this RibbonMenu and I wanted to know if it was possible to use the menu items to change the ContentView of the Activity instead of another activity to reduce the size of my app. I've tried doing this already,and it changed the content view perfectly, but i was not able to press the home button. I'm in a bit of a rush here, but i'll try to post code if anyone asks for it. thank you!
Menu items is UI element. It does nothing by itself. It however can trigger some more actions in your code. As for changing activity layout, yes, you can call setContentView() at any time you want.
to reduce the size of my app
this is not the way optimalizations should be done