Java tutorial
/* * Copyright (C) 2013 Dominik Schrmann <dominik@dominikschuermann.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.thialfihar.android.apg.ui; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.provider.KeychainContract; import org.thialfihar.android.apg.provider.KeychainContract.KeyRings; import org.thialfihar.android.apg.provider.KeychainContract.UserIds; import org.thialfihar.android.apg.ui.adapter.KeyListSecretAdapter; import org.thialfihar.android.apg.ui.dialog.DeleteKeyDialogFragment; import java.util.Set; public class KeyListSecretFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener { private KeyListSecretActivity mKeyListSecretActivity; private KeyListSecretAdapter mAdapter; /** * Define Adapter and Loader on create of Activity */ @SuppressLint("NewApi") @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mKeyListSecretActivity = (KeyListSecretActivity) getActivity(); getListView().setOnItemClickListener(this); // Give some text to display if there is no data. In a real // application this would come from a resource. setEmptyText(getString(R.string.list_empty)); /* * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only * available for Android >= 3.0 */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { android.view.MenuInflater inflater = getActivity().getMenuInflater(); inflater.inflate(R.menu.key_list_secret_multi, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { Set<Integer> positions = mAdapter.getCurrentCheckedPosition(); // get IDs for checked positions as long array long[] ids = new long[positions.size()]; int i = 0; for (int pos : positions) { ids[i] = mAdapter.getItemId(pos); i++; } switch (item.getItemId()) { case R.id.menu_key_list_public_multi_delete: { showDeleteKeyDialog(mode, ids); break; } case R.id.menu_key_list_public_multi_select_all: { // select all int localCount = getListView().getCount(); for (int k = 0; k < localCount; k++) { getListView().setItemChecked(k, true); } break; } } return true; } @Override public void onDestroyActionMode(ActionMode mode) { mAdapter.clearSelection(); } @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { if (checked) { mAdapter.setNewSelection(position, checked); } else { mAdapter.removeSelection(position); } int count = getListView().getCheckedItemCount(); String keysSelected = getResources().getQuantityString(R.plurals.key_list_selected_keys, count, count); mode.setTitle(keysSelected); } }); } // We have a menu item to show in action bar. setHasOptionsMenu(true); // Start out with a progress indicator. setListShown(false); // Create an empty adapter we will use to display the loaded data. mAdapter = new KeyListSecretAdapter(mKeyListSecretActivity, null, 0); setListAdapter(mAdapter); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this); } // These are the rows that we will retrieve. static final String[] PROJECTION = new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID, UserIds.USER_ID }; static final String SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC"; public Loader<Cursor> onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. // First, pick the base URI to use depending on whether we are // currently filtering. Uri baseUri = KeyRings.buildSecretKeyRingsUri(); // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, SORT_ORDER); } public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); // The list should now be shown. if (isResumed()) { setListShown(true); } else { setListShownNoAnimation(true); } } public void onLoaderReset(Loader<Cursor> loader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); } /** * On click on item, start key view activity */ @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { Intent editIntent = new Intent(mKeyListSecretActivity, EditKeyActivity.class); editIntent.setData(KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(id))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); } /** * Show dialog to delete key * * @param keyRingRowIds */ @TargetApi(11) public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) { // Message is received after key is deleted Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { mode.finish(); } } }; // Create a new Messenger for the communication back Messenger messenger = new Messenger(returnHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, keyRingRowIds, Id.type.secret_key); deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); } }