Android Open Source - watchme Movie List Fragment






From Project

Back to project page watchme.

License

The source code is released under:

Copyright (c) 2012 Johan Brook, Robin Andersson, Lisa Stenberg, Mattias Henriksson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen...

If you think the Android project watchme listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 *  MovieListFragment.java//w w w  . j  a  v a  2s.c  o  m
 *
 *  A fragment that present data about Movies.
 *
 *  @author lisastenberg, Johan Brook
 *  @copyright (c) 2012 Robin Andersson, Johan Brook, Mattias Henriksson, Lisa Stenberg
 *  @license MIT
 */

package se.chalmers.watchme.ui;

import java.io.File;
import java.net.ResponseCache;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import se.chalmers.watchme.R;
import se.chalmers.watchme.activity.MovieDetailsActivity;
import se.chalmers.watchme.database.GenericCursorLoader;
import se.chalmers.watchme.database.ICursorHelper;
import se.chalmers.watchme.database.MoviesTable;
import se.chalmers.watchme.database.WatchMeContentProvider;
import se.chalmers.watchme.model.Movie;
import se.chalmers.watchme.net.ImageDownloadTask;
import se.chalmers.watchme.notifications.NotificationClient;
import se.chalmers.watchme.utils.DateTimeUtils;
import se.chalmers.watchme.utils.ImageCache;
import se.chalmers.watchme.utils.MenuUtils;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter.ViewBinder;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;

// TODO Important! API level required does not match with what is used
@TargetApi(11)
public class MovieListFragment extends ContentListFragment {

  /**
   * Enum that represents a sort order for Movies
   * 
   * @author lisastenberg
   */
  public enum SortOrder {

    ORDER_BY_DATE(MoviesTable.COLUMN_DATE), 
    ORDER_BY_RATING(MoviesTable.COLUMN_RATING + " DESC"),
    ORDER_BY_TITLE(MoviesTable.COLUMN_TITLE);

    private String orderBy;

    /**
     * Creates a new enum that has a string to order by
     * 
     * @param orderBy
     */
    SortOrder(String orderBy) {
      this.orderBy = orderBy;
    }

    /**
     * Return the string to order by
     * 
     * @return the string to order by
     */
    public String getOrderBy() {
      return orderBy;
    }
  }

  private static final int LOADER_ID = 0;

  private AsyncTask<String, Void, Bitmap> imageTask;

  private static final long MISSING_TAGID = -1;
  private Long tagId;

  /**
   * Has the current sort order
   */
  private static int sortOrder;
  private String query;
  
  private MenuItem mailItem;
  private MenuItem sortItem;
  private MenuItem searchItem;
  
  /**
   * Creates a new MovieListFragment with the Uri
   * WatchMeContentProvider.CONTENT_URI_MOVIES
   */
  public MovieListFragment() {
    super(WatchMeContentProvider.CONTENT_URI_MOVIES);
  }

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    final File cacheDir = getActivity().getBaseContext().getCacheDir();
    ResponseCache.setDefault(new ImageCache(cacheDir));

    /*
     * If any arguments were set, fetch the values
     */
    Bundle arguments = getArguments();
    if (arguments != null) {
      query = arguments.getString(getString(R.string.search), null);
      tagId = arguments.getLong(TagListFragment.TAG_ID, MISSING_TAGID);
    } else if (tagId == null) {
      tagId = MISSING_TAGID;
    }

    setUpAdapter();

    // Set up listeners to delete and view a movie
    this.getListView().setOnItemClickListener(new OnDetailsListener());
    this.getListView().setOnItemLongClickListener(new OnDeleteListener());
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {

    return inflater.inflate(R.layout.movie_list_fragment_view, container,
        false);
  }
  
  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    
    mailItem = menu.findItem(R.id.menu_send_email_button);
    sortItem = menu.findItem(R.id.menu_sort_button);
    searchItem = menu.findItem(R.id.menu_search_button);

    setButtonsState();

    super.onCreateOptionsMenu(menu, inflater);
  }
  
  private void setButtonsState() {
    boolean existMovies = (db.getMovieCount() == 0);
    
    // If there are no movies make the mail, search and sort buttons disabled
    mailItem.setEnabled(!existMovies);
    sortItem.setEnabled(!existMovies);
    searchItem.setEnabled(!existMovies);
    
    MenuUtils.setMenuIconState(mailItem);
    MenuUtils.setMenuIconState(sortItem);
    MenuUtils.setMenuIconState(searchItem);
  }

  @Override
  public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {

    return new GenericCursorLoader(getActivity(), new ICursorHelper() {

      @Override
      public Uri getUri() {
        return MovieListFragment.this.getUri();
      }

      @Override
      public String getSortOrder() {
        return SortOrder.values()[sortOrder].getOrderBy();
      }

      @Override
      public Cursor getCursor() {
        if (tagId == MISSING_TAGID) {
          if (query == null || query.equals("")) {
            return db.getAllMoviesCursor(getSortOrder());
          }
          // If this is presenting a search.
          return db.searchForMovies(query);
        }
        return db.getAttachedMovies(tagId);
      }

    });
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.menu_sort_button:
      sortList();
      break;

    default:
      break;
    }
    return super.onOptionsItemSelected(item);
  }

  /**
   * Show a Dialog Box with choices of attributes to order the Movies by.
   */
  private void sortList() {
    final String[] alternatives = { "Date", "Rating", "Title" };
    
    AlertDialog.Builder alertbox = new AlertDialog.Builder(getActivity());
    alertbox.setTitle(getString(R.string.order_dialog_title));
    alertbox.setSingleChoiceItems(alternatives, sortOrder,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int item) {

            sortOrder = item;
            // Fetch the order by-string from SortOrder
            String orderBy = SortOrder.values()[sortOrder]
                .getOrderBy();

            Cursor cursor = db.getAllMoviesCursor(orderBy);

            // Change the cursor
            onLoadFinished(null, cursor);

            dialog.dismiss();
          }
        });

    alertbox.show();
  }

  /**
   * Listener for when the user clicks an item in the list
   * 
   * The movie object in the list is used to fill a new activity with data
   * 
   * @author Robin
   */
  private class OnDetailsListener implements OnItemClickListener {

    public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {

      /*
       * Cancel any tasks that fetches poster images if a movie is
       * selected
       */
      if (imageTask != null
          && imageTask.getStatus() == AsyncTask.Status.RUNNING) {
        imageTask.cancel(true);
      }

      // Fetch selected movie from database
      Cursor selectedMovie = (Cursor) getListView().getItemAtPosition(
          position);
      Movie movie = db
          .getMovie(Long.parseLong(selectedMovie.getString(0)));

      Intent intent = new Intent(getActivity(),
          MovieDetailsActivity.class);
      intent.putExtra(MovieDetailsActivity.MOVIE_EXTRA, movie);

      // .. and jump to the details view
      startActivity(intent);

    }
  }

  /**
   * The listener for when the user does a long-tap on an item in the list.
   * 
   * The Movie object in the list is removed if the user confirms that he
   * wants to remove the Movie.
   * 
   * @author Johan
   * @author lisastenberg
   */
  private class OnDeleteListener implements OnItemLongClickListener {
    public boolean onItemLongClick(AdapterView<?> parent, View view,
        int position, long id) {

      Cursor selectedMovie = (Cursor) getListView().getItemAtPosition(
          position);
      final Movie movie = db.getMovie(Long.parseLong(selectedMovie
          .getString(0)));

      AlertDialog.Builder alertbox = new AlertDialog.Builder(
          getActivity());
      alertbox.setMessage(getString(R.string.delete_dialog_text) + " \""
          + movie.getTitle() + "\"?");
      alertbox.setPositiveButton(
          getString(R.string.delete_button_positive),
          new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {

              db.removeMovie(movie);

              setButtonsState();
              
              NotificationClient.cancelNotification(
                  getActivity(), movie);
              Toast.makeText(
                  getActivity().getApplicationContext(),
                  "\"" + movie.getTitle() + "\" was deleted",
                  Toast.LENGTH_SHORT).show();

              /*
               * If this MovieListFragment contains all Movies for
               * a specified tag and the tag has no other attached
               * movies, the user is brought back to the main
               * activity.
               */
              if (tagId != MISSING_TAGID
                  && db.getAttachedMovies(tagId).getCount() == 0) {
                NavUtils.navigateUpFromSameTask(getActivity());
              }
            }
          });
      alertbox.setNeutralButton(
          getString(R.string.delete_button_negative),
          new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
              // Nothing should happen if the user press cancel.
            }
          });

      alertbox.show();
      return true;
    }
  }

  /**
   * Set up adapter and set adapter.
   */
  private void setUpAdapter() {

    // Bind columns from the table Movies to items in the rows.
    String[] from = new String[] { MoviesTable.COLUMN_TITLE,
        MoviesTable.COLUMN_RATING, MoviesTable.COLUMN_DATE,
        MoviesTable.COLUMN_POSTER_SMALL };

    int[] to = new int[] { R.id.title, R.id.raiting, R.id.date, R.id.poster };

    getActivity().getSupportLoaderManager().initLoader(LOADER_ID, null,
        this);
    setAdapter(new SimpleCursorAdapter(getActivity(),
        R.layout.list_item_movie, null, from, to, 0));

    /**
     * Manipulate the shown date in list
     */
    getAdapter().setViewBinder(new ViewBinder() {

      public boolean setViewValue(View view, Cursor cursor,
          int columnIndex) {

        if (columnIndex == cursor
            .getColumnIndexOrThrow(MoviesTable.COLUMN_DATE)) {
          
          String dateString = cursor.getString(columnIndex);
          TextView textView = (TextView) view;
          Calendar date = Calendar.getInstance();
          date.setTimeInMillis(Long.parseLong(dateString));
          
          /*
           * If the movie's release date is within a given threshold (fetched 
           * from resource file), change the text color of the field. 
           */
          int threshold = Integer.parseInt(getString(R.string.days_threshold));
          
          if(DateTimeUtils.isDateInInterval(date, threshold, TimeUnit.DAYS)) {
            String color = getString(R.string.color_threshold);
            textView.setTextColor(Color.parseColor(color));
          }
          /*
           * Set to original color if not in threshold
           */
          else {
            textView.setTextColor(R.string.list_date_color);
          }
          
          
          // Format the date to relative form ("two days left")
          String formattedDate = DateTimeUtils.toHumanDate(date);
          textView.setText(formattedDate);

          return true;
        }

        /*
         * Handle rating bar conversion
         */
        else if (columnIndex == cursor
            .getColumnIndexOrThrow(MoviesTable.COLUMN_RATING)) {
          int rating = cursor.getInt(columnIndex);
          RatingBar bar = (RatingBar) view;
          bar.setRating(rating);

          return true;
        }

        /*
         * Handle poster images
         */

        else if (columnIndex == cursor
            .getColumnIndexOrThrow(MoviesTable.COLUMN_POSTER_SMALL)) {
          String smallImageUrl = cursor.getString(columnIndex);
          final ImageView imageView = (ImageView) view;

          if (smallImageUrl != null && !smallImageUrl.isEmpty()) {

            // Fetch the image in an async task
            imageTask = new ImageDownloadTask(
                new ImageDownloadTask.TaskActions() {

                  // When task is finished, set the resulting
                  // image on the poster view
                  public void onFinished(Bitmap image) {
                    if (image != null) {
                      ((ImageView) imageView)
                          .setImageBitmap(image);
                    }
                  }
                });

            imageTask.execute(new String[] { smallImageUrl });
          }

          return true;
        }

        return false;
      }
    });
  }

  public long getTagId() {
    return tagId;
  }
}




Java Source Code List

se.chalmers.watchme.activity.AddMovieActivity.java
se.chalmers.watchme.activity.AutoCompleteAdapter.java
se.chalmers.watchme.activity.MainActivity.java
se.chalmers.watchme.activity.MovieDetailsActivity.java
se.chalmers.watchme.activity.SearchableActivity.java
se.chalmers.watchme.activity.TabsAdapter.java
se.chalmers.watchme.activity.TagMovieListActivity.java
se.chalmers.watchme.database.DatabaseAdapter.java
se.chalmers.watchme.database.DatabaseHelper.java
se.chalmers.watchme.database.GenericCursorLoader.java
se.chalmers.watchme.database.HasTagTable.java
se.chalmers.watchme.database.ICursorHelper.java
se.chalmers.watchme.database.MovieAlreadyExistsException.java
se.chalmers.watchme.database.MoviesTable.java
se.chalmers.watchme.database.TagsTable.java
se.chalmers.watchme.database.WatchMeContentProvider.java
se.chalmers.watchme.model.Movie.java
se.chalmers.watchme.model.Tag.java
se.chalmers.watchme.net.HttpRetriever.java
se.chalmers.watchme.net.IMDBHandler.java
se.chalmers.watchme.net.ImageDownloadTask.java
se.chalmers.watchme.net.MovieSource.java
se.chalmers.watchme.net.NoEntityException.java
se.chalmers.watchme.notifications.Notifiable.java
se.chalmers.watchme.notifications.NotificationClient.java
se.chalmers.watchme.notifications.NotificationService.java
se.chalmers.watchme.notifications.NotifyService.java
se.chalmers.watchme.ui.ContentListFragment.java
se.chalmers.watchme.ui.DatePickerFragment.java
se.chalmers.watchme.ui.ImageDialog.java
se.chalmers.watchme.ui.MovieListFragment.java
se.chalmers.watchme.ui.TagListFragment.java
se.chalmers.watchme.utils.DateTimeUtils.java
se.chalmers.watchme.utils.ImageCache.java
se.chalmers.watchme.utils.MenuUtils.java
se.chalmers.watchme.utils.MovieHelper.java
se.chalmers.watchmetest.Constants.java
se.chalmers.watchmetest.activity.MainActivityTest.java
se.chalmers.watchmetest.activity.MovieDetailsActivityTest.java
se.chalmers.watchmetest.activity.SearchableActivityTest.java
se.chalmers.watchmetest.activity.TabsAdapterTest.java
se.chalmers.watchmetest.activity.TagMovieListActivityTest.java
se.chalmers.watchmetest.database.WatchMeContentProviderTest.java
se.chalmers.watchmetest.model.MovieTest.java
se.chalmers.watchmetest.model.TagTest.java
se.chalmers.watchmetest.net.HttpRetrieverTest.java
se.chalmers.watchmetest.net.IMDBHandlerTest.java
se.chalmers.watchmetest.ui.MovieListFragmentTest.java
se.chalmers.watchmetest.ui.TagListFragmentTest.java
se.chalmers.watchmetest.util.DateTimeUtilsTest.java
se.chalmers.watchmetest.util.MovieHelperTest.java