Stack Overflow Asked by GremlinShX on February 10, 2021
I try to understand the Room persistence library with this course, however, I stuck with updating RecyclerView and populate it with data in Room. Sorry for this boilerplate code.
Data passing to Room successfully and kept there as Android Database Inspector show to me, but at the same time, Rycyclerview is empty. Here is my code :
Item:
@Entity (tableName = "active_accounts")
public class Dashboard_Account {
@PrimaryKey (autoGenerate = true)
int accountID;
@ColumnInfo(name = "accountName")
String accountName;
@ColumnInfo(name = "accountEmail")
String accountEmail;
public Dashboard_Account() {
}
public Dashboard_Account(String accountName,String accountEmail) {
this.accountName = accountName;
this. accountEmail = accountEmail;
}
//getters and setters
DAO
@Dao
public interface Dashboard_DAO {
@Insert (onConflict = OnConflictStrategy.REPLACE)
void insert(Dashboard_Account... dashboard_accounts);
@Delete
void delete(Dashboard_Account account);
@Query("DELETE FROM active_accounts")
void deleteAll();
@Update
void update(Dashboard_Account account);
@Query("SELECT * FROM active_accounts" )
LiveData<List<Dashboard_Account>> getAllAccounts();
}
Database
@Database(entities = {Dashboard_Account.class},version = 2,exportSchema = false)
public abstract class Dashboard_Database extends RoomDatabase {
public abstract Dashboard_DAO dashboard_dao();
private static Dashboard_Database INSTANCE;
public static Dashboard_Database getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (Dashboard_Database.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
Dashboard_Database.class, "account_database")
.fallbackToDestructiveMigration()
.build();
}
}
}
return INSTANCE;
}
}
Repository class
public class Dashboard_Repository {
private Dashboard_DAO mDashboardDao;
private LiveData<List<Dashboard_Account>> mAllAccounts;
Dashboard_Repository(Application application) {
Dashboard_Database db = Dashboard_Database.getDatabase(application);
mDashboardDao = db.dashboard_dao();
mAllAccounts = mDashboardDao.getAllAccounts();
}
LiveData<List<Dashboard_Account>> getAllAcounts(){
return mAllAccounts;
}
public void insert (Dashboard_Account account) {
new insertAsyncTask(mDashboardDao).execute(account);
}
private static class insertAsyncTask extends AsyncTask<Dashboard_Account, Void, Void> {
private Dashboard_DAO mAsyncTaskDao;
insertAsyncTask(Dashboard_DAO mDashboardDao) {
mAsyncTaskDao = mDashboardDao;
}
@Override
protected Void doInBackground(final Dashboard_Account... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
Viewmodel
public class Dashboard_ViewModel extends AndroidViewModel {
private Dashboard_Repository mRepo;
private LiveData<List<Dashboard_Account>> mAllAccounts;
public Dashboard_ViewModel(@NonNull Application application) {
super(application);
mRepo = new Dashboard_Repository(application);
mAllAccounts = mRepo.getAllAcounts();
}
LiveData<List<Dashboard_Account>> getmAllAccounts() { return mAllAccounts; }
public void insert(Dashboard_Account account) { mRepo.insert(account); }
}
For adding data I use DialogFragment with setFragmentResultListener that placed in Fragment onViewCreated()
public class Dashboard_Fragment extends Fragment {
…
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
setRecyclerView();
getParentFragmentManager().setFragmentResultListener("fragmentKey", getViewLifecycleOwner(), (requestKey, result) -> {
String name = result.getString("nameResult");
String email = result.getString ("email");
Dashboard_Account account = new Dashboard_Account(name,email);
dashboardViewModel.insert(account);
});
}
And the code of recyclerview setup:
private void setRecyclerView(){
binding.accountView.setLayoutManager(new LinearLayoutManager(requireContext()));
adapter = new Dashboard_RecyclevrViewAdapter(AccountItemList);
dashboardViewModel.getmAllAccounts().observe(requireActivity(), accounts -> {
adapter.setListContent(AccountItemList);
});
binding.accountView.setAdapter(adapter);
}
RecyclerViewAdapter is typical and here onBindViewHolder and setListcontent:
public class Dashboard_RecyclevrViewAdapter extends RecyclerView.Adapter<Dashboard_RecyclevrViewAdapter.MyViewHolder> {
....
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
if(pad_list!=null){
final Dashboard_Account account = pad_list.get(position);
holder.binding.accountType.setText(account.getAccountName());
holder.binding.acountemail.setText(account.getAccountValue()));
}
}
…
public void setListContent(List <Dashboard_Account> pad_list) {
this.pad_list = pad_list;
notifyItemChanged(getItemCount());
}
….
}
I am really can’t understand why the recycler view doesn’t show data after I add the item to ViewModel, that in theory should handle with that. I will provide additional code if it will be needed. Thanks in advance.
Besides notifyDataSetChanged()
that pointed out by @a_local_nobody you need to send the updated list to the RecyclerView
adapter, not the original list
To do that replace dapter.setListContent(AccountItemList);
with dapter.setListContent(accounts);
in setRecyclerView()
private void setRecyclerView(){
binding.accountView.setLayoutManager(new LinearLayoutManager(requireContext()));
adapter = new Dashboard_RecyclevrViewAdapter(AccountItemList);
dashboardViewModel.getmAllAccounts().observe(requireActivity(), accounts -> {
adapter.setListContent(accounts); // <<< Change here
});
binding.accountView.setAdapter(adapter);
}
Answered by Zain on February 10, 2021
public void setListContent(List <Dashboard_Account> pad_list) {
this.pad_list = pad_list;
notifyItemChanged(getItemCount());
}
could be wrong but i don't really see the point of doing notifyItemChanged
here, try adding in notifyDataSetChanged()
instead
notifyItemChanged
tells the recycler that a specific item has been changed, while notifyDataSetChanged
informs the recycler that all the data has (potentially) changed, this forces it to rebind all the items it has.
From the course you've mentioned, there's no reference to notifyItemChanged
, so i'm not sure why you added it :)
the course link you've provided has:
void setWords(List<Word> words){
mWords = words;
notifyDataSetChanged(); <-- notifyDataSetChanged, not itemChanged
}
Answered by a_local_nobody on February 10, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP