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.app.ListFragment; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Color; 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; import com.example.android.swipedismiss.SwipeDismissListViewTouchListener; public class QuotesListFragment extends ListFragment { private static final String TAG = "VPQuotesListFragment"; private QuoteCursor quoteCursor; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); getActivity().setTitle(R.string.title_quotes_screen); // config the database and adapter quoteCursor = DatabaseManager.get(getActivity()).queryQuotes(); // create an adapter to point at this cursor QuoteCursorAdapter adapter = new QuoteCursorAdapter(getActivity(), quoteCursor); setListAdapter(adapter); } @Override public void onDestroy() { quoteCursor.close(); //TODO working on possible memory leaks quoteCursor = null; setListAdapter(null); super.onDestroy(); } @Override public void onActivityCreated(Bundle bundle) { super.onActivityCreated(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( listView, new SwipeDismissListViewTouchListener.DismissCallbacks() { @Override public boolean canDismiss(int position) { return true; } @Override public void onDismiss(ListView listView, int[] reverseSortedPositions) { for (int position : reverseSortedPositions) { String quoteToDelete = ((QuoteCursor)(getListAdapter()).getItem(position)).getQuote().getQuote(); DatabaseManager.get(getActivity()).deleteQuote(quoteToDelete); // need the next two lines to update the list after the delete refreshQuoteCursorDataSet(); handleCasesWhereThisQuoteWasTheCurrentlyDisplayedQuote(quoteToDelete); } } }); listView.setOnTouchListener(touchListener); // setting this scroll listener is required to ensure that during ListView scrolling, // we don't look for swipes. listView.setOnScrollListener(touchListener.makeScrollListener()); } 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 PreferencesUtils.handleUserUnpinsQuoteAction(getActivity().getBaseContext()); 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. */ @Override 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. */ @Override public void onResume() { super.onResume(); refreshQuoteCursorDataSet(); } /** * as the code shows, the cursor needs to be refreshed before * notifyDataSetChanged is called */ private void refreshQuoteCursorDataSet() { quoteCursor.requery(); ((QuoteCursorAdapter)getListAdapter()).notifyDataSetChanged(); } /** * the menu layout has the 'add/new' menu item */ @Override public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { menuInflater.inflate(R.menu.menu_quotes_list, menu); super.onCreateOptionsMenu(menu, menuInflater); } /** * react to the user tapping/selecting an options menu item */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_item_new_quote: Intent addQuoteIntent = new Intent(getActivity(), NewQuoteActivity.class); startActivityForResult(addQuoteIntent, 0); return true; default: 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; } @Override 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); } @Override 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(R.id.the_quote); textView.setText(quote.getQuote()); // set the text size textView.setTextAppearance(context, R.style.listViewText); // confirmed: this works. can also specify alpha as '00-ff' before the rgb // component, but that won't do anything in this case textView.setBackgroundColor(Color.parseColor("#ffffff")); } } }
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
.