Rewrite MotorBrowser to use a fragment for the list. This is the first step in making this portion of the application look and operate better on tables.
This commit is contained in:
parent
b5d7143803
commit
d8d9f499b7
@ -71,8 +71,8 @@
|
||||
<category android:name="android.intent.category.PREFERENCE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".android.motor.MotorHierarchicalBrowser" />
|
||||
<activity android:name=".android.motor.MotorDetails" />
|
||||
<activity android:name=".android.motor.MotorBrowserActivity" />
|
||||
<activity android:name=".android.motor.MotorDetailsActivity" />
|
||||
<activity android:name=".android.thrustcurve.TCQueryActivity" />
|
||||
<activity android:name=".android.simulation.SimulationViewActivity" />
|
||||
<activity android:name=".android.filebrowser.SimpleFileBrowser" />
|
||||
|
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<ExpandableListView
|
||||
android:id="@+id/motorListView"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" >
|
||||
</ExpandableListView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="No motors" />
|
||||
|
||||
</LinearLayout>
|
@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:title="Download from ThrustCurve" android:id="@+id/download_from_thrustcurve_menu_option"/>
|
||||
<item android:title="Preferences" android:id="@+id/preference_menu_option"/>
|
||||
</menu>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item
|
||||
android:id="@+id/download_from_thrustcurve_menu_option"
|
||||
android:title="Download from ThrustCurve"/>
|
||||
<item
|
||||
android:id="@+id/preference_menu_option"
|
||||
android:icon="@drawable/ic_menu_preferences"
|
||||
android:title="@string/Preferences"/>
|
||||
|
||||
</menu>
|
@ -1,6 +1,7 @@
|
||||
package net.sf.openrocket.android;
|
||||
|
||||
import net.sf.openrocket.android.motor.MotorHierarchicalBrowser;
|
||||
import net.sf.openrocket.android.motor.MotorBrowserActivity;
|
||||
import net.sf.openrocket.android.thrustcurve.TCQueryActivity;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
||||
@ -8,14 +9,18 @@ public abstract class ActivityHelpers {
|
||||
|
||||
|
||||
public static void browseMotors( Activity parent ) {
|
||||
Intent i = new Intent(parent, MotorHierarchicalBrowser.class);
|
||||
Intent i = new Intent(parent, MotorBrowserActivity.class);
|
||||
parent.startActivity(i);
|
||||
|
||||
}
|
||||
|
||||
public static void startPreferences( Activity parent ) {
|
||||
Intent intent = new Intent(parent, PreferencesActivity.class);
|
||||
parent.startActivity(intent);
|
||||
|
||||
}
|
||||
|
||||
public static void downloadFromThrustcurve( Activity parent ) {
|
||||
Intent i = new Intent(parent, TCQueryActivity.class);
|
||||
parent.startActivity(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import java.io.ObjectOutputStream;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
abstract class ConversionUtils {
|
||||
public abstract class ConversionUtils {
|
||||
|
||||
static double[] stringToDelays( String value ) {
|
||||
if (value == null || "".equals(value) ) {
|
||||
@ -28,7 +28,7 @@ abstract class ConversionUtils {
|
||||
return values;
|
||||
}
|
||||
|
||||
static String delaysToString( double[] delays ) {
|
||||
public static String delaysToString( double[] delays ) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
boolean first = true;
|
||||
for( double d:delays ) {
|
||||
|
@ -0,0 +1,91 @@
|
||||
package net.sf.openrocket.android.motor;
|
||||
|
||||
import net.sf.openrocket.R;
|
||||
import net.sf.openrocket.android.ActivityHelpers;
|
||||
import net.sf.openrocket.android.PreferencesActivity;
|
||||
import net.sf.openrocket.android.simulation.SimulationChart;
|
||||
import net.sf.openrocket.android.simulation.SimulationFragment;
|
||||
import net.sf.openrocket.android.simulation.SimulationViewActivity;
|
||||
import net.sf.openrocket.android.thrustcurve.TCQueryActivity;
|
||||
import net.sf.openrocket.android.util.AndroidLogWrapper;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
public class MotorBrowserActivity extends FragmentActivity
|
||||
implements MotorListFragment.OnMotorSelectedListener
|
||||
{
|
||||
|
||||
MotorListFragment motorList;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
|
||||
motorList = MotorListFragment.newInstance();
|
||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
ft.add(android.R.id.content, motorList);
|
||||
ft.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.motor_browser_option_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
AndroidLogWrapper.d(MotorBrowserActivity.class,"onMenuItemSelected" + item.getItemId());
|
||||
switch(item.getItemId()) {
|
||||
case R.id.download_from_thrustcurve_menu_option:
|
||||
ActivityHelpers.downloadFromThrustcurve(this);
|
||||
return true;
|
||||
case R.id.preference_menu_option:
|
||||
Intent intent = new Intent().setClass(this, PreferencesActivity.class);
|
||||
this.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
return super.onMenuItemSelected(featureId, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotorSelected(long motorId) {
|
||||
|
||||
View sidepane = findViewById(R.id.sidepane);
|
||||
if ( /* if multi pane */ sidepane != null ) {
|
||||
/*
|
||||
Simulation sim = app.getRocketDocument().getSimulation(simulationId);
|
||||
SimulationChart chart = new SimulationChart(simulationId);
|
||||
|
||||
Fragment graph = SimulationFragment.newInstance(chart);
|
||||
|
||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
|
||||
// probably only want to update back stack for first time.
|
||||
ft.addToBackStack("simulationplot");
|
||||
ft.replace(R.id.sidepane, graph);
|
||||
ft.show(graph);
|
||||
ft.commit();
|
||||
*/
|
||||
|
||||
} else {
|
||||
Intent i = new Intent(this,MotorDetailsActivity.class);
|
||||
i.putExtra("Motor", motorId);
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ import android.view.MenuItem;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SlidingDrawer;
|
||||
|
||||
public class MotorDetails extends FragmentActivity
|
||||
public class MotorDetailsActivity extends FragmentActivity
|
||||
implements SlidingDrawer.OnDrawerCloseListener, SlidingDrawer.OnDrawerOpenListener {
|
||||
|
||||
private final static String TAG = "MotorDetails";
|
@ -1,8 +1,7 @@
|
||||
package net.sf.openrocket.android.motor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.sf.openrocket.R;
|
||||
import net.sf.openrocket.android.db.ConversionUtils;
|
||||
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
@ -39,7 +38,7 @@ public class MotorDetailsFragment extends Fragment {
|
||||
ThrustCurveMotor tcm = m.getThrustCurveMotor();
|
||||
manuField.setText( tcm.getManufacturer().getDisplayName());
|
||||
nameField.setText( tcm.getDesignation() );
|
||||
delaysField.setText( Arrays.toString(tcm.getStandardDelays()) );
|
||||
delaysField.setText( ConversionUtils.delaysToString(tcm.getStandardDelays()) );
|
||||
caseField.setText( m.getCaseInfo());
|
||||
impulseClassField.setText( m.getImpulseClass());
|
||||
diameterField.setText( String.valueOf(tcm.getDiameter()*1000.0) );
|
||||
|
@ -1,10 +1,12 @@
|
||||
package net.sf.openrocket.android.motor;
|
||||
|
||||
import net.sf.openrocket.R;
|
||||
import net.sf.openrocket.android.PreferencesActivity;
|
||||
import net.sf.openrocket.android.db.DbAdapter;
|
||||
import net.sf.openrocket.android.db.MotorDao;
|
||||
import net.sf.openrocket.android.thrustcurve.TCQueryActivity;
|
||||
import net.sf.openrocket.android.util.AndroidLogWrapper;
|
||||
import net.sf.openrocket.android.util.PersistentExpandableListFragment;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -12,11 +14,9 @@ import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.CursorTreeAdapter;
|
||||
@ -25,14 +25,23 @@ import android.widget.ResourceCursorTreeAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
public class MotorHierarchicalBrowser
|
||||
extends PersistentExpandableListActivity
|
||||
/*
|
||||
* TODO - make this work with PersistentExpandableListFragment.
|
||||
*
|
||||
*/
|
||||
public class MotorListFragment extends PersistentExpandableListFragment
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
{
|
||||
private static final String TAG = "MotorHierarchicalBrowser";
|
||||
|
||||
private static final int ACTIVITY_DOWNLOAD=0;
|
||||
|
||||
public interface OnMotorSelectedListener {
|
||||
public void onMotorSelected( long motorId );
|
||||
}
|
||||
|
||||
public static MotorListFragment newInstance( ) {
|
||||
|
||||
MotorListFragment frag = new MotorListFragment();
|
||||
return frag;
|
||||
}
|
||||
|
||||
private static final int CONTEXTMENU_DELETE = Menu.FIRST+1;
|
||||
|
||||
private String groupColumnPreferenceKey;
|
||||
@ -48,6 +57,13 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
private CursorTreeAdapter mAdapter;
|
||||
|
||||
private DbAdapter mDbHelper;
|
||||
|
||||
private OnMotorSelectedListener motorSelectedListener;
|
||||
|
||||
public void setMotorSelectedListener(
|
||||
OnMotorSelectedListener motorSelectedListener) {
|
||||
this.motorSelectedListener = motorSelectedListener;
|
||||
}
|
||||
|
||||
public class MotorHierarchicalListAdapter extends ResourceCursorTreeAdapter
|
||||
{
|
||||
@ -62,12 +78,12 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
|
||||
@Override
|
||||
protected Cursor getChildrenCursor(Cursor arg0) {
|
||||
Log.d(TAG,"getChildrenCursor");
|
||||
AndroidLogWrapper.d(MotorListFragment.class,"getChildrenCursor");
|
||||
String group = arg0.getString(arg0.getColumnIndex(groupColumn));
|
||||
Log.d(TAG," for: "+ groupColumn + " = " + group);
|
||||
AndroidLogWrapper.d(MotorListFragment.class," for: "+ groupColumn + " = " + group);
|
||||
Cursor c = mDbHelper.getMotorDao().fetchAllInGroups(groupColumn,group);
|
||||
Log.d(TAG," got cursor");
|
||||
startManagingCursor(c);
|
||||
AndroidLogWrapper.d(MotorListFragment.class," got cursor");
|
||||
getActivity().startManagingCursor(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -111,8 +127,6 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -124,20 +138,8 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mDbHelper = new DbAdapter(this);
|
||||
mDbHelper.open();
|
||||
|
||||
Resources resources = this.getResources();
|
||||
groupColumnPreferenceKey = resources.getString(R.string.PreferenceMotorBrowserGroupingOption);
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
setGroupColumnFromPreferences(pref);
|
||||
|
||||
pref.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
refreshData();
|
||||
|
||||
registerForContextMenu(getExpandableListView());
|
||||
@ -145,37 +147,29 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.motor_browser_option_menu, menu);
|
||||
return true;
|
||||
}
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
mDbHelper = new DbAdapter(getActivity());
|
||||
mDbHelper.open();
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
Log.d(TAG,"onMenuItemSelected" + item.getItemId());
|
||||
switch(item.getItemId()) {
|
||||
case R.id.download_from_thrustcurve_menu_option:
|
||||
tcDownload();
|
||||
return true;
|
||||
case R.id.preference_menu_option:
|
||||
Intent intent = new Intent().setClass(this, PreferencesActivity.class);
|
||||
this.startActivity(intent);
|
||||
return true;
|
||||
Resources resources = this.getResources();
|
||||
groupColumnPreferenceKey = resources.getString(R.string.PreferenceMotorBrowserGroupingOption);
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
setGroupColumnFromPreferences(pref);
|
||||
|
||||
pref.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
if ( activity instanceof OnMotorSelectedListener ) {
|
||||
motorSelectedListener = (OnMotorSelectedListener) activity;
|
||||
}
|
||||
return super.onMenuItemSelected(featureId, item);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
Log.d(TAG,"onCreateContextMenu " + menuInfo);
|
||||
Log.d(TAG, "v.getId() = " + v.getId());
|
||||
Log.d(TAG, "motorListView = " + R.id.motorListView);
|
||||
// if (v.getId() == R.id.motorListView) {
|
||||
ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
|
||||
menu.setHeaderTitle("context menu");
|
||||
menu.setHeaderTitle("Motor Operations");
|
||||
menu.add(Menu.NONE,CONTEXTMENU_DELETE,CONTEXTMENU_DELETE,"Delete");
|
||||
// }
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
}
|
||||
|
||||
@ -183,7 +177,7 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) item.getMenuInfo();
|
||||
long motorId = info.id;
|
||||
Log.d(TAG,"ContextMenu: " + motorId);
|
||||
AndroidLogWrapper.d(MotorListFragment.class,"ContextMenu: " + motorId);
|
||||
switch(item.getItemId()) {
|
||||
case CONTEXTMENU_DELETE:
|
||||
mDbHelper.getMotorDao().deleteMotor(motorId);
|
||||
@ -193,28 +187,20 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
refreshData();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
|
||||
super.onChildClick(parent, v, groupPosition, childPosition, id);
|
||||
//Intent i = new Intent(this, BurnPlotActivity.class);
|
||||
Intent i = new Intent(this,MotorDetails.class);
|
||||
i.putExtra("Motor", id);
|
||||
startActivity(i);
|
||||
if( motorSelectedListener != null ) {
|
||||
motorSelectedListener.onMotorSelected(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
pref.unregisterOnSharedPreferenceChangeListener(this);
|
||||
|
||||
// Null out the group cursor. This will cause the group cursor and all of the child cursors
|
||||
@ -225,11 +211,6 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
mDbHelper.close();
|
||||
}
|
||||
|
||||
private void tcDownload() {
|
||||
Intent i = new Intent(this, TCQueryActivity.class);
|
||||
startActivityForResult(i, ACTIVITY_DOWNLOAD);
|
||||
}
|
||||
|
||||
private void setGroupColumnFromPreferences( SharedPreferences prefs ) {
|
||||
String indexStr = prefs.getString(groupColumnPreferenceKey, "1");
|
||||
int index;
|
||||
@ -250,10 +231,10 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
mAdapter.changeCursor(null);
|
||||
}
|
||||
Cursor motorCursor = mDbHelper.getMotorDao().fetchGroups(groupColumn);
|
||||
startManagingCursor(motorCursor);
|
||||
getActivity().startManagingCursor(motorCursor);
|
||||
// Set up our adapter
|
||||
mAdapter = new MotorHierarchicalListAdapter(
|
||||
this,
|
||||
getActivity(),
|
||||
motorCursor,
|
||||
R.layout.motor_list_group,
|
||||
R.layout.motor_list_child);
|
@ -1,91 +0,0 @@
|
||||
package net.sf.openrocket.android.motor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.ExpandableListActivity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.ExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
|
||||
public class PersistentExpandableListActivity extends ExpandableListActivity {
|
||||
private long[] expandedIds;
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (this.expandedIds != null) {
|
||||
restoreExpandedState(expandedIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
expandedIds = getExpandedIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
this.expandedIds = getExpandedIds();
|
||||
outState.putLongArray("ExpandedIds", this.expandedIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle state) {
|
||||
super.onRestoreInstanceState(state);
|
||||
long[] expandedIds = state.getLongArray("ExpandedIds");
|
||||
if (expandedIds != null) {
|
||||
restoreExpandedState(expandedIds);
|
||||
}
|
||||
}
|
||||
|
||||
private long[] getExpandedIds() {
|
||||
ExpandableListView list = getExpandableListView();
|
||||
ExpandableListAdapter adapter = getExpandableListAdapter();
|
||||
if (adapter != null) {
|
||||
int length = adapter.getGroupCount();
|
||||
ArrayList<Long> expandedIds = new ArrayList<Long>();
|
||||
for(int i=0; i < length; i++) {
|
||||
if(list.isGroupExpanded(i)) {
|
||||
expandedIds.add(adapter.getGroupId(i));
|
||||
}
|
||||
}
|
||||
return toLongArray(expandedIds);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreExpandedState(long[] expandedIds) {
|
||||
this.expandedIds = expandedIds;
|
||||
if (expandedIds != null) {
|
||||
ExpandableListView list = getExpandableListView();
|
||||
ExpandableListAdapter adapter = getExpandableListAdapter();
|
||||
if (adapter != null) {
|
||||
for (int i=0; i<adapter.getGroupCount(); i++) {
|
||||
long id = adapter.getGroupId(i);
|
||||
if (inArray(expandedIds, id)) list.expandGroup(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean inArray(long[] array, long element) {
|
||||
for (long l : array) {
|
||||
if (l == element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static long[] toLongArray(List<Long> list) {
|
||||
long[] ret = new long[list.size()];
|
||||
int i = 0;
|
||||
for (Long e : list)
|
||||
ret[i++] = e.longValue();
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package net.sf.openrocket.android.util;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class AndroidLogWrapper {
|
||||
|
||||
private static final boolean logEnabled = true;
|
||||
|
||||
public static void d( Class clzz, String msg, Object ... args ) {
|
||||
|
||||
if ( logEnabled ) {
|
||||
String tag = getTagForClass(clzz);
|
||||
String formatted = MessageFormat.format(msg, args);
|
||||
Log.d(tag,formatted);
|
||||
}
|
||||
}
|
||||
|
||||
public static void e( Class clzz, String msg, Object ... args ) {
|
||||
if ( logEnabled ) {
|
||||
String tag = getTagForClass(clzz);
|
||||
String formatted = MessageFormat.format(msg, args);
|
||||
Log.e(tag,formatted);
|
||||
}
|
||||
}
|
||||
|
||||
public static void i( Class clzz, String msg, Object ... args ) {
|
||||
if ( logEnabled ) {
|
||||
String tag = getTagForClass(clzz);
|
||||
String formatted = MessageFormat.format(msg, args);
|
||||
Log.i(tag,formatted);
|
||||
}
|
||||
}
|
||||
public static void v( Class clzz, String msg, Object ... args ) {
|
||||
if ( logEnabled ) {
|
||||
String tag = getTagForClass(clzz);
|
||||
String formatted = MessageFormat.format(msg, args);
|
||||
Log.v(tag,formatted);
|
||||
}
|
||||
}
|
||||
public static void w( Class clzz, String msg, Object ... args ) {
|
||||
if ( logEnabled ) {
|
||||
String tag = getTagForClass(clzz);
|
||||
String formatted = MessageFormat.format(msg, args);
|
||||
Log.w(tag,formatted);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTagForClass( Class clzz ) {
|
||||
String s = clzz.getSimpleName();
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,344 @@
|
||||
package net.sf.openrocket.android.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnCreateContextMenuListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
*
|
||||
* Pulled from https://gist.github.com/1316903
|
||||
*
|
||||
* This class has originally been taken from
|
||||
* http://stackoverflow.com/questions/6051050/expandablelistfragment-with-loadermanager-for-compatibility-package
|
||||
* and then modified by Manfred Moser <manfred@simpligility.com> to get it to work with the v4 r4 compatibility
|
||||
* library. With inspirations from the library source.
|
||||
*
|
||||
* All ASLv2 licensed.
|
||||
*/
|
||||
public class ExpandableListFragment extends Fragment
|
||||
implements OnCreateContextMenuListener, ExpandableListView.OnChildClickListener,
|
||||
ExpandableListView.OnGroupCollapseListener, ExpandableListView.OnGroupExpandListener
|
||||
{
|
||||
|
||||
static final int INTERNAL_EMPTY_ID = 0x00ff0001;
|
||||
static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
|
||||
|
||||
final private Handler mHandler = new Handler();
|
||||
|
||||
final private Runnable mRequestFocus = new Runnable() {
|
||||
public void run() {
|
||||
mList.focusableViewAvailable(mList);
|
||||
}
|
||||
};
|
||||
|
||||
final private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
||||
onListItemClick((ListView) parent, v, position, id);
|
||||
}
|
||||
};
|
||||
|
||||
ExpandableListAdapter mAdapter;
|
||||
ExpandableListView mList;
|
||||
View mEmptyView;
|
||||
TextView mStandardEmptyView;
|
||||
View mListContainer;
|
||||
boolean mSetEmptyText;
|
||||
boolean mListShown;
|
||||
boolean mFinishedStart = false;
|
||||
|
||||
public ExpandableListFragment() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide default implementation to return a simple list view. Subclasses
|
||||
* can override to replace with their own layout. If doing so, the
|
||||
* returned view hierarchy <em>must</em> have a ListView whose id
|
||||
* is {@link android.R.id#list android.R.id.list} and can optionally
|
||||
* have a sibling view id {@link android.R.id#empty android.R.id.empty}
|
||||
* that is to be shown when the list is empty.
|
||||
* <p/>
|
||||
* <p>If you are overriding this method with your own custom content,
|
||||
* consider including the standard layout {@link android.R.layout#list_content}
|
||||
* in your layout file, so that you continue to retain all of the standard
|
||||
* behavior of ListFragment. In particular, this is currently the only
|
||||
* way to have the built-in indeterminant progress state be shown.
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
FrameLayout root = new FrameLayout(getActivity());
|
||||
|
||||
FrameLayout lframe = new FrameLayout(getActivity());
|
||||
lframe.setId(INTERNAL_LIST_CONTAINER_ID);
|
||||
|
||||
TextView tv = new TextView(getActivity());
|
||||
tv.setId(INTERNAL_EMPTY_ID);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
lframe.addView(tv,
|
||||
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
|
||||
ExpandableListView lv = new ExpandableListView(getActivity());
|
||||
lv.setId(android.R.id.list);
|
||||
lv.setDrawSelectorOnTop(false);
|
||||
lv.setOnChildClickListener(this);
|
||||
lv.setOnGroupExpandListener(this);
|
||||
lv.setOnGroupCollapseListener(this);
|
||||
|
||||
lframe.addView(lv,
|
||||
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
|
||||
root.addView(lframe, new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
|
||||
ListView.LayoutParams lp =
|
||||
new ListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
|
||||
root.setLayoutParams(lp);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach to list view once the view hierarchy has been created.
|
||||
*/
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
ensureList();
|
||||
}
|
||||
|
||||
/** Detach from list view. */
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mHandler.removeCallbacks(mRequestFocus);
|
||||
mList = null;
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called when an item in the list is selected.
|
||||
* Subclasses should override. Subclasses can call
|
||||
* getListView().getItemAtPosition(position) if they need to access the
|
||||
* data associated with the selected item.
|
||||
* @param l The ListView where the click happened
|
||||
* @param v The view that was clicked within the ListView
|
||||
* @param position The position of the view in the list
|
||||
* @param id The row id of the item that was clicked
|
||||
*/
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
}
|
||||
|
||||
/** Provide the cursor for the list view. */
|
||||
public void setListAdapter(ExpandableListAdapter adapter) {
|
||||
boolean hadAdapter = mAdapter != null;
|
||||
mAdapter = adapter;
|
||||
if (mList != null) {
|
||||
mList.setAdapter((ExpandableListAdapter) null);
|
||||
mList.setAdapter(adapter);
|
||||
if (!mListShown && !hadAdapter) {
|
||||
// The list was hidden, and previously didn't have an
|
||||
// adapter. It is now time to show it.
|
||||
setListShown(true, getView().getWindowToken() != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the currently selected list item to the specified
|
||||
* position with the adapter's data
|
||||
*/
|
||||
public void setSelection(int position) {
|
||||
ensureList();
|
||||
mList.setSelection(position);
|
||||
}
|
||||
|
||||
public long getSelectedPosition() {
|
||||
ensureList();
|
||||
return mList.getSelectedPosition();
|
||||
}
|
||||
|
||||
public long getSelectedId() {
|
||||
ensureList();
|
||||
return mList.getSelectedId();
|
||||
}
|
||||
|
||||
public ExpandableListView getExpandableListView() {
|
||||
ensureList();
|
||||
return mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default content for a ListFragment has a TextView that can
|
||||
* be shown when the list is empty. If you would like to have it
|
||||
* shown, call this method to supply the text it should use.
|
||||
*/
|
||||
public void setEmptyText(CharSequence text) {
|
||||
ensureList();
|
||||
if (mStandardEmptyView == null) {
|
||||
throw new IllegalStateException("Can't be used with a custom content view");
|
||||
}
|
||||
mStandardEmptyView.setText(text);
|
||||
if (!mSetEmptyText) {
|
||||
mList.setEmptyView(mStandardEmptyView);
|
||||
mSetEmptyText = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Control whether the list is being displayed. You can make it not
|
||||
* displayed if you are waiting for the initial data to show in it. During
|
||||
* this time an indeterminant progress indicator will be shown instead.
|
||||
* <p/>
|
||||
* <p>Applications do not normally need to use this themselves. The default
|
||||
* behavior of ListFragment is to start with the list not being shown, only
|
||||
* showing it once an adapter is given with {@link #setListAdapter(ListAdapter)}.
|
||||
* If the list at that point had not been shown, when it does get shown
|
||||
* it will be do without the user ever seeing the hidden state.
|
||||
* @param shown If true, the list view is shown; if false, the progress
|
||||
* indicator. The initial value is true.
|
||||
*/
|
||||
public void setListShown(boolean shown) {
|
||||
setListShown(shown, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #setListShown(boolean)}, but no animation is used when
|
||||
* transitioning from the previous state.
|
||||
*/
|
||||
public void setListShownNoAnimation(boolean shown) {
|
||||
setListShown(shown, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Control whether the list is being displayed. You can make it not
|
||||
* displayed if you are waiting for the initial data to show in it. During
|
||||
* this time an indeterminant progress indicator will be shown instead.
|
||||
* @param shown If true, the list view is shown; if false, the progress
|
||||
* indicator. The initial value is true.
|
||||
* @param animate If true, an animation will be used to transition to the
|
||||
* new state.
|
||||
*/
|
||||
private void setListShown(boolean shown, boolean animate) {
|
||||
ensureList();
|
||||
if (mListShown == shown) {
|
||||
return;
|
||||
}
|
||||
mListShown = shown;
|
||||
if (mListContainer != null) {
|
||||
if (shown) {
|
||||
if (animate) {
|
||||
mListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
|
||||
}
|
||||
mListContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
if (animate) {
|
||||
mListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
|
||||
}
|
||||
mListContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the ListAdapter associated with this activity's ListView. */
|
||||
public ExpandableListAdapter getExpandableListAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
private void ensureList() {
|
||||
if (mList != null) {
|
||||
return;
|
||||
}
|
||||
View root = getView();
|
||||
if (root == null) {
|
||||
throw new IllegalStateException("Content view not yet created");
|
||||
}
|
||||
if (root instanceof ExpandableListView) {
|
||||
mList = (ExpandableListView) root;
|
||||
} else {
|
||||
mStandardEmptyView = (TextView) root.findViewById(INTERNAL_EMPTY_ID);
|
||||
if (mStandardEmptyView == null) {
|
||||
mEmptyView = root.findViewById(android.R.id.empty);
|
||||
}
|
||||
mListContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID);
|
||||
View rawListView = root.findViewById(android.R.id.list);
|
||||
if (!(rawListView instanceof ExpandableListView)) {
|
||||
if (rawListView == null) {
|
||||
throw new RuntimeException("Your content must have a ExpandableListView whose id attribute is " +
|
||||
"'android.R.id.list'");
|
||||
}
|
||||
throw new RuntimeException("Content has view with id attribute 'android.R.id.list' " +
|
||||
"that is not a ExpandableListView class");
|
||||
}
|
||||
mList = (ExpandableListView) rawListView;
|
||||
if (mEmptyView != null) {
|
||||
mList.setEmptyView(mEmptyView);
|
||||
}
|
||||
}
|
||||
mListShown = true;
|
||||
mList.setOnItemClickListener(mOnClickListener);
|
||||
if (mAdapter != null) {
|
||||
setListAdapter(mAdapter);
|
||||
} else {
|
||||
// We are starting without an adapter, so assume we won't
|
||||
// have our data right away and start with the progress indicator.
|
||||
setListShown(false, false);
|
||||
}
|
||||
mHandler.post(mRequestFocus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGroupExpand(int arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGroupCollapse(int arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onChildClick(ExpandableListView arg0, View arg1, int arg2, int arg3, long arg4) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
}
|
||||
|
||||
public void onContentChanged() {
|
||||
View emptyView = getView().findViewById(android.R.id.empty);
|
||||
mList = (ExpandableListView) getView().findViewById(android.R.id.list);
|
||||
if (mList == null) {
|
||||
throw new RuntimeException(
|
||||
"Your content must have a ExpandableListView whose id attribute is " + "'android.R.id.list'");
|
||||
}
|
||||
if (emptyView != null) {
|
||||
mList.setEmptyView(emptyView);
|
||||
}
|
||||
mList.setOnChildClickListener(this);
|
||||
mList.setOnGroupExpandListener(this);
|
||||
mList.setOnGroupCollapseListener(this);
|
||||
|
||||
if (mFinishedStart) {
|
||||
setListAdapter(mAdapter);
|
||||
}
|
||||
mFinishedStart = true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,145 @@
|
||||
package net.sf.openrocket.android.util;
|
||||
|
||||
/*
|
||||
* TODO - this isn't working.
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.ExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
|
||||
public class PersistentExpandableListFragment extends ExpandableListFragment {
|
||||
private long[] expandedIds;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
AndroidLogWrapper.d(PersistentExpandableListFragment.class, "onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
if ( savedInstanceState != null ) {
|
||||
expandedIds = savedInstanceState.getLongArray("ExpandedIds");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
AndroidLogWrapper.d(PersistentExpandableListFragment.class, "onStop");
|
||||
super.onStop();
|
||||
expandedIds = getExpandedIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
AndroidLogWrapper.d(PersistentExpandableListFragment.class, "onStart");
|
||||
super.onStart();
|
||||
if (this.expandedIds != null) {
|
||||
restoreExpandedState(expandedIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
AndroidLogWrapper.d(PersistentExpandableListFragment.class, "onPause");
|
||||
super.onPause();
|
||||
expandedIds = getExpandedIds();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
AndroidLogWrapper.d(PersistentExpandableListFragment.class, "onResume");
|
||||
super.onResume();
|
||||
if (this.expandedIds != null) {
|
||||
restoreExpandedState(expandedIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
this.expandedIds = getExpandedIds();
|
||||
outState.putLongArray("ExpandedIds", this.expandedIds);
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (this.expandedIds != null) {
|
||||
restoreExpandedState(expandedIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
expandedIds = getExpandedIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
this.expandedIds = getExpandedIds();
|
||||
outState.putLongArray("ExpandedIds", this.expandedIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle state) {
|
||||
super.onRestoreInstanceState(state);
|
||||
long[] expandedIds = state.getLongArray("ExpandedIds");
|
||||
if (expandedIds != null) {
|
||||
restoreExpandedState(expandedIds);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
private long[] getExpandedIds() {
|
||||
ExpandableListView list = getExpandableListView();
|
||||
ExpandableListAdapter adapter = getExpandableListAdapter();
|
||||
if (adapter != null) {
|
||||
int length = adapter.getGroupCount();
|
||||
ArrayList<Long> expandedIds = new ArrayList<Long>();
|
||||
for(int i=0; i < length; i++) {
|
||||
if(list.isGroupExpanded(i)) {
|
||||
expandedIds.add(adapter.getGroupId(i));
|
||||
}
|
||||
}
|
||||
return toLongArray(expandedIds);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreExpandedState(long[] expandedIds) {
|
||||
this.expandedIds = expandedIds;
|
||||
if (expandedIds != null) {
|
||||
ExpandableListView list = getExpandableListView();
|
||||
ExpandableListAdapter adapter = getExpandableListAdapter();
|
||||
if (adapter != null) {
|
||||
for (int i=0; i<adapter.getGroupCount(); i++) {
|
||||
long id = adapter.getGroupId(i);
|
||||
if (inArray(expandedIds, id)) list.expandGroup(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean inArray(long[] array, long element) {
|
||||
for (long l : array) {
|
||||
if (l == element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static long[] toLongArray(List<Long> list) {
|
||||
long[] ret = new long[list.size()];
|
||||
int i = 0;
|
||||
for (Long e : list)
|
||||
ret[i++] = e.longValue();
|
||||
return ret;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user