Firebase recycleradapter显示错误信息Android [英] Firebase recycleradapter displaying wrong information Android

查看:51
本文介绍了Firebase recycleradapter显示错误信息Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序使用firebase RecyclerAdapter来显示活动中的植物"实体. 我这样做的目的是,如果我使用ViewHolder和RecyclerAdapter长按Cardview格式显示的实体,它将提示执行删除操作,并删除Firebase数据库和存储上的工厂实体+映像.可以在后端上轻松地删除和添加植物,因为我可以在我的Firebase数据库中确认这一点.

My app uses a firebase RecyclerAdapter to display "plant" entities in an activity. I made it so that if I longclick on an entity displayed in Cardview format using a ViewHolder and the RecyclerAdapter it will prompt to perform a delete and delete the plant entity + image on the firebase database and storage. Deleting and adding plants work without a hitch on the backend as I can confirm this on my firebase database.

但是,当我删除一个植物"实体并添加一个新的实体时,CardView会显示上一个或另一个图像.删除应用程序并重新安装它似乎可以解决问题,因此,我认为这可能与本地缓存有关.

However, when I delete a "plant" entity and add a new one, the CardView shows the previous or another image. Deleting the app and reinstalling it seems to fix the problem, because of this I think it might have to do with the local cache.

  • PlantActivity.java(加载植物的位置) 我认为如果可以通过某种方式刷新活动或使用RecyclerAdapter可以解决此问题……尽管我已经尝试了很多事情
  • PlantActivity.java (where the plants are loaded) I think this might be solved if there was some way to refresh the activity in some way or the RecyclerAdapter... although i've tried many things already

公共类PlantActivity扩展了AppCompatActivity {

public class PlantActivity extends AppCompatActivity {

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方法上是最终的

The position and model are final on the onBindViewHolder method

观看者可以是最终的,但不能是数据或位置

The viewholder can be final, but not the data or the position

使用holder.getAdapterPosition()获取匿名接口(如点击监听器)中的位置

Use holder.getAdapterPosition() to get the position inside annonymous interfaces like click listeners

然后使用适配器类中的getItem()方法获取数据

And then get the data using getItem() method from the adapter class

这篇关于Firebase recycleradapter显示错误信息Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆