Add compatibility library.

Have TrackListActivity extends FragmentActivity
Use Loader to load cursor.
Use DialogFragment to display dialogs.
This commit is contained in:
Jimmy Shih
2012-03-27 13:42:45 -07:00
parent 30b0348655
commit 6afa67acad
3 changed files with 105 additions and 69 deletions
+1
View File
@@ -13,6 +13,7 @@
<classpathentry kind="lib" path="libs/google-api-client/guava-r09.jar"/> <classpathentry kind="lib" path="libs/google-api-client/guava-r09.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/jackson-core-asl-1.6.7.jar"/> <classpathentry kind="lib" path="libs/google-api-client/jackson-core-asl-1.6.7.jar"/>
<classpathentry kind="lib" path="libs/google-api-client/jsr305-1.3.9.jar"/> <classpathentry kind="lib" path="libs/google-api-client/jsr305-1.3.9.jar"/>
<classpathentry kind="lib" path="libs/android-support-v4.jar"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/> <classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/> <classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/>
Binary file not shown.
@@ -27,7 +27,6 @@ import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
@@ -38,6 +37,12 @@ import android.content.SharedPreferences.Editor;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.ResourceCursorAdapter;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
@@ -46,24 +51,31 @@ import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView; import android.widget.ListView;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
/** /**
* An activity displaying a list of tracks. * An activity displaying a list of tracks.
* *
* @author Leif Hendrik Wilden * @author Leif Hendrik Wilden
*/ */
public class TrackListActivity extends Activity { public class TrackListActivity extends FragmentActivity {
private static final String TAG = TrackListActivity.class.getSimpleName(); private static final String TAG = TrackListActivity.class.getSimpleName();
private static final int DIALOG_EXPORT_ALL_ID = 0; private static final String EXPORT_ALL_DIALOG_TAG = "exportAllDialog";
private static final int DIALOG_DELETE_ALL_ID = 1; private static final String DELETE_ALL_DIALOG_TAG = "deleteAllDialog";
private static final String[] PROJECTION = new String[] {
TracksColumns._ID,
TracksColumns.NAME,
TracksColumns.CATEGORY,
TracksColumns.TOTALTIME,
TracksColumns.TOTALDISTANCE,
TracksColumns.STARTTIME,
TracksColumns.DESCRIPTION };
// Callback when the trackRecordingServiceConnection binding changes // Callback when the trackRecordingServiceConnection binding changes
private final Runnable bindChangedCallback = new Runnable() { private final Runnable bindChangedCallback = new Runnable() {
@Override @Override
public void run() { public void run() {
synchronized (trackRecordingServiceConnection) { synchronized (trackRecordingServiceConnection) {
if (startNewRecording) { if (startNewRecording) {
@@ -122,10 +134,6 @@ public class TrackListActivity extends Activity {
metricUnits = sharedPreferences.getBoolean(getString(R.string.metric_units_key), true); metricUnits = sharedPreferences.getBoolean(getString(R.string.metric_units_key), true);
recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L); recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
Cursor trackCursor = myTracksProviderUtils.getTracksCursor(
null, null, TracksColumns._ID + " DESC");
startManagingCursor(trackCursor);
listView = (ListView) findViewById(R.id.track_list); listView = (ListView) findViewById(R.id.track_list);
listView.setOnItemClickListener(new OnItemClickListener() { listView.setOnItemClickListener(new OnItemClickListener() {
@Override @Override
@@ -134,7 +142,7 @@ public class TrackListActivity extends Activity {
finish(); finish();
} }
}); });
adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, trackCursor, true) { adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, null, 0) {
@Override @Override
public void bindView(View view, Context context, Cursor cursor) { public void bindView(View view, Context context, Cursor cursor) {
int idIndex = cursor.getColumnIndex(TracksColumns._ID); int idIndex = cursor.getColumnIndex(TracksColumns._ID);
@@ -146,7 +154,7 @@ public class TrackListActivity extends Activity {
int descriptionIndex = cursor.getColumnIndex(TracksColumns.DESCRIPTION); int descriptionIndex = cursor.getColumnIndex(TracksColumns.DESCRIPTION);
boolean isRecording = cursor.getLong(idIndex) == recordingTrackId; boolean isRecording = cursor.getLong(idIndex) == recordingTrackId;
TextView name = (TextView) view.findViewById(R.id.track_list_item_name); TextView name = (TextView) view.findViewById(R.id.track_list_item_name);
name.setText(cursor.getString(nameIndex)); name.setText(cursor.getString(nameIndex));
name.setCompoundDrawablesWithIntrinsicBounds( name.setCompoundDrawablesWithIntrinsicBounds(
@@ -163,7 +171,7 @@ public class TrackListActivity extends Activity {
distance.setText(StringUtils.formatDistance( distance.setText(StringUtils.formatDistance(
TrackListActivity.this, cursor.getDouble(distanceIndex), metricUnits)); TrackListActivity.this, cursor.getDouble(distanceIndex), metricUnits));
distance.setVisibility(isRecording ? View.GONE : View.VISIBLE); distance.setVisibility(isRecording ? View.GONE : View.VISIBLE);
TextView start = (TextView) view.findViewById(R.id.track_list_item_start); TextView start = (TextView) view.findViewById(R.id.track_list_item_start);
start.setText( start.setText(
StringUtils.formatDateTime(TrackListActivity.this, cursor.getLong(startIndex))); StringUtils.formatDateTime(TrackListActivity.this, cursor.getLong(startIndex)));
@@ -175,6 +183,28 @@ public class TrackListActivity extends Activity {
} }
}; };
listView.setAdapter(adapter); listView.setAdapter(adapter);
getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(TrackListActivity.this,
TracksColumns.CONTENT_URI,
PROJECTION,
null,
null,
TracksColumns._ID + " DESC");
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
});
} }
@Override @Override
@@ -192,15 +222,15 @@ public class TrackListActivity extends Activity {
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.track_list, menu); getMenuInflater().inflate(R.menu.track_list, menu);
recordTrack = menu.findItem(R.id.menu_record_track); recordTrack = menu.findItem(R.id.menu_record_track);
stopRecording = menu.findItem(R.id.menu_stop_recording); stopRecording = menu.findItem(R.id.menu_stop_recording);
search = menu.findItem(R.id.menu_search); search = menu.findItem(R.id.menu_search);
importAll = menu.findItem(R.id.menu_import_all); importAll = menu.findItem(R.id.menu_import_all);
exportAll = menu.findItem(R.id.menu_export_all); exportAll = menu.findItem(R.id.menu_export_all);
deleteAll = menu.findItem(R.id.menu_delete_all); deleteAll = menu.findItem(R.id.menu_delete_all);
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, search); ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, search);
updateMenu(); updateMenu();
return true; return true;
} }
@@ -216,7 +246,7 @@ public class TrackListActivity extends Activity {
/** /**
* Updates the menu items. * Updates the menu items.
* *
* @param isRecording true if recording * @param isRecording true if recording
*/ */
private void updateMenuItems(boolean isRecording) { private void updateMenuItems(boolean isRecording) {
@@ -263,14 +293,14 @@ public class TrackListActivity extends Activity {
case R.id.menu_search: case R.id.menu_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this); return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
case R.id.menu_import_all: case R.id.menu_import_all:
startActivity(new Intent(this, ImportActivity.class) startActivity(
.putExtra(ImportActivity.EXTRA_IMPORT_ALL, true)); new Intent(this, ImportActivity.class).putExtra(ImportActivity.EXTRA_IMPORT_ALL, true));
return true; return true;
case R.id.menu_export_all: case R.id.menu_export_all:
showDialog(DIALOG_EXPORT_ALL_ID); new ExportAllDialogFragment().show(getSupportFragmentManager(), EXPORT_ALL_DIALOG_TAG);
return true; return true;
case R.id.menu_delete_all: case R.id.menu_delete_all:
showDialog(DIALOG_DELETE_ALL_ID); new DeleteAllDialogFragment().show(getSupportFragmentManager(), DELETE_ALL_DIALOG_TAG);
return true; return true;
case R.id.menu_aggregated_statistics: case R.id.menu_aggregated_statistics:
startActivity(new Intent(this, AggregatedStatsActivity.class)); startActivity(new Intent(this, AggregatedStatsActivity.class));
@@ -331,58 +361,63 @@ public class TrackListActivity extends Activity {
} }
} }
@Override /**
protected Dialog onCreateDialog(int id) { * Export All DialogFragment.
switch (id) { */
case DIALOG_EXPORT_ALL_ID: private static class ExportAllDialogFragment extends DialogFragment {
return createExportAllDialog();
case DIALOG_DELETE_ALL_ID: @Override
return DialogUtils.createConfirmationDialog(this, public Dialog onCreateDialog(Bundle savedInstanceState) {
R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() { String exportFileFormat = getString(R.string.track_list_export_file);
@Override String fileTypes[] = getResources().getStringArray(R.array.file_types);
public void onClick(DialogInterface dialog, int which) { String[] choices = new String[fileTypes.length];
MyTracksProviderUtils.Factory.get(TrackListActivity.this).deleteAllTracks(); for (int i = 0; i < fileTypes.length; i++) {
/* choices[i] = String.format(exportFileFormat, fileTypes[i]);
* TODO Verify that selected_track_key is still needed with the }
* ICS navigation design return new AlertDialog.Builder(getActivity()).setNegativeButton(R.string.generic_cancel, null)
*/ .setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
Editor editor = sharedPreferences.edit(); @Override
// TODO: Go through data manager public void onClick(DialogInterface dialog, int which) {
editor.putLong(getString(R.string.selected_track_key), -1L); int index = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); Intent intent = new Intent(getActivity(), ExportActivity.class).putExtra(
} ExportActivity.EXTRA_TRACK_FILE_FORMAT,
}); (Parcelable) TrackFileFormat.values()[index]);
default: getActivity().startActivity(intent);
return null; }
})
.setSingleChoiceItems(choices, 0, null)
.setTitle(R.string.menu_export_all)
.create();
} }
} };
/** /**
* Creates an export all dialog. * Delete All DialogFragment.
*/ */
private AlertDialog createExportAllDialog() { private static class DeleteAllDialogFragment extends DialogFragment {
String exportFileFormat = getString(R.string.track_list_export_file);
String fileTypes[] = getResources().getStringArray(R.array.file_types); @Override
String[] choices = new String[fileTypes.length]; public Dialog onCreateDialog(Bundle savedInstanceState) {
for (int i = 0; i < fileTypes.length; i++) { return DialogUtils.createConfirmationDialog(getActivity(),
choices[i] = String.format(exportFileFormat, fileTypes[i]); R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
MyTracksProviderUtils.Factory.get(getActivity()).deleteAllTracks();
/*
* TODO Verify that selected_track_key is still needed with the
* ICS navigation design
*/
SharedPreferences sharedPreferences = getActivity()
.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
// TODO: Go through data manager
editor.putLong(getString(R.string.selected_track_key), -1L);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
}
});
} }
return new AlertDialog.Builder(this).setNegativeButton(R.string.generic_cancel, null) };
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int index = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
Intent intent = new Intent(TrackListActivity.this, ExportActivity.class).putExtra(
ExportActivity.EXTRA_TRACK_FILE_FORMAT,
(Parcelable) TrackFileFormat.values()[index]);
TrackListActivity.this.startActivity(intent);
}
})
.setSingleChoiceItems(choices, 0, null)
.setTitle(R.string.track_list_export_all)
.create();
}
@Override @Override
public boolean onKeyUp(int keyCode, KeyEvent event) { public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_SEARCH) { if (keyCode == KeyEvent.KEYCODE_SEARCH) {