Livedata 正在处理一个 activity 但不处理其他 activity

Livedata is working on one activity but not working on other activity

我正在从 SQLite 数据库加载动物信息列表。我使用过 MVVM 架构。我在 MainActivity 中有两个按钮,可以启动两个不同的活动。一个是 AnimalAugmented 另一个是 AnimalIntroducer。在这两项活动中,我加载了相同的数据。为了在 AnimalAugmented 中加载数据,我使用了以下代码

        RecyclerView recyclerView = findViewById(R.id.recycler_view_animals);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);

        AnimalAdapter animalAdapter = new AnimalAdapter();
        recyclerView.setAdapter(animalAdapter);

        animalViewModel = ViewModelProviders.of(this).get(AnimalViewModel.class);
        animalViewModel.getAllAnimals().observe(this, animals -> {
            animalAdapter.setAnimals(animals);
        });

它工作正常。但是当我尝试在 AnimalIntroducer 中加载数据时,它没有显示任何项目。对于 AnimalIntroducer 我使用了以前的代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animal_introducer);

        RecyclerView recyclerView = findViewById(R.id.recycler_view_animal_introducer);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
        recyclerView.setHasFixedSize(true);

        AnimalAdapter animalAdapter = new AnimalAdapter();
        recyclerView.setAdapter(animalAdapter);

        animalViewModel = ViewModelProviders.of(this).get(AnimalViewModel.class);
        animalViewModel.getAllAnimals().observe(this, animals -> {

            animalAdapter.setAnimals(animals);
            Log.e(TAG, "onCreate: grid "+animals.size());
            for(Animal animal:animals){
                Log.e(TAG,animal.getBanglaName());
            }
        });
    }

此处它按预期在日志中打印动物列表的大小,但不显示任何项目。但是,如果我从 ArrayList 而不是 ViewModel 加载数据,它就可以工作。那么,为什么我的 activity 没有显示来自 SQLite 的任何项目?

        animalAdapter.setAnimals(AnimalDump.insertToList());

这是我的AnimalAdapterclass

public class AnimalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final String TAG = "Augmented";
    private static final int TYPE_FREE = 1;
    private static final int TYPE_LOCKED = 2;
    List<Animal> animals= new ArrayList<>();

    public OnItemClickListener listener;

    public AnimalAdapter() {

        Log.d(TAG, "AnimalAdapter: ");
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        if(viewType==TYPE_FREE){
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_animal,parent,false);
            return new AnimalViewHolder(view);
        }
        else {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_animal_locked,parent,false);
            return new LockedAnimalViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {


        Animal animal=animals.get(position);
        if(animal.isOffline()){
            ((AnimalViewHolder)holder).setValues(animal);
        }
        else {
            ((LockedAnimalViewHolder)holder).setValues(animal);
        }
    }

    @Override
    public int getItemCount() {
        return animals.size();
    }

    public void setAnimals(List<Animal> animals) {
        this.animals = animals;
        Log.d(TAG, "setAnimals: ");
    }

    @Override
    public int getItemViewType(int position) {
        if(animals.get(position).isOffline())
            return TYPE_FREE;
        else
            return TYPE_LOCKED;
    }

    public void setListener(OnItemClickListener listener) {
        this.listener = listener;
    }

    protected class AnimalViewHolder extends RecyclerView.ViewHolder {

        private ImageView itemAnimalImageView;
        private TextView itemAnimalTextView;
        private Context context;
        public CardView itemCardView;

        public AnimalViewHolder(@NonNull View itemView) {
            super(itemView);
            itemAnimalImageView=itemView.findViewById(R.id.item_animal_image_view);
            itemAnimalTextView=itemView.findViewById(R.id.item_animal_text_view);
            itemCardView = itemView.findViewById(R.id.item_card_view);
            context = itemView.getContext();

            itemView.setOnClickListener(view -> {

                int position = getAdapterPosition();
                if(listener!=null && position!=RecyclerView.NO_POSITION){
                    listener.onItemClick(animals.get(position));
                }

                YoYo.with(Techniques.RollIn)
                        .duration(700)
                        .repeat(0)
                        .playOn(itemAnimalImageView);

            });

        }

        public void setValues(Animal animal){
            itemAnimalTextView.setText(animal.getBanglaName());
            itemAnimalImageView.setImageResource(context.getResources().getIdentifier(animal.getId(),"drawable",context.getPackageName()));
        }
    }

    protected class LockedAnimalViewHolder extends RecyclerView.ViewHolder {

        private ImageView itemAnimalImageView,itemLockIcon;
        private TextView itemAnimalTextView;
        private Context context;
        public CardView itemCardView;

        public LockedAnimalViewHolder(@NonNull View itemView) {
            super(itemView);
            itemAnimalImageView=itemView.findViewById(R.id.item_animal_image_view);
            itemAnimalTextView=itemView.findViewById(R.id.item_animal_text_view);
            itemCardView = itemView.findViewById(R.id.item_card_view);
            itemLockIcon = itemView.findViewById(R.id.icon_lock);
            context = itemView.getContext();

            itemView.setOnClickListener(view -> {

                YoYo.with(Techniques.RubberBand)
                        .duration(700)
                        .repeat(0)
                        .playOn(itemAnimalImageView);

            });

        }

        public void setValues(Animal animal){
            itemAnimalTextView.setText(animal.getBanglaName());
            itemAnimalImageView.setImageResource(context.getResources().getIdentifier(animal.getId(),"drawable",context.getPackageName()));
        }
    }

    public interface OnItemClickListener{
        void onItemClick(Animal animal);
    }

this.animals = animals;

之后在 setAnimals(..) 内调用 notifyDataSetChaged()

您必须在列表数据更改后调用 notifyDataSetChaged()

RecyclerView Adapters 要求您通知他们有关数据集的任何更改。显然,适配器无法神奇地知道您向列表中添加了一个项目。所以至少,您需要调用 notifyDataSetChanged(),这只会使所有项目无效并再次呈现它们。

在您的情况下,您可能希望将此添加到您的 setAnimals 方法中:

public void setAnimals(List<Animal> animals) {
    this.animals = animals;
    notifyDataSetChanged(); // << this is important
    Log.d(TAG, "setAnimals: ");
}