An Android ActionBar + ListFragment example

The source code below corresponds to an article I wrote titled, Android ActionBar example: How to create an options menu item.

package com.valleyprogramming.justbe;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
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.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.valleyprogramming.justbe.QuotesDatabaseHelper.QuoteCursor;

public class QuotesListFragment extends ListFragment {

    private static final String TAG = "VPQuotesListFragment";
    private QuoteCursor quoteCursor;

    public void onCreate(Bundle savedInstanceState) {

        // config the database and adapter
        quoteCursor = DatabaseManager.get(getActivity()).queryQuotes();

        // create an adapter to point at this cursor
        QuoteCursorAdapter adapter = new QuoteCursorAdapter(getActivity(), quoteCursor);

    public void onDestroy() {

        //TODO working on possible memory leaks
        quoteCursor = null;

    public void onActivityCreated(Bundle bundle) {
        // get a handle to our list view to implement 'swipe to delete'
        ListView listView = getListView();
        // Create a ListView-specific touch listener. ListViews are given special treatment because
        // by default they handle touches for their list items... i.e. they're in charge of drawing
        // the pressed state (the list selector), handling list item clicks, etc.
        SwipeDismissListViewTouchListener touchListener =
            new SwipeDismissListViewTouchListener(
                new SwipeDismissListViewTouchListener.DismissCallbacks() {
                    public boolean canDismiss(int position) {
                        return true;
                    public void onDismiss(ListView listView, int[] reverseSortedPositions) {
                        for (int position : reverseSortedPositions) {
                            String quoteToDelete = ((QuoteCursor)(getListAdapter()).getItem(position)).getQuote().getQuote();

                            // need the next two lines to update the list after the delete

        // setting this scroll listener is required to ensure that during ListView scrolling,
        // we don't look for swipes.

    private void handleCasesWhereThisQuoteWasTheCurrentlyDisplayedQuote(String quoteThatWasDeleted) {
        if (GlobalState.currentlyDisplayedQuote.equals(quoteThatWasDeleted)) {
            if (GlobalState.pinnedStateEnabled) {
                // the quote that was deleted was the current quote and it was pinned
                GlobalState.currentlyDisplayedQuote = "";
            } else {
                // the quote that was deleted was the current quote but it was not pinned
                GlobalState.currentlyDisplayedQuote = "";

     * When a list item is clicked, perform the 'Edit' action.
    public void onListItemClick(ListView l, View v, int position, long id) {
        String quote = ((QuoteCursor)(getListAdapter()).getItem(position)).getQuote().getQuote();
        Log.d(TAG, quote + " was clicked");

        // i'm doing this in the long form just for my own knowledge
        Context context = getActivity();
        Class destination = EditQuoteActivity.class;
        Intent intent = new Intent(context, destination);
        intent.putExtra(EditQuoteFragment.KEY_QUOTE_EXTRA, quote);
        startActivityForResult(intent, 0);

     * update the list of quotes when the user returns, presumably after
     * using the 'edit' screen. p. 197.
     * the book's code example actually uses onActivityResult instead of
     * onResume. i just tested it, and they both get called, so either one
     * will work.
    public void onResume() {

     * as the code shows, the cursor needs to be refreshed before
     * notifyDataSetChanged is called
    private void refreshQuoteCursorDataSet() {

     * the menu layout has the 'add/new' menu item
    public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
        menuInflater.inflate(, menu);
        super.onCreateOptionsMenu(menu, menuInflater);

     * react to the user tapping/selecting an options menu item
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
                Intent addQuoteIntent = new Intent(getActivity(), NewQuoteActivity.class);
                startActivityForResult(addQuoteIntent, 0);
                return true;
                return super.onOptionsItemSelected(item);

     * The adapter class that will work with the ListView.
    private static class QuoteCursorAdapter extends CursorAdapter {

        private QuoteCursor mRunCursor;

        public QuoteCursorAdapter(Context context, QuoteCursor cursor) {
            super(context, cursor, 0);
            mRunCursor = cursor;

        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            return inflater.inflate(R.layout.quote_item_view, parent, false);

        public void bindView(View view, Context context, Cursor cursor) {
            // get the quote for the current row
            Quote quote = mRunCursor.getQuote();

            // this works with my custom view (quote_item_view.xml)
            TextView textView = (TextView)view.findViewById(;

            // set the text size

            // confirmed: this works. can also specify alpha as '00-ff' before the rgb
            // component, but that won't do anything in this case



The reason I show the code here is because it shows how to enable the Android ActionBar, in this case from a Fragment, and more specifically a ListFragment.