ViewModel观察器显示空的RecyclerView。

huangapple go评论77阅读模式
英文:

ViewModel Observer shows empty RecyclerView

问题

以下是你提供的代码的翻译部分:

MainActivity:

public class MainActivity extends AppCompatActivity {

    RecyclerView mMainRecycler;
    MoviesViewModel moviesViewModel;
    MainRecyclerAdapter mainRecyclerAdapter;
    Context context = this;

    List<String> genresNames = new ArrayList<>();
    List<Integer> genresIds = new ArrayList<>();
    List<List<Movies.Result>> listResults = new ArrayList<>();

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

        mMainRecycler = findViewById(R.id.main_recycler);

        moviesViewModel = new ViewModelProvider(this).get(MoviesViewModel.class);

        moviesViewModel.getMoviesGenres();
        moviesViewModel.mutableMoviesGenres.observe(this, new Observer<List<MoviesGenres.GenresBean>>() {
            @Override
            public void onChanged(List<MoviesGenres.GenresBean> genresBeans) {

                for (int i = 0; i < genresBeans.size(); i++) {
                    genresIds.add(genresBeans.get(i).getId());
                    genresNames.add(genresBeans.get(i).getName());
                }
            }
        });

        for(int i = 0; i < genresIds.size(); i++) {
            moviesViewModel.getMovieWithGenre(genresIds.get(i));
            moviesViewModel.mutableMoviesWithGenre.observe(this, new Observer<List<Movies.Result>>() {
                @Override
                public void onChanged(List<Movies.Result> results) {
                    listResults.add(results);
                }
            });
        }

        mMainRecycler.setLayoutManager(new LinearLayoutManager(this));
        mainRecyclerAdapter = new MainRecyclerAdapter(context, genresIds, listResults);
        mMainRecycler.setAdapter(mainRecyclerAdapter);
    }
}

Main Recycler Adapter:

public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.MainViewHolder> {

    private Context context;

    private List<List<Movies.Result>> moviesResults;
    private List<Integer> moviesNames;
    private Context mContext;

    public MainRecyclerAdapter(Context context, List<Integer> moviesNames, List<List<Movies.Result>> moviesResults ) {
        this.mContext = context;
        this.moviesNames = moviesNames;
        this.moviesResults = moviesResults;
    }

    @NonNull
    @Override
    public MainRecyclerAdapter.MainViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        return new MainViewHolder(LayoutInflater.from(mContext).inflate(R.layout.category_rv_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull final MainRecyclerAdapter.MainViewHolder holder, int position) {
        holder.genresTv.setText(moviesNames.get(position).toString());

        holder.mRecycler.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false));
        MovieAdapter adapter = new MovieAdapter(moviesResults.get(position));
        holder.mRecycler.setAdapter(adapter);
    }

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

    public class MainViewHolder extends RecyclerView.ViewHolder {
        TextView genresTv;
        RecyclerView mRecycler;

        public MainViewHolder(@NonNull View itemView) {
            super(itemView);

            genresTv = itemView.findViewById(R.id.cat_title);
            mRecycler = itemView.findViewById(R.id.item_recycler);
        }
    }
}

Child Recycler Adapter:

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {

    private List<Movies.Result> moviesResult;

    public MovieAdapter(List<Movies.Result> moviesResult) {
        this.moviesResult = moviesResult;
    }

    @NonNull
    @Override
    public MovieAdapter.MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MovieViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull MovieAdapter.MovieViewHolder holder, int position) {
        String imageUrl = MoviesClient.IMAGE_URL + moviesResult.get(position).getPosterPath();
        Glide.with(holder.mPosterImage.getContext()).load(imageUrl).into(holder.mPosterImage);
    }

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

    public class MovieViewHolder extends RecyclerView.ViewHolder {

        ImageView mPosterImage;

        public MovieViewHolder(@NonNull View itemView) {
            super(itemView);

            mPosterImage = itemView.findViewById(R.id.poster_image);
        }
    }
}
英文:

I'm trying to get some data from an API (using retrofit and MVVM), pass it to the adapter and the recyclerView, however when I run the app all I get is a blank white screen nothing shows up.

I made sure that there is no problem with the API or the data so the problem probably happened when I tried to implement and nested recyclerview.

MainActivity:

public class MainActivity extends AppCompatActivity {
RecyclerView mMainRecycler;
MoviesViewModel moviesViewModel;
MainRecyclerAdapter mainRecyclerAdapter;
Context context = this;
List&lt;String&gt; genresNames = new ArrayList&lt;&gt;();
List&lt;Integer&gt; genresIds = new ArrayList&lt;&gt;();
List&lt;List&lt;Movies.Result&gt;&gt; listResults = new ArrayList&lt;&gt;();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainRecycler = findViewById(R.id.main_recycler);
moviesViewModel = new ViewModelProvider(this).get(MoviesViewModel.class);
moviesViewModel.getMoviesGenres();
moviesViewModel.mutableMoviesGenres.observe(this, new Observer&lt;List&lt;MoviesGenres.GenresBean&gt;&gt;() {
@Override
public void onChanged(List&lt;MoviesGenres.GenresBean&gt; genresBeans) {
for (int i = 0; i &lt; genresBeans.size(); i++) {
genresIds.add(genresBeans.get(i).getId());
genresNames.add(genresBeans.get(i).getName());
}
}
});
for(int i = 0; i &lt; genresIds.size(); i++) {
moviesViewModel.getMovieWithGenre(genresIds.get(i));
moviesViewModel.mutableMoviesWithGenre.observe(this, new Observer&lt;List&lt;Movies.Result&gt;&gt;() {
@Override
public void onChanged(List&lt;Movies.Result&gt; results) {
listResults.add(results);
}
});
}
mMainRecycler.setLayoutManager(new LinearLayoutManager(this));
mainRecyclerAdapter = new MainRecyclerAdapter(context, genresIds, listResults);
mMainRecycler.setAdapter(mainRecyclerAdapter);
}
}

Main Recycler Adapter:

public class MainRecyclerAdapter extends RecyclerView.Adapter&lt;MainRecyclerAdapter.MainViewHolder&gt; {
private Context context;
private List&lt;List&lt;Movies.Result&gt;&gt; moviesResults;
private List&lt;Integer&gt; moviesNames;
private Context mContext;
public MainRecyclerAdapter(Context context, List&lt;Integer&gt; moviesNames, List&lt;List&lt;Movies.Result&gt;&gt; moviesResults ) {
this.mContext = context;
this.moviesNames = moviesNames;
this.moviesResults = moviesResults;
}
@NonNull
@Override
public MainRecyclerAdapter.MainViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
return new MainViewHolder(LayoutInflater.from(mContext).inflate(R.layout.category_rv_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull final MainRecyclerAdapter.MainViewHolder holder, int position) {
holder.genresTv.setText(moviesNames.get(position).toString());
holder.mRecycler.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false));
MovieAdapter adapter = new MovieAdapter(moviesResults.get(position));
holder.mRecycler.setAdapter(adapter);
}
@Override
public int getItemCount() {
return moviesNames.size();
}
public class MainViewHolder extends RecyclerView.ViewHolder {
TextView genresTv;
RecyclerView mRecycler;
public MainViewHolder(@NonNull View itemView) {
super(itemView);
genresTv = itemView.findViewById(R.id.cat_title);
mRecycler = itemView.findViewById(R.id.item_recycler);
}
}
}

Chile Recycler Adapter:

public class MovieAdapter extends RecyclerView.Adapter&lt;MovieAdapter.MovieViewHolder&gt; {
private List&lt;Movies.Result&gt; moviesResult;
public MovieAdapter(List&lt;Movies.Result&gt; moviesResult) {
this.moviesResult = moviesResult;
}
@NonNull
@Override
public MovieAdapter.MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MovieViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull MovieAdapter.MovieViewHolder holder, int position) {
String imageUrl = MoviesClient.IMAGE_URL + moviesResult.get(position).getPosterPath();
Glide.with(holder.mPosterImage.getContext()).load(imageUrl).into(holder.mPosterImage);
}
@Override
public int getItemCount() {
return moviesResult.size();
}
public class MovieViewHolder extends RecyclerView.ViewHolder {
ImageView mPosterImage;
public MovieViewHolder(@NonNull View itemView) {
super(itemView);
mPosterImage = itemView.findViewById(R.id.poster_image);
}
}
}

答案1

得分: 0

你忘记在获取列表后调用notifyDataSetChanged();,因此适配器没有收到通知,无法显示recyclerView中的新数据。

另外,将第二个观察者移到for循环之外。你不需要每次都设置一个新的观察者。

修改为:

moviesViewModel.mutableMoviesWithGenre.observe(this, new Observer<List<Movies.Result>>() {
    @Override
    public void onChanged(List<Movies.Result> results) {
        listResults.add(results);
    }
});   

for(int i = 0; i < genresIds.size(); i++) {
    moviesViewModel.getMovieWithGenre(genresIds.get(i));
}
英文:

You forgot to call notifyDataSetChanged(); after fetching the list, due to this the adapter does not get notified that new data is available for display in recyclerView.

Also, move the second observer outside the for loop. You don't need to set a new observer every time.

Change to this:

moviesViewModel.mutableMoviesWithGenre.observe(this, new Observer&lt;List&lt;Movies.Result&gt;&gt;() {
@Override
public void onChanged(List&lt;Movies.Result&gt; results) {
listResults.add(results);
}
});   
for(int i = 0; i &lt; genresIds.size(); i++) {
moviesViewModel.getMovieWithGenre(genresIds.get(i));
}

huangapple
  • 本文由 发表于 2020年8月24日 08:14:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63553219.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定