Android Firebase recycleradapter显示错误信息
我的应用程序使用firebase RecyclerAdapter在活动中显示植物实体。 我这样做是为了,如果我使用ViewHolder和RecyclerAdapter长按Cardview格式显示的实体,它将提示执行删除,并删除firebase数据库和存储上的plant entity+图像。删除和添加植物在后端可以顺利工作,因为我可以在firebase数据库中确认这一点 但是,当我删除一个plant实体并添加一个新实体时,CardView会显示上一个或另一个图像。删除应用程序并重新安装似乎可以解决问题,因此我认为这可能与本地缓存有关 PlantActivity.java加载植物的位置 我认为,如果有某种方法以某种方式刷新活动,或者RecyclerAdapter。。。虽然我已经尝试了很多东西 公共类PlantActivity扩展了AppActivity{Android Firebase recycleradapter显示错误信息,android,firebase,firebase-realtime-database,firebase-storage,Android,Firebase,Firebase Realtime Database,Firebase Storage,我的应用程序使用firebase RecyclerAdapter在活动中显示植物实体。 我这样做是为了,如果我使用ViewHolder和RecyclerAdapter长按Cardview格式显示的实体,它将提示执行删除,并删除firebase数据库和存储上的plant entity+图像。删除和添加植物在后端可以顺利工作,因为我可以在firebase数据库中确认这一点 但是,当我删除一个plant实体并添加一个新实体时,CardView会显示上一个或另一个图像。删除应用程序并重新安装似乎可以解决
private static final int ADD_REQUEST = 101;
private static final String TAG = "PlantActivityView";
private DatabaseReference mDatabaseReference;
private FirebaseRecyclerAdapter plantAdapter;
private PlantDAO mPlantDAO;
private UserDAO mUserDAO;
private CoordinatorLayout coordinatorLayout;
@Override
protected void onStart() {
super.onStart();
if(!mUserDAO.isLoggedIn()){
finish();
startActivity(new Intent(PlantActivity.this, LoginActivity.class));
}
plantAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
plantAdapter.stopListening();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plant_view);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mPlantDAO = new PlantDAO(mDatabaseReference);
mUserDAO = new UserDAO();
//make custom appcompat toolbar to replace actionbar and add logout item
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
coordinatorLayout = findViewById(R.id.plant_coordinator);
providePlantsOfCurrentUser();
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),PlantAddActivity.class);
startActivityForResult(intent, ADD_REQUEST);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.menuLogout:
mUserDAO.getAuth().signOut();
finish();
startActivity(new Intent(PlantActivity.this,LoginActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Snackbar GoodResultSnackbar = Snackbar.make(coordinatorLayout,"PLANT ADDED",Snackbar.LENGTH_SHORT);
Snackbar BadResultSnackbar = Snackbar.make(coordinatorLayout,"PLANT ADD FAILED",Snackbar.LENGTH_SHORT);
if(requestCode == ADD_REQUEST){
if(resultCode == Activity.RESULT_OK){
GoodResultSnackbar.show();
} else if(resultCode == Activity.RESULT_CANCELED){
BadResultSnackbar.show();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void providePlantsOfCurrentUser(){
FirebaseRecyclerOptions<Plant> options = new FirebaseRecyclerOptions.Builder<Plant>().setQuery(mPlantDAO.currentUserPlantsQuery(), Plant.class).build();
plantAdapter = new FirebaseRecyclerAdapter<Plant,PlantViewHolder>(options) {
@NonNull
@Override
public PlantViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cardview_item_plant, parent, false);
return new PlantViewHolder(view);
}
@Override
protected void onBindViewHolder(@NonNull final PlantViewHolder holder, final int position, @NonNull final Plant model) {
StorageReference localstorage = FirebaseStorage.getInstance().getReferenceFromUrl(model.getImageLocation());
String plantText = /*model.getPlantID() + ": " + */ model.getPlanttype();
holder.tv_plant_name.setText(plantText);
//image implementation
GlideApp.with(getApplicationContext()).load(localstorage).into(holder.img_plant_thumbnail);
holder.dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
mPlantDAO.deletePlant(model.getPlantID());
plantAdapter.notifyDataSetChanged();
break;
case DialogInterface.BUTTON_NEGATIVE:
//Return
break;
}
}
};
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//passing data with intent to PlantDetailActivity instance
Intent intent = new Intent(getApplicationContext(), PlantDetailActivity.class);
intent.putExtra("plantID", model.getPlantID());
intent.putExtra("planttype", model.getPlanttype());
//image implementation
intent.putExtra("image_url", model.getImageLocation());
//start the activity
startActivity(intent);
}
});
holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
showDeleteDialog(holder);
return true;
}
});
}
};
RecyclerView recyclerView = findViewById(R.id.recyclerview_id);
recyclerView.setAdapter(plantAdapter);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
}
private void showDeleteDialog(PlantViewHolder holder){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Delete this plant?").setPositiveButton("Yes", holder.dialogClickListener)
.setNegativeButton("Cancel", holder.dialogClickListener).show();
}
}位置和型号在onBindViewHolder方法中是最终的 viewholder可以是最终的,但不能是数据或位置 使用holder.getAdapterPosition可以获取诸如click listeners之类的注释性界面中的位置
然后使用getItem方法从adapter类中获取数据,@cutiko的最后一个答案肯定有帮助!但我想我意识到了问题所在。我正在以以下方式保存新Plant对象的plantID字符串属性: plant+数据库中的植物计数++当前用户的ID+.jpg 这导致的问题是,当我删除一个plant实体并添加另一个时,可能会导致数据库中的两个plant实体具有相同的ID,从而导致奇怪的行为
我将解决这个问题,而不是从数据库中删除植物,将新属性的活动更改为false,并且不在FirebaseRecyclerAdapter中显示这些属性plant currentPlant=plant plantAdapter.getItemholder.getAdapterPosition;mPlantDAO.deletePlantcurrentPlant.getPlantID;像这样的?在onBindViewHolder开始时声明当前工厂并使用模型进行设置不是更有效吗?是和否。是的,麻烦更少。不,RecyclerView。适配器不是那样工作的。问题在于与回收商的逻辑作斗争。创建一个普通的回收器适配器,然后使位置最终,你会得到一个皮棉解释它,比我在评论中做得更好。