Firebase recycleradapter отображает неверную информацию Android - PullRequest
0 голосов
/ 18 декабря 2018

Мое приложение использует Firebase RecyclerAdapter для отображения "растений" сущностей в действии.Я сделал так, чтобы, если я долго щелкну по объекту, отображаемому в формате Cardview, используя ViewHolder и RecyclerAdapter, он предложит выполнить удаление и удаление объекта Plant + изображение в базе данных и хранилище Firebase.Удаление и добавление заводов работают без проблем на бэкэнде, поскольку я могу подтвердить это в моей базе данных Firebase.

Однако, когда я удаляю объект «завод» и добавляю новый, CardView показывает предыдущий или другойобраз.Удаление приложения и его переустановка, кажется, решают проблему, поэтому я думаю, что это может быть связано с локальным кэшем.

  • PlantActivity.java (куда загружаются растения) Я думаю, что это можетрешить, если был какой-то способ обновить активность каким-либо образом или RecyclerAdapter ... хотя я уже пробовал много вещей

открытый класс PlantActivity расширяет 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();
}

}

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Последний ответ @cutiko определенно помог!Но я думаю, что понимаю проблему.Я сохранял свой строковый атрибут plantID (нового объекта Plant) следующим образом: "plant_" + count () для "Plant" в базе данных + "_" + ID текущего пользователя + ".jpg"

Проблема, которую это вызывает, состоит в том, что когда я удаляю объект растения и добавляю другой, это может привести к тому, что 2 объекта растения в базе данных будут иметь одинаковый идентификатор, что вызывает странное поведение.

Я решу это, вместо того, чтобы удалять растение из базы данных, меняя новый атрибут («активный») на false и не отображая их в FirebaseRecyclerAdapter

0 голосов
/ 18 декабря 2018

Позиция и модель являются окончательными в методе onBindViewHolder

Держатель может быть конечным, но не данные или позиция

Используйте holder.getAdapterPosition (), чтобы получить позицию внутри анонимногоинтерфейсы, такие как прослушиватели кликов

, а затем получить данные с помощью метода getItem () из класса адаптера

...