net.callmeike.android.mojowire.ui.PodcastFragment.java Source code

Java tutorial

Introduction

Here is the source code for net.callmeike.android.mojowire.ui.PodcastFragment.java

Source

/* $Id: $
   Copyright 2012, G. Blake Meike
    
   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 net.callmeike.android.mojowire.ui;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
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.ListView;
import android.widget.SimpleCursorAdapter;

import net.callmeike.android.mojowire.R;
import net.callmeike.android.mojowire.data.PodcastContract;

/**
 *
 * @version $Revision: $
 * @author <a href="mailto:blake.meike@gmail.com">G. Blake Meike</a>
 */
public class PodcastFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
    private static final String TAG = "PODCASTS";

    private static final String STATE_SELECTED_POSITION = "PodcastFragment.DRAWER_POSITION";
    private static final String PREF_USER_LEARNED_DRAWER = "PodcastFragment.DRAWER_USED";

    private static final int PODCAST_TAG = 311;

    private static final String[] PROJ = new String[] { PodcastContract.Podcasts.Columns.ID,
            PodcastContract.Podcasts.Columns.THUMB, PodcastContract.Podcasts.Columns.TITLE };

    private static final String[] FROM = new String[PROJ.length - 1];
    static {
        System.arraycopy(PROJ, 1, FROM, 0, FROM.length);
    }

    private static final int[] TO = new int[] { R.id.podcast_thumb, R.id.podcast_title };

    public static interface PodcastDrawerCallbacks {
        void onPodcastSelected(int id, String title);

        void onAddPodcast();
    }

    private static class PodcastBinder implements SimpleCursorAdapter.ViewBinder {
        public PodcastBinder() {
        }

        @Override
        public boolean setViewValue(View view, Cursor cursor, int i) {
            return R.id.podcast_title != view.getId();
        }
    }

    ActionBarDrawerToggle drawerToggle;

    private DrawerLayout drawerLayout;
    private View fragmentContainerView;

    private PodcastDrawerCallbacks callbacks;

    private ListView podcastsView;

    private boolean drawerHasBeenSeen;
    private boolean fromSavedInstanceState;
    private int currentSelectedPosition;

    public void setDrawerSeen() {
        if (!drawerHasBeenSeen) {
            drawerHasBeenSeen = true;
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
            sp.edit().putBoolean(PodcastFragment.PREF_USER_LEARNED_DRAWER, true).apply();
        }
    }

    /**
     * Users of this fragment must call this method to set up the navigation drawer interactions.
     *
     * @param fragmentId   The android:id of this fragment in its activity's layout.
     * @param layout The DrawerLayout containing this fragment's UI.
     */
    public void setUp(int fragmentId, DrawerLayout layout) {
        drawerLayout = layout;

        drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

        fragmentContainerView = getActivity().findViewById(fragmentId);

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);

        // ActionBarDrawerToggle ties together the the proper interactions
        // between the navigation drawer and the action bar app icon.
        drawerToggle = new PodcastActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer,
                R.string.navigation_drawer_open, R.string.navigation_drawer_close);

        // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
        // per the navigation drawer design guidelines.
        if (!drawerHasBeenSeen && !fromSavedInstanceState) {
            this.drawerLayout.openDrawer(fragmentContainerView);
        }

        // Defer code dependent on restoration of previous instance state.
        this.drawerLayout.post(new Runnable() {
            @Override
            public void run() {
                drawerToggle.syncState();
            }
        });

        this.drawerLayout.setDrawerListener(drawerToggle);
    }

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

        // Read in the flag indicating whether or not the user has demonstrated awareness of the
        // drawer. See PREF_USER_LEARNED_DRAWER for details.
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
        drawerHasBeenSeen = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);

        if (savedInstanceState != null) {
            currentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
            fromSavedInstanceState = true;
        }

        // Select either the default item (0) or the last selected item.
        selectItem(currentSelectedPosition);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        podcastsView = (ListView) inflater.inflate(R.layout.fragment_podcasts, container, false);

        podcastsView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int p, long id) {
                selectItem(p);
            }
        });

        SimpleCursorAdapter adapter = new SimpleCursorAdapter(getActivity(), R.layout.podcast_row, null, FROM, TO,
                0);
        adapter.setViewBinder(new PodcastBinder());
        podcastsView.setAdapter(adapter);

        getLoaderManager().initLoader(PODCAST_TAG, null, this);

        return podcastsView;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            callbacks = (PodcastDrawerCallbacks) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement PodcastDrawerCallbacks.");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callbacks = null;
    }

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

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (drawerLayout != null && isDrawerOpen()) {
            inflater.inflate(R.menu.podcasts, menu);
            showGlobalContextActionBar();
        }
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        if (item.getItemId() == R.id.action_add_podcast) {
            if (callbacks != null) {
                callbacks.onAddPodcast();
            }
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        return new CursorLoader(getActivity(), PodcastContract.Podcasts.URI, PROJ, null, null,
                PodcastContract.Podcasts.Columns.TITLE + " ASC");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        ((SimpleCursorAdapter) podcastsView.getAdapter()).swapCursor(cursor);
        podcastsView.setItemChecked(currentSelectedPosition, true);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
        ((SimpleCursorAdapter) podcastsView.getAdapter()).swapCursor(null);
    }

    public boolean isDrawerOpen() {
        return drawerLayout != null && drawerLayout.isDrawerOpen(fragmentContainerView);
    }

    void selectItem(int position) {
        currentSelectedPosition = position;
        if (null != podcastsView) {
            podcastsView.setItemChecked(position, true);
        }
        if (null != drawerLayout) {
            drawerLayout.closeDrawer(fragmentContainerView);
        }
        if ((0 <= position) && (null != podcastsView) && (null != callbacks)) {
            Cursor c = (Cursor) podcastsView.getItemAtPosition(position);
            callbacks.onPodcastSelected(c.getInt(c.getColumnIndex(PodcastContract.Podcasts.Columns.ID)),
                    c.getString(c.getColumnIndex(PodcastContract.Podcasts.Columns.TITLE)));
        }
    }

    /**
     * Per the navigation drawer design guidelines,
     * updates the action bar to show the global app 'context',
     * rather than just what's in the current screen.
     */
    private void showGlobalContextActionBar() {
        ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setTitle(R.string.app_name);
    }

    private ActionBar getActionBar() {
        return getActivity().getActionBar();
    }
}