I have a situation that I must get some data from the database with a button click in Recyclerview item and fill the Recyclerview adapter again with new data.
Should I put the database fetch code in button onClickListener in the adapter or it is better to do it in another way? For example with help of Callback in activity.
It is a definitely bad scenario, because database belongs to model and RecyclerView - to View layers. All presentation logic will be in adapter (along with execution in background). It will lead to difficult to maintain application.
Related
suppose i have an app that has a tool bar and a fragment container in the main activity, the fragment container in this situation is displaying a fragment that has a recyclerview which has a list of objects retrieved from a basic room database, and the toolbar has a button that clears out all the data stored in the database (which means the code that responsible for this is located in the main activity not in the fragment), how should i go about notifying the adapter inside the fragment that the object list has been updated?
i don't think any code is necessary here as it's more of a general question, but i will gladly share all the code necessary if its needed.
You can make the adapter a public static variable and call notifyDataSetChanged from the main activity
Basically what the title says. I'm trying to start a ViewPager activity when a user clicks a RecyclerView item. I'm not having problems here, that works fine. The goal is to go from a grid based gallery to viewpager gallery. I'm also trying to send the List<> of data which is loaded over the network. This is where I'm having a lot of trouble. The data is sent through a singleton because it's too large to send through intent and if opened in the new activity too quickly upon app startup, more data is loaded in the original activity (Even if Call is cancelled, using Retrofit2 btw) and I need to notify the adapter, which I have a listener that does.
Another crash that is common is a null pointer when reading an item in viewpager activity, which doesn't make sense to me because the item is not null in the original activity before sending, but if I wait a few seconds it is not null. Some of the code pertaining to my issue can be found here, a question I asked yesterday with a solution I could not successfully implement.
Please point me in the right direction for starting a ViewPager of the same dataset from a RecyclerView, thanks
When you are "sending" feed data to the view pager activity, use a shallow copy of the list instead of directly referencing it as shown below
DataTransferer.get().storeItems(new ArrayList(feed));
This should prevent IllegalStateException raised by feed being updated on your RecyclerView activity.
I trying to refactor one of my activity class to implement mvp(using mvp mosby library) . I have a RecyclerView and in this view there is some items that some changes apply to them during the run time. for example I do some I/O operation and change one row.
I think it's better to keep my items in presenter class; what is the best practice for this? keep this in 1)presenter or 2)activity or 3)only keep view related item in adapter and all other item in presenter.
the activity now keep items directly and change item row in activity and then notify adapter. isn't better to move all this line in adapter and notify adapter in the adapter class? for example i want change icon of some row.where and which class is responsible for that? adapter? activity? now I want to implement it like this in adapter:
changeItemIcon(int position, int iconRes){
mImages.get(position).setICon(iconRes);
notifyItemChanged(position);
}
I invoke this method on activity and invoke activity method from presenter.
is it good? what is the best practice to do this?
UPDATE
also I find this question ( Best way to update data with a RecyclerView adapter ) that using adapter method for changing items. but what about modify? Need I keep reference to items in my activity?
for example i want change icon of some row.where and which class is responsible for that? adapter? activity?
I know it sounds a little bit strange, but changing an element is always the responsibility of your "business logic", even just for "icons".
The workflow should be as follows (unidirectional data flow):
View appeares, tells presenter to load a list of items
Presenter loads items form "business logic" and registers himself as an
observer / listener / callback (whatever you want to call it)
Presenter receives result and tells the view to display the list of
items (through RecyclerView and corresponding adapter).
so far is what you have implemented I guess, now it comes to the point where you want to change an item.
User clicks on an item in your RecyclerView which then should trigger to change the icon of this item. Therefore View should call: presenter.changeItem()
Presenter is just the man in the middle in this case and will invoke the "business logic layer" to tell that the item should be changed to new state (icon has changed).
"Business logic layer" will change the models state (change the items icon) and then will notify its observer / listeners that the model has been changed.
Since Presenter is still observing / listening to the business logic layer (see point 2.) the Presenter will be notified (see point 6.) with a new (updated) list of items containing the updated item which icon has been changed.
Similar to point 3. Presenter will tell the view to display the new (updated) list of items (through RecyclerView and corresponding adapter).
Do you see the unidirectional data flow? That is very important. Immutability FTW.
MVP has two different variants: Passive View and Supervising Controller. Depending on your taste, you can stick to one or mix both of them in your app.
If you choose Passive View, you need to hide Model from View and let Presenter format data then set to the View. In this case, you need to keep Model reference in Presenter. View should only hold view-data (adapter) for its displaying purpose.
If you stick to Supervising Controller, you can allow View to directly bind data from Model and ask Model to perform some simple logic. Presenter should only care complex logic, i.e some operations which need to involve Services. In this case, you can give Model (your items) to View (activity) and let it interact with Model in some simple manner.
PS: Please also check out our new MVP framework: Robo MVP at http://robo-creative.github.io/mvp.
I've never used mosby, but I've just read their docs (good reading btw) and here's my understanding:
A recycler view usually consists of the view (android term) and an adapter. Both are connected inside a fragment or activity. In terms of MVP/mosby this is all view layer. The presenter should only retrieve and pass the to-be-shown data from your service (model layer in mosby, "service layer" or "business logic" in other concepts), which in turn gets it from a DAO or repository (model layer).
The docs say that the presenter only handles the view state, not the actual contents. Your state is "showing list".
I'm using the navigation drawer example in Android. What's the easiest way to change the string items in the adapter dynamically? Do I just create a new adapter and set it with my new values?
The problem is I'm altering the string items based on user state logged in and logged out. How do I access it from a non static context and just say update list adapter? It doesn't seem to be re-drawing itself and running my adapter code which is dynamic based on user state, so I guess it runs/inits once and I have to create and load a new adapter if I want to change it later?
Thanks.
You haven't given us much to go on (a little code would be nice), but you can update the data in the ListView by calling notifyDatasetChanged() on the Adapter. If you are not using a custom Adapter e.g. an ArrayAdapter then you can just create a new Adapter instance with different String values and set it to the ListView.
I have a ListView that is like an inbox. The information comes from a user,so the ListView displays text and a userPicture.To display userPictures, I display the userPicture if exists or a imageView of a letter of the first name.
when I receive data from WS I launch an asynctask that compare userPicture ids with DB to ask the WS for ones I don't have or one's that have changed.
After the asyncTask finishes I save pictures locally and notify listView that the data set has changed, in order to look for the new pictures.
my problem comes when there is only 1 user on the listview and the picture wasn't found but was downloaded from WS. after calling notifyDataSetChanged, also calling refreshDrawableState and invalidateViews,that acording to documentation "Causes all the views to be rebuilt and redrawn". the image is not changed and imageView still shows the letter ImageView,
neither scrolling through the listView its updated. (I guess is part of the Viewholder that recycle the views that is meant for performance and a good practive acording to ).
on the getView of the adapter I have a the Following statement to processThe Picture
if(mIDataPersistence.userHasPicture(userId)
ViewHolder.userImg.setImageBitmap(mIDataPersistence.getUserPicture(userId));
else
ViewHolder.userImg.setImageBitmap(BitmapUtils.createBitMap(userName);
note: mIDataPersistence is persistence data interface to access all the data locally stored that I'm using here. and BitmapUtils.createBitMap() makes a bitmap from the first letter of the user.
can anyone help me or point me on a way to make listView update images in this particular case.