In RecyclerViewFragment Class, there is MovieData, and the Adapter Class stores MovieData.getMovieList( ).
My question is, when Event Handler be triggered,
Add / Delete data directly in RecyclerViewFragment Class
Define add( ) / delete( ) function in Adapter Class and call adapter.add( ) / adapter.delete( ) in RecyclerViewFragment Class
Which way is the better design? Who has the responsibility to take care of data change?
I would suggest to have RecyclerViewFragment containing the data. And create an adapter passing the reference to the data. For example:
mAdapter = new CustomAdapter(mMovieData.getMovieList());
Then in the RecyclerViewFragment just perform the needed actions such as add / remove such as:
mMovieData.getMovieList().add(index);
Think this is the most common way todo it. You do not want to replicate the getMovieList data twice in adapter and RecyclerViewFragment. This will get confusing.
If data change is happening after adapter has been initialized, then it should be handled inside adapter. Adapter also has a nifty function notifyDataSetChanged() which will update item positions inside the adapter when data has changed.
The recyclerview is not concerned with the data, this is all handled by the adapter you have created to present the data. Have a look at the functions here to see what options you have in regard to data changes.
Adapter is the responsible class for filling a list with data ,for example if you have a list that need to be filled with data lets say SCORES then the adapter is the one responsible for filling these scores in the list. on the other side, RecyclerView is reposnsilbe for making the adapter fill it with more speed and effecieny, the recyclerView uses views that are previously used to display data by the adapter and place them in cache for later reuse to display the same type object so that it doesn't have to initialize a new object each time the adapter want to fill item in the list which make it faster.
and here is a link that might help you as well :
Hope my answer have helped you.
Related
I am trying to update data in the recyclerview from the adapter, a function inside the adapter to do the update.
It is working properly and data is being added to the database but it is not updating the views, I need to restart the app so that it runs the cursor to get data from the database and load the views.
I figured out that the main problem is the different lists in the adapter and in the main activity. The list from the main activity is controlling the views so that when i update the list in the adapter nothing happens.
'''kotlin
private val adapter = Padapter (mainActivityList)
and
class adapter(private val adapterList:ArrayList)
'''
How can I do it ? Should i try to call a function in the main activity ?
I really appreciate any help or suggestions you can provide.
I solved it as adam yong suggested in the comments. I stored the list in the adapter.
At first i didnt know how to do that but i discovered somewhere that i had to call the list to the database thought the adapter like this :
In the main activity:
"'Kotlin
adapter.list.addAll( dbHandler!!.cursor())
"'
I am having problems sorting items inside the recycler view after updating them.
I found this approach that is looking terrible and im wondering if there is a better approach. Also im using it to add new records to the recycler view but im not sure if it's a good practice of if I should change it.
Another big doubt I have in my code is about how im handling things in the adapter
Is it possible or better to do the sorting through the view holder ?
I really appreciate any help or suggestions you can provide.
Aproach:
Calling function on main activity to do the folowing
MyList.clear()
MyList.addAll( dbHandler!!.cursor())
MyList.sortedWith(compareBy({ it.sortervalue }))
adapter.notifyDataSetChanged()
How im handling buttons, is it a good practice or a big no ?
inside the onBindViewHolder
p0.itemView.editButton.setOnClickListener {
editpress()
Log.d("myTag", "edit pressed")
}
I solved it by moving the list entirely to the adapter so i dont call the adapter giving the list like
in Main activity it was :
private val adapter = adapter (list)
instead i do like this now :
private val adapter = adapter ()
and in main activity on create
adapter.lista.addAll( dbHandler!!.cursor())
so the list is inside the adapter only now when i sort it i dont have to pass it to adapter again.
to sort it :
listaPrioridades.sortByDescending { it.xxxx }
where xxxx is the column you are sorting.
What is the best way to clear an adapter in Kotlin?
I was trying to clear a recyclerview and update the values.
I am using LoaderManager and I am kind of stuck in this state.
If you want update recyclerview after adding/removing data in your adapter use this code
If you use Arraylist to store the data objects then just clear your list and call notifyDataSetChanged.
dataList.clear()
recyclerView?.adapter?.notifyDataSetChanged()
Say I have a List<User>. Now I can wrap this list in an ArrayAdapter.
List<User> users = Users.getAll();
ArrayAdapter<User> = new ArrayAdapter<User>(this, android.R.layout.simple_list_item_1, users);
I then bind the adapter to a listview to display the list of Users.
Users.getAll() uses Sugar ORM to query the database and return a list of users. Items can be added to the user list from the activity that displays the user list. I am wondering how do I keep the listview updated.
Option 1
One way is to manually update the users as a I add to the database and then call adapter.notifyDataSetChanged(). This works, but it doesn't feel right because I am maintaining a "fake" list that represents what is in the database.
Option 2
I am wondering how bad is it if I just clear the items in users, update it with the results of a new database query and then call adapter.notifyDataSetChanged()?
Will all the child views be thrown away and be re-rendered? Or does it call the equals() method to see if the models bound to each child is the same and then update only what is new?
Other Info
Since I am using SugarORM, I don't think I can get access to the Cursor to do something more efficient. However if there is a better way to keep the list synced with SugarORM, I am happy to hear that as well.
In answer to your option 2: No, it doesnt call equals, because the adapter works in conjunction with the widget to re-use the views, it doens't create a new view foreach item in the list, it create a view foreach visible item and as you scroll re-uses view that left the screen.
The best option here is to create your own adapter, creating a class extending BaseAdapter and creating your own logic inside it requerying the database and notifying the change to the listview (or gridview)..
On the other hand doing what you said here:
I am wondering how bad is it if I just clear the items in users, update it with the results of a new database query and then call adapter.notifyDataSetChanged()?
isn't bad either.
Create a DAO class that extends Observable, then have your Adapter implement Observer. Now every time you add or remove a SugarRecord, do through the DAO class and whoever is register as the Observer will get notified through the following method:
#Override
public void update(Observable observable, Object o)
You can more about Observable/Observer pattern here. This is just one of the many examples and tutorials out there.
I am having a situation where I want to update my Custom List View using BaseAdapter whenever my Database is updated. I have tried calling invalidate() on this Custom List but it didn't work, similarly I even tried having a timer to update my list after sometime, that didn't work either. Please let me know of possible solution.
Update:
This is how I am making my custom list view
li= (ListView)findViewById(R.id.id_lv_row);
ColorDrawable divcolor = new ColorDrawable(Color.DKGRAY);
registerForContextMenu(li);
li.setDivider(divcolor);
li.setDividerHeight(2);
li.setAdapter(new FriendsPositionAdapter(this));
BaseAdapter.notifyDataSetChanged() should do the trick as long as the data behind the adapter actually changed. That's all you need to do to refresh the list.
Invalidate is for repainting views only, you have to tell to the List adapter (BaseAdapter) that dataset has changed.
When the data changes, asign the new dataset to the adapter, and later call notifyDataSetChanged()...
in order to make functional notifyDataSetChanged() the adapter data must be changed. Remember that the original data that change is not reflected automatically to the adapter.
//here i retrieve the new list, named "beans"
lista = (BeanList) result.getDataObject();
Vector<Bean>beans = list.getBeanList();
((BeanListAdapter)listAdapter).syncData(beans);
((BeanListAdapter)listAdapter).notifyDataSetChanged();
//now the syncData method
public void syncData( List<PINPropiedad> newData ){
for(Object o : newData){
add(o);
}
}