Reputation: 51
So I have an activity containing 2 fragments, a repository and a ViewModel class since I'm following android developers' guide to use a MVVM structure. So far it seems to work, but I'm not sure if I'm following a good practices when it comes to the implementation. So far it looks like this:
Repository class:
public class MyRepository{
...
private MutableLiveData<ArrayList<Book>> bookList;
public MyRepository(){
bookList= new MutableLiveData<>();
getBookList(); //method that uses retrofit to fill bookList, since it's empty at this point
}
...
}
ViewModel class:
public class BookViewModel extends ViewModel {
private MyRepository repository;
private LiveData<ArrayList<Book>> bookList;
public void init(){
repository = new MyRepository();
bookList = repository.getBookList();
};
public LiveData<ArrayList<Book>> getBookList() {
if (bookList== null) {
bookList= new MutableLiveData<>();
}
return bookList;
}
Recycler view that shows the book list:
public class MyRecyclerView extends RecyclerView.Adapter<MyRecyclerView.MyViewHolder> {
Context context;
ArrayList<Book> bookList;
public MyRecyclerView(Context context) {
context = context;
bookList = new ArrayList<>();
}
public void setList(ArrayList<Book> list){
bookList= list;
notifyDataSetChanged();
}
...
}
Fragment 1
public class Fragment1 extends Fragment {
....
@Nullable
@Override
public View onCreateView(...) {
....
recyclerview_adapter = new AdapterRecyclerView(Context);
myRecyclerView = (RecyclerView)view.findViewById(R.id.recycler_view);
myRecyclerView.setLayoutManager(new LinearLayoutManager((getActivity())));
myRecyclerView.setAdapter(recyclerview_adapter);
viewModel.getbookList().observe(getViewLifecycleOwner(), new Observer<ArrayList<Producto>>() {
@Override
public void onChanged(ArrayList<Producto> books) {
recyclerview_adapter.setList(viewModel.getbookList().getValue());
}
});
return view;
}
...
}
Questions:
1) Am I using this correctly? Should I use the viewModel object in onActivityCreated() or elsewhere to prevent any errors?
2) Should I use an instance of the viewModel in each fragment, or should I use it in the activity that contains them all, and then pass it to each fragment by parameters?
3) Where is the correct place to call init()
(method to get all the books in the database) for the first time, so the user sees the book list stored in the database when the app is opened?
4) Should the ArrayList<Book> bookList;
in MyRecyclerView
class be a LiveData/MutableData as well?
Upvotes: 1
Views: 695
Reputation: 1361
onViewCreated
in Fragment.Reason -> your are updating UI when changes in the Viewmodel occur. You might encouter a crash if you populate the view with data from viewmodel if view element is not yet instantiated.
Reason -> If you have only one instance of viewmodel in activity, passing them to fragments will not be ideal as it will get complex when you add more fragments.
Init
can be called from different places depending on the type of tasks it performs. In your case, onViewCreated should be good.reason-> In your case, your init
is fetching data from repository.Once that data is fetched, your recyclerview
will come into play. You dont want to play with view elements in OnCreateView
ArrayList<Book> bookList
in RecyclerView
does not have to be livedata.Reason-> Livedata is for communication between view (Activity/Fragment) and Viewmodel. Once your livedata has been observed by the view, you dont need to treat it as livedata anymore.
Upvotes: 1