【问题标题】:Livedata is working on one activity but not working on other activityLivedata 正在处理一项活动,但未处理其他活动
【发布时间】:2020-07-03 11:12:26
【问题描述】:

我正在从 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 加载数据,它就可以工作。那么为什么我的活动没有显示来自 SQLite 的任何项目?

        animalAdapter.setAnimals(AnimalDump.insertToList());

这是我的AnimalAdapter 课程

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);
    }

【问题讨论】:

  • 发布AnimalAdapter班级代码
  • @MD 我已经添加了AnimalAdapter 类。请检查。我对这两个活动都使用了相同的 AnimalAdapter 类。
  • setAnimals(..) 内调用notifyDataSetChaged() this.animals = animals;之后
  • @MD 非常感谢...它奏效了。将其发布在答案部分,以便我可以打勾:v顺便说一句为什么它在AnimalAugmented上工作我不明白。 :(

标签: android mvvm android-recyclerview android-jetpack android-viewmodel


【解决方案1】:

this.animals = animals; 之后在setAnimals(..) 内调用notifyDataSetChaged()

列表数据更改后,您必须致电notifyDataSetChaged()

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      相关资源
      最近更新 更多