Я работаю с MVVM. Главный экран показывает постеры фильма только во время отладки (а не во время обычного запуска).
Проблема в наблюдении за RecyclerView
населением. Observer
в MainActivity
. Я ожидаю, что метод notifyDataSetChanged
вызовет
плакаты появляются после получения данных от API, но этого не происходит.
Мой очищенный код, связанный только с этой проблемой, доступен в https://github.com/RayaLevinson/Test
Я упускаю важный момент, связанный с Observer
. Пожалуйста, помогите мне! Спасибо.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view_movie);
mMainActivityViewModal = ViewModelProviders.of(this).get(MainActivityViewModel.class);
mMainActivityViewModal.init();
mMainActivityViewModal.getMovies().observe(this, new Observer<List<Movie>>() {
@Override
public void onChanged(@Nullable List<Movie> movies) {
mAdapter.notifyDataSetChanged();
}
});
initRecyclerView();
}
private void initRecyclerView() {
mAdapter = new RecyclerViewAdapter(this, mMainActivityViewModal.getMovies().getValue());
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
mRecyclerView.setAdapter(mAdapter);
}
MovieRepository.java
public class MovieRepository {
private static final String TAG = "MovieRepository";
private static String mSortBy = "popular";
private static MovieRepository instance;
private List<Movie> movies = new ArrayList<>();
public static MovieRepository getInstance() {
if (instance == null) {
instance = new MovieRepository();
}
return instance;
}
public MutableLiveData<List<Movie>> getMovies() {
setMovies();
MutableLiveData<List<Movie>> data = new MutableLiveData<List<Movie>>();
data.setValue(movies);
return data;
}
private void setMovies() {
Context context = GlobalApplication.getAppContext();
if (NetworkUtils.isNetworkAvailable(context)) {
movies.clear();
new MovieRepository.FetchMoviesTask().execute(mSortBy);
} else {
alertUserAboutNetworkError();
}
}
private void alertUserAboutNetworkError() {
Context context = GlobalApplication.getAppContext();
// Toast.makeText(context, R.string.networkErr, Toast.LENGTH_LONG).show();
}
private class FetchMoviesTask extends AsyncTask<String, Void, List<Movie>> {
@Override
protected List<Movie> doInBackground(String... params) {
if (params.length == 0) {
return null;
}
String sortBy = params[0];
Log.d(TAG, "In doInBackground " + sortBy);
URL moviesRequestUrl = NetworkUtils.buildUrl(sortBy);
try {
String jsonWeatherResponse = NetworkUtils.getResponseFromHttpUrl(moviesRequestUrl);
return MovieJsonUtils.getMoviesDataFromJson(jsonWeatherResponse);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(List<Movie> parsedMoviesData) {
if (parsedMoviesData != null) {
for (Movie movie : parsedMoviesData) {
movies.add(movie);
Log.d(TAG, "In onPostExecute " + " movie was added");
}
}
}
}
}
MainActivityViewModel.java
public class MainActivityViewModel extends ViewModel {
private MutableLiveData<List<Movie>> mMovies;
private MovieRepository mMoviewRepository;
public void init() {
if (mMovies != null) {
return;
}
mMoviewRepository = MovieRepository.getInstance();
mMovies = mMoviewRepository.getMovies();
}
public LiveData<List<Movie>> getMovies() {
return mMovies;
}
}
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
private final Context mContext;
private List<Movie> mMovies;
public RecyclerViewAdapter(Context mContext, List<Movie> movies) {
this.mMovies = movies;
this.mContext = mContext;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_list_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder called");
Picasso.get()
.load(mMovies.get(holder.getAdapterPosition()).getPosterPath())
.placeholder(R.mipmap.ic_launcher)
.into(holder.image);
}
@Override
public int getItemCount() {
return mMovies.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
final ImageView image;
final LinearLayout parentLayout;
private ViewHolder(@NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.image);
parentLayout = itemView.findViewById(R.id.parent_layout);
}
}
public void update(List<Movie> movies) {
mMovies.clear();
mMovies.addAll(movies);
notifyDataSetChanged();
}
}