com.burhan.udacity.popularmovies.ui.fragment.MoviesFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.burhan.udacity.popularmovies.ui.fragment.MoviesFragment.java

Source

/*
 * Copyright 2015.  Emin Yahyayev
 *
 * 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 com.burhan.udacity.popularmovies.ui.fragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.burhan.udacity.popularmovies.R;
import com.burhan.udacity.popularmovies.data.model.Movie;
import com.burhan.udacity.popularmovies.data.repository.MoviesRepository;
import com.burhan.udacity.popularmovies.ui.adapter.MoviesAdapter;
import com.burhan.udacity.popularmovies.ui.helper.MoviesHelper;
import com.burhan.udacity.popularmovies.ui.module.MoviesModule;
import com.burhan.udacity.popularmovies.ui.widget.BetterViewAnimator;
import com.burhan.udacity.popularmovies.ui.widget.MultiSwipeRefreshLayout;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.inject.Inject;

import butterknife.Bind;
import rx.subscriptions.CompositeSubscription;
import timber.log.Timber;

public abstract class MoviesFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener,
        MultiSwipeRefreshLayout.CanChildScrollUpCallback, MoviesAdapter.OnMovieClickListener {

    public interface Listener {
        void onMovieSelected(Movie movie, View view);
    }

    private static final String STATE_MOVIES = "state_movies";
    private static final String STATE_SELECTED_POSITION = "state_selected_position";

    protected static final int ANIMATOR_VIEW_LOADING = R.id.view_loading;
    protected static final int ANIMATOR_VIEW_CONTENT = R.id.movies_recycler_view;
    protected static final int ANIMATOR_VIEW_ERROR = R.id.view_error;
    protected static final int ANIMATOR_VIEW_EMPTY = R.id.view_empty;

    @Inject
    MoviesRepository mMoviesRepository;

    @Bind(R.id.multi_swipe_refresh_layout)
    MultiSwipeRefreshLayout mSwipeRefreshLayout;
    @Bind(R.id.movies_animator)
    BetterViewAnimator mViewAnimator;
    @Bind(R.id.movies_recycler_view)
    RecyclerView mRecyclerView;

    protected MoviesHelper mHelper;
    protected Listener listener;
    protected MoviesAdapter mMoviesAdapter;
    protected GridLayoutManager mGridLayoutManager;
    protected CompositeSubscription mSubscriptions;
    protected int mSelectedPosition = -1;

    @Override
    public void onAttach(Activity activity) {
        if (!(activity instanceof Listener)) {
            throw new IllegalStateException("Activity must implement MoviesFragment.Listener.");
        }

        super.onAttach(activity);
        listener = (Listener) activity;
        mHelper = new MoviesHelper(activity, mMoviesRepository);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_movies, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mSubscriptions = new CompositeSubscription();

        mSelectedPosition = savedInstanceState != null ? savedInstanceState.getInt(STATE_SELECTED_POSITION, -1)
                : -1;

        List<Movie> restoredMovies = savedInstanceState != null
                ? savedInstanceState.getParcelableArrayList(STATE_MOVIES)
                : new ArrayList<>();

        mMoviesAdapter = new MoviesAdapter(this, restoredMovies);
        mMoviesAdapter.setListener(this);

        initSwipeRefreshLayout();
        initRecyclerView();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(STATE_MOVIES, new ArrayList<>(mMoviesAdapter.getItems()));
        outState.putInt(STATE_SELECTED_POSITION, mSelectedPosition);
    }

    @Override
    public void onDestroyView() {
        mSubscriptions.unsubscribe();
        super.onDestroyView();
    }

    @Override
    public void onDetach() {
        listener = (movie, view) -> {
        };
        mMoviesAdapter.setListener(MoviesAdapter.OnMovieClickListener.DUMMY);
        super.onDetach();
    }

    @Override
    public boolean canSwipeRefreshChildScrollUp() {
        return mRecyclerView != null && ViewCompat.canScrollVertically(mRecyclerView, -1)
                || mViewAnimator != null && mViewAnimator.getDisplayedChildId() == ANIMATOR_VIEW_LOADING;
    }

    public void scrollToTop(boolean smooth) {
        if (smooth)
            mRecyclerView.smoothScrollToPosition(0);
        else
            mRecyclerView.scrollToPosition(0);
    }

    @Override
    public abstract void onRefresh();

    @Override
    public void onContentClicked(@NonNull Movie movie, View view, int position) {
        mSelectedPosition = position;
        listener.onMovieSelected(movie, view);
    }

    @Override
    public void onFavoredClicked(@NonNull final Movie movie, int position) {
        boolean favored = !movie.isFavored();
        Timber.v("onFavoredClicked: favored=" + favored);

        mHelper.setMovieFavored(movie, favored);
        if (favored)
            showToast(R.string.message_movie_favored);
    }

    @CallSuper
    protected void initRecyclerView() {
        mGridLayoutManager = new GridLayoutManager(getActivity(),
                getResources().getInteger(R.integer.movies_columns));
        mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                int spanCount = mGridLayoutManager.getSpanCount();
                return (mMoviesAdapter.isLoadMore(position) /* && (position % spanCount == 0) */) ? spanCount : 1;
            }
        });

        mRecyclerView.setLayoutManager(mGridLayoutManager);
        mRecyclerView.setAdapter(mMoviesAdapter);
        if (mSelectedPosition != -1)
            mRecyclerView.scrollToPosition(mSelectedPosition);
    }

    private void initSwipeRefreshLayout() {
        mSwipeRefreshLayout.setColorSchemeColors(getResources().getIntArray(R.array.swipe_progress_colors));
        mSwipeRefreshLayout.setOnRefreshListener(this);
        mSwipeRefreshLayout.setCanChildScrollUpCallback(this);
    }

    @Override
    protected List<Object> getModules() {
        return Collections.<Object>singletonList(new MoviesModule());
    }
}