TheMovieDb API – Part 7 – Load and show

MovieZone demo app runing

It’s finally time! Welcome back to this series on implementing TheMovieDb API. As always remember all the code for this series will be in this GitHub repo today we are taking all the building blocks created in previous posts and finally begin to show up the good stuff. Let’s get started!

First let’s create the fragment that will implement our MoviesContract.View that we created previously. Go ahead and use, if possible, the built in Fragment template leave the create resource/layout view option marked so Android Studio automatically generates it for you. Now you will have two new things one class representing your Fragment and a new layout.xml file for it. Here are mine:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.jrosa.moviezone.MoviesFragment">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/movies_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:listitem="@layout/movie_view" />

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>

The most important element in here is the tools:listitem=”@layout/movie_view” with it we can preview how our items look in the recycler view directly. Next up the fragment class implementing our contract and other required methods.

public class MoviesFragment extends Fragment implements MovieItemClickListener,
        MoviesContract.View {

    public static final String TAG = "MoviesFragment";

    private ProgressBar progressBar;
    private MoviesAdapter moviesAdapter;
    private MoviesContract.UserActionsListener mActionsListener;

    public MoviesFragment() {
        // Required empty public constructor
    }

    public static MoviesFragment newInstance() {
        return new MoviesFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) e{
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        moviesAdapter = new MoviesAdapter(getContext(), this);
        mActionsListener = new MoviesPresenter(ApiClient.createService(MovieServiceInterface.class), this);

        if (savedInstanceState == null) {
            mActionsListener.loadMovies();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.fragment_movies, container, false);
        progressBar = (ProgressBar) root.findViewById(R.id.progress_bar);
        RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.movies_recycler_view);
        recyclerView.setAdapter(moviesAdapter);
        recyclerView.setHasFixedSize(true);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.addItemDecoration(new MovieItemDecorator(getContext()));

        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        return root;
    }

    @Override
    public void onResume() {
        if (mActionsListener != null) {
            mActionsListener.setProgressBar(false);
            mActionsListener.loadMovies();
        }
        super.onResume();
    }

    @Override
    public void onMovieActionClick(View v, int position) {
        //nothing for now :)
    }

    @Override
    public void showProgressBar(boolean active) {
        if (active)
            progressBar.setVisibility(View.VISIBLE);
        else
            progressBar.setVisibility(View.INVISIBLE);
    }

    @Override
    public void showMovieDetailUi(Bundle movieArgs) {
        //nothing for now.
    }

    @Override
    public void setMovies(List<Movie> movies) {
        moviesAdapter.addAll(movies);
    }

    @Override
    public void clearMovies() {
        moviesAdapter.clear();
    }

    @Override
    public void showMessage(String msg, int duration) {
        if (getView() != null)
            Snackbar.make(getView(), msg, duration).show();
    }

Easy right? I added an items decorator to include spacing between each item, you can find the code for it here. By implementing our MoviesContract.View interface we get a cleaned implementation of each possible action so far that is movie related. Notice thouth there are a few we have implemented but have not done anything yet such as showMovieDetailUi() this are in a future blog post. The rest are pretty straight forward. One quick note thouth these fragment does not implement, yet, onSavedInstance() method to prevent re-fetch on rotation.

Now that we have our fragment ready let’s load it up in our MainActivity.class

public class MainActivity extends AppCompatActivity {

    private FragmentManager mFragmentManager;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFragmentManager = getSupportFragmentManager();
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle(R.string.app_name);
        setSupportActionBar(toolbar);

        if (savedInstanceState == null) {
            mFragmentManager.beginTransaction()
                    .add(R.id.main_container, MoviesFragment.newInstance(), MoviesFragment.TAG)
                    .commit();
        }

        progressBar.setVisibility(View.GONE);
    }
}

See how short and to the point this is? The most important part is in bold above, we are checking if don;t have a savedInstanceState in memory if so we add the movies fragment by calling newInstance() static method, a convenience method to ensure only one instance of itself.

That’s it fire it up! You should get something similar like the screenshot below.

MovieZone demo app runing
MovieZone demo app runing

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Awesome! But we are just beginning to see our long work pay off. Stay tuned because next time we are placing some action in that details button!

Cheers,

Joel

Please follow and like us:
Facebook
Twitter
Joel Sosa

Author: Joel Sosa

Android nanodegree holder | Graduate Student @GeorgiaTech CS Interactive Intelligence | @gdgpuertorico Organizer