我尝试通过本课程了解Room持久性库,但是,我坚持更新RecyclerView并在Room中填充数据。很抱歉出现了这个样板代码。数据传递到房间成功,并保持那里作为Android数据库检查器显示给我,但同时,Rycyclerview是空的。下面是我的代码:
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
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(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;
}
}
库类
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;
}
}
视图模型
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); }
}
对于添加数据,我使用DialogFragment与setFragmentResultListener,放置在片段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);
});
}
和recyclerview设置的代码:
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是典型的,这里onBindViewHolder和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());
}
….
}
我真的无法理解为什么在我将项目添加到ViewModel后,回收器视图不显示数据,理论上应该处理。我将提供额外的代码,如果需要的话。提前谢谢。
除了@a_local_nobody指出的notifyDataSetChanged()
之外,您需要将更新的列表发送到RecyclerView
适配器,而不是原始列表
将setRecyclerView()
中的dapter.setListContent(AccountItemList);
替换为dapter.setListContent(accounts);
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);
}
public void setListContent(List <Dashboard_Account> pad_list) {
this.pad_list = pad_list;
notifyItemChanged(getItemCount());
}
可能是错误的,但我真的不明白在这里做notifyItemChanged
的意义,试着添加notifyDataSetChanged()
代替
notifyItemChanged
告诉回收器特定的项已经更改,而notifyDataSetChanged
通知回收器所有数据(可能)已经更改,这迫使它重新绑定它所有的项。
从你提到的课程中,没有提到notifyItemChanged
,所以我不确定你为什么添加它:)
您提供的课程链接有:
void setWords(List<Word> words){
mWords = words;
notifyDataSetChanged(); <-- notifyDataSetChanged, not itemChanged
}