Android Studio-Java RecyclerView显示的视图(持有者)比房间数据库中的行数还要多
1。实体(表)CurrentyEntity.javaAndroid Studio-Java RecyclerView显示的视图(持有者)比房间数据库中的行数还要多,java,android,mvvm,android-recyclerview,android-room,Java,Android,Mvvm,Android Recyclerview,Android Room,1。实体(表)CurrentyEntity.java @Entity(tableName = "Corona") public class CurrentyEntity { @PrimaryKey(autoGenerate = true) private int id; public int getId() { return this.id; } public void setId(int id) { this.id = id; } @NonNull
@Entity(tableName = "Corona")
public class CurrentyEntity {
@PrimaryKey(autoGenerate = true)
private int id;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@NonNull
@ColumnInfo (name = "country")
private String country;
@NonNull
public String getCountry() {
return this.country;
}
@ColumnInfo (name = "infections_count")
private int infections_count;
public int getInfections_count() {
return this.infections_count;
}
public CurrentyEntity (@NonNull String country, int infections_count){
this.country = country;
this.infections_count = infections_count;
}
@Ignore
public CurrentyEntity (int id, String country , int infections_count){
this.id = id;
this.country = country;
this.infections_count = infections_count;
}
}
2。道玩家道。类
import java.util.List;
@Dao
public interface PlayerDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(CurrentyEntity player);
@Update
void update(CurrentyEntity...players);
// how to delete a column value for a row
@Delete
void delete(CurrentyEntity player);
// how to return a specific row ??
@Query("SELECT * FROM Corona ORDER BY infections_count ASC ")
LiveData<List<CurrentyEntity>> returnRowLowToHigh();
@Query("SELECT COUNT(*) FROM Corona")
Integer getRowCount();
}
@Database(entities = {CurrentyEntity.class}, version = 2, exportSchema = false)
public abstract class RoomDB extends RoomDatabase {
public abstract PlayerDao PlayerDao();
private static RoomDB INSTANCE;
public static RoomDB getINSTANCE(final Context context){
if (INSTANCE == null)
{
synchronized (RoomDB.class)
{
if (INSTANCE == null)
{
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), RoomDB.class,"pumpin_DataBase")
// Wipes and rebuilds instead of migrating
// if no Migration object.
// Migration is not part of this practical.
.fallbackToDestructiveMigration()
.addCallback(afterOpeningRoomDB)
.build();
}
}
}
return INSTANCE;
}
// // the only 2 callback methods
// //void onCreate(SupportSQLiteDatabase db)
// //Called when the database is created for the first time.
// //
// //void onOpen(SupportSQLiteDatabase db)
// //Called when the database has been opened.
private static RoomDatabase.Callback afterOpeningRoomDB = new RoomDatabase.Callback(){
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
new LaunchAsyncTask(INSTANCE).execute();
}
};
private static class LaunchAsyncTask extends AsyncTask<Void,Void,Void>{
private final PlayerDao DAO;
public LaunchAsyncTask(RoomDB db){
DAO = db.PlayerDao();
}
@Override
protected Void doInBackground(final Void... voids) {
DAO.insert(new CurrentyEntity("jordan",3434));
return null;
}
}
}
public class AllRepository {
private PlayerDao playerDao;
private LiveData<List<CurrentyEntity>> rowList;
private static String rowCount;
AllRepository(Application application){
RoomDB roomdb = RoomDB.getINSTANCE(application);
playerDao = roomdb.PlayerDao();
rowList = playerDao.returnRowLowToHigh();
}
LiveData<List<CurrentyEntity>> returnRowList () {return rowList;}
public void RemoveRow(CurrentyEntity row){ new removeRow(playerDao).execute(row);}
public void AddRow(CurrentyEntity row) { new addRow(playerDao).execute(row);}
public void UpdateRow(CurrentyEntity row){ new updateRow(playerDao).execute(row);}
public String getRowCount(){ new getRowCount(playerDao).execute();
return rowCount; }
private static class removeRow extends AsyncTask<CurrentyEntity,Void,Void> {
private PlayerDao removePlayerDao;
public removeRow(PlayerDao currentDao){
removePlayerDao = currentDao;
}
@Override
protected Void doInBackground(CurrentyEntity... players) {
removePlayerDao.delete(players[0]);
return null;
}
}
private static class addRow extends AsyncTask<CurrentyEntity,Void,Void> {
private PlayerDao addPlayerDao;
public addRow(PlayerDao currentDao){
addPlayerDao = currentDao;
}
@Override
protected Void doInBackground(CurrentyEntity... players) {
addPlayerDao.insert(players[0]);
return null;
}
}
private static class updateRow extends AsyncTask<CurrentyEntity,Void,Void> {
private PlayerDao updatePlayerDao;
public updateRow(PlayerDao currentDao){
updatePlayerDao = currentDao;
}
@Override
protected Void doInBackground(CurrentyEntity... players) {
updatePlayerDao.update(players[0]);
return null;
}
}
private static class getRowCount extends AsyncTask<CurrentyEntity,Void,Void> {
private PlayerDao addPlayerDao;
public getRowCount(PlayerDao currentDao){
addPlayerDao = currentDao;
}
@Override
protected Void doInBackground(CurrentyEntity... players) {
rowCount = String.valueOf(addPlayerDao.getRowCount());
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
public class MenWomenRecycler extends RecyclerView.Adapter<MenWomenRecycler.MenWomenViewHolder> {
private final LayoutInflater mInflater;
private List<CurrentyEntity> listOfCases;
MenWomenRecycler(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setList(List<CurrentyEntity> incomingList ){
listOfCases = incomingList;
notifyDataSetChanged();
}
@NonNull
@Override
public MenWomenViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.view_holder_men_women, parent, false);
return new MenWomenViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MenWomenViewHolder holder, int position) {
CurrentyEntity currentCase = listOfCases.get(position);
TextView first = holder.cardView.findViewById(R.id.men_women_count);
first.setText(currentCase.getCountry());
TextView secound = holder.cardView.findViewById(R.id.men_women_country);
secound.setText(Integer.toString(currentCase.getInfections_count()));
// Warning : maybe I shouldve used String.format instead
}
// if this is set to 0 it fucks up the whole thing. RecyclerView'ss contents won't be displayed
// getItemCount() is called many times, and when it is first called,
// mWords has not been updated (means initially, it's null, and we can't return null).
@Override
public int getItemCount() {
if(listOfCases != null){
Log.w("Row Count", String.valueOf(listOfCases.size()));
return listOfCases.size();
} else return 0;
}
class MenWomenViewHolder extends RecyclerView.ViewHolder {
/* private final TextView Country;
private final TextView count;
Country = itemView.findViewById(R.id.men_women_country);
count = itemView.findViewById(R.id.men_women_count);
*/
private CardView cardView;
public MenWomenViewHolder(@NonNull View itemView) {
super(itemView);
cardView = (CardView) itemView;
}
}
}
并使用第一个statemment在RoomDB.class中插入一行,即
DAO.insert(new CurrentyEntity("jordan",3434));
到目前为止,一切正常,他们的回收商只会显示一个单一的视图(viewHolder)
现在,让我们重新包含上面从HomeActivity.class中排除的两行内容,并再次添加它们
RecyclerView将显示随机数目的视图,该数目大于RoomDB中的行数
例如,当我运行应用程序并启动它时
由于我只插入了3行,所以RecyclerView应该显示3个视图(视图持有者),而不是6个视图。这是由于以下原因 第一次启动应用程序时,它会在DB中创建3个条目。 RoomDb课程(Jordan one)的1个条目,家庭活动课程的2个条目 现在,如果您通过按下设备后退按钮关闭应用程序并重新打开它,它将在DB中创建另外2个条目(Home Activities条目(easy&letsee))。 由于数据库连接仍然打开,RoomDB类(Jordan one)将不会有任何条目
new LaunchAsyncTask(INSTANCE).execute();
不会执行
现在,如果您关闭应用程序并重新打开,那么它将在DB中插入另外3个条目。因此,总计将是DB+中以前的条目加上这3个新条目
同样的行为还在继续
上述问题是由于主键不正确导致的。每次在DB中创建新条目时
您可以通过将国家/地区设置为主键来尝试以下代码
@NonNull
@PrimaryKey
@ColumnInfo(name = "country")
private String country;
发生这种情况的原因如下 第一次启动应用程序时,它会在DB中创建3个条目。 RoomDb课程(Jordan one)的1个条目,家庭活动课程的2个条目 现在,如果您通过按下设备后退按钮关闭应用程序并重新打开它,它将在DB中创建另外2个条目(Home Activities条目(easy&letsee))。 由于数据库连接仍然打开,RoomDB类(Jordan one)将不会有任何条目
new LaunchAsyncTask(INSTANCE).execute();
不会执行
现在,如果您关闭应用程序并重新打开,那么它将在DB中插入另外3个条目。因此,总计将是DB+中以前的条目加上这3个新条目
同样的行为还在继续
上述问题是由于主键不正确导致的。每次在DB中创建新条目时
您可以通过将国家/地区设置为主键来尝试以下代码
@NonNull
@PrimaryKey
@ColumnInfo(name = "country")
private String country;
我非常感谢你的解释,这个问题让我抓狂。但问题是我在自动生成“id”列(主键)为了更新已经存在的条目。好吧,那么我想我必须寻找另一种方法。我非常感谢你的清晰解释,这个问题让我发疯。但问题是我正在自动生成“id”列(主键)为了更新已经存在的条目。那么,我想我必须寻找另一种方法
new LaunchAsyncTask(INSTANCE).execute();
@NonNull
@PrimaryKey
@ColumnInfo(name = "country")
private String country;