Java tutorial
/* * Copyright (c) 2016 Fabio Berta * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ch.berta.fabio.popularmovies.presentation.viewmodels; import android.databinding.Bindable; import android.os.Parcel; import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; import android.view.View; import java.util.ArrayList; import java.util.List; import ch.berta.fabio.popularmovies.BR; import ch.berta.fabio.popularmovies.R; import ch.berta.fabio.popularmovies.domain.models.Movie; import ch.berta.fabio.popularmovies.domain.models.SnackbarAction; import ch.berta.fabio.popularmovies.domain.models.Sort; /** * Provides an implementation of the {@link MovieGridViewModelOnl} interface. * <p/> * Subclass of {@link MovieGridViewModelBaseImpl}. */ public class MovieGridViewModelOnlImpl extends MovieGridViewModelBaseImpl<MovieGridViewModelOnl.ViewInteractionListener> implements MovieGridViewModelOnl { public static final Creator<MovieGridViewModelOnlImpl> CREATOR = new Creator<MovieGridViewModelOnlImpl>() { public MovieGridViewModelOnlImpl createFromParcel(Parcel source) { return new MovieGridViewModelOnlImpl(source); } public MovieGridViewModelOnlImpl[] newArray(int size) { return new MovieGridViewModelOnlImpl[size]; } }; private final List<Movie> mMovies; private int mMoviePage; private boolean mRefreshing; private boolean mLoadingMore; private boolean mLoadingNewSort; private Sort mSortSelected; private int mMovieDbIdSelected; /** * Constructs a new {@link MovieGridViewModelOnlImpl}. * * @param sortSelected the currently selected sort option */ public MovieGridViewModelOnlImpl(@NonNull Sort sortSelected) { mSortSelected = sortSelected; mMovies = new ArrayList<>(); } protected MovieGridViewModelOnlImpl(Parcel in) { super(in); mMovies = in.createTypedArrayList(Movie.CREATOR); mMoviePage = in.readInt(); mRefreshing = in.readByte() != 0; mLoadingMore = in.readByte() != 0; mLoadingNewSort = in.readByte() != 0; mSortSelected = in.readParcelable(Sort.class.getClassLoader()); mMovieDbIdSelected = in.readInt(); } @Override @Bindable public boolean isRefreshing() { return mRefreshing; } @Override public void setRefreshing(boolean refreshing) { mRefreshing = refreshing; notifyPropertyChanged(BR.refreshing); } @Override public SwipeRefreshLayout.OnRefreshListener getOnRefreshListener() { return new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { setRefreshing(true); mMoviePage = 1; mView.loadQueryMoviesWorker(mMoviePage, mSortSelected.getOption(), false); } }; } @Override public void onSortOptionSelected(@NonNull Sort sortSelected) { mSortSelected = sortSelected; setMoviesLoaded(false); setRefreshing(false); mLoadingMore = false; mLoadingNewSort = true; mMoviePage = 1; mView.loadQueryMoviesWorker(mMoviePage, mSortSelected.getOption(), true); } @Override public void loadMovies() { final int moviesSize = getItemCount(); if (moviesSize == 0) { mMoviePage = 1; mView.loadQueryMoviesWorker(mMoviePage, mSortSelected.getOption(), false); } else { if (mLoadingMore) { // scroll to last position to show load more indicator mView.scrollToPosition(moviesSize - 1); } if (!mLoadingNewSort) { setMoviesLoaded(true); } } } @Override public void onMoviesOnlineLoaded(@NonNull List<Movie> movies) { mView.removeQueryMoviesWorker(); if (mMoviePage == 1) { setMovies(movies); } else { addMovies(movies); } mMoviePage++; } private void setMovies(List<Movie> movies) { // finished loading mLoadingNewSort = false; setRefreshing(false); // set movies mMovies.clear(); if (!movies.isEmpty()) { mMovies.addAll(movies); } mView.notifyMoviesChanged(); // update view mView.scrollToPosition(0); setMoviesLoaded(true); setMoviesAvailable(!movies.isEmpty()); } private void addMovies(List<Movie> movies) { // remove load more indicator hideLoadMoreIndicator(); // insert movies mMovies.addAll(movies); mView.notifyMoviesInserted(getItemCount(), movies.size()); // indicate load more process finished mLoadingMore = false; } private void hideLoadMoreIndicator() { final int position = getItemCount() - 1; mMovies.remove(position); mView.notifyLoadMoreRemoved(position); } @Override public void onMoviesOnlineLoadFailed() { mView.removeQueryMoviesWorker(); if (mMoviePage == 1) { mLoadingNewSort = false; setRefreshing(false); setMoviesLoaded(true); mView.showSnackbar(R.string.snackbar_movies_load_failed, new SnackbarAction(R.string.snackbar_retry) { @Override public void onClick(View v) { setRefreshing(true); mView.loadQueryMoviesWorker(mMoviePage, mSortSelected.getOption(), false); } }); } else { hideLoadMoreIndicator(); mLoadingMore = false; mView.showSnackbar(R.string.snackbar_movies_load_failed, null); } } @Override public void onLoadMore() { mLoadingMore = true; showLoadMoreIndicator(); mView.loadQueryMoviesWorker(mMoviePage, mSortSelected.getOption(), false); } private void showLoadMoreIndicator() { mMovies.add(null); mView.notifyLoadMoreInserted(getItemCount() - 1); } @Override public boolean isLoading() { return mRefreshing || mLoadingMore || mLoadingNewSort; } @Override public boolean hasLoadedAllItems() { return mMoviePage >= MOVIE_DB_MAX_PAGE; } @Override public int getItemCount() { return mMovies.size(); } @Override public int getItemViewType(int position) { if (mMovies.get(position) == null) { return TYPE_PROGRESS; } return TYPE_ITEM; } @Override public Movie getMovieAtPosition(int position) { return mMovies.get(position); } @Override public boolean isMovieSelected(@NonNull Movie movie) { final int dbId = movie.getDbId(); if (dbId == mMovieDbIdSelected) { return true; } mMovieDbIdSelected = dbId; return false; } @Override public void onMovieRowItemClick(int position, @NonNull View sharedView) { final Movie movie = getMovieAtPosition(position); mView.launchDetailsScreen(movie, sharedView); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeTypedList(mMovies); dest.writeInt(mMoviePage); dest.writeByte(mRefreshing ? (byte) 1 : (byte) 0); dest.writeByte(mLoadingMore ? (byte) 1 : (byte) 0); dest.writeByte(mLoadingNewSort ? (byte) 1 : (byte) 0); dest.writeParcelable(mSortSelected, 0); dest.writeInt(mMovieDbIdSelected); } }