rewrite DictsActivity to not crash when un- and re-loaded: make

dialogs depend only on bundleable ivars -- ints and strings, not Views
-- and bundle them.  Don't use onPrepareDialog, only onCreateDialog,
and so call removeDialog() every time one's dismissed.  Do some
refactoring to support this.
This commit is contained in:
Andy2 2011-08-23 18:41:19 -07:00
parent 84e61f3b3f
commit 7da5b24e0f
7 changed files with 149 additions and 101 deletions

View file

@ -157,7 +157,7 @@ public class BoardActivity extends XWActivity
ab.setNegativeButton( R.string.button_retry, lstnr );
}
dialog = ab.create();
setRemoveOnDismiss( dialog, id );
Utils.setRemoveOnDismiss( this, dialog, id );
break;
case DLG_DELETED:

View file

@ -61,6 +61,12 @@ public class DictsActivity extends ExpandableListActivity
private static final String DICT_DOLAUNCH = "do_launch";
private static final String DICT_LANG_EXTRA = "use_lang";
private static final String DICT_NAME_EXTRA = "use_dict";
private static final String PACKED_POSITION = "packed_position";
private static final String NAME = "name";
private static final String LANG = "lang";
private static final String MOVEFROMLOC = "movefromloc";
private static final String MOVETOLOC = "movetoloc";
private static final int PICK_STORAGE = DlgDelegate.DIALOG_LAST + 1;
private static final int MOVE_DICT = DlgDelegate.DIALOG_LAST + 2;
@ -72,17 +78,18 @@ public class DictsActivity extends ExpandableListActivity
private ExpandableListView m_expView;
private DlgDelegate m_delegate;
private String[] m_locNames;
private DictListAdapter m_adapter;
private XWListItem m_rowView;
GameUtils.DictLoc m_moveFromLoc;
GameUtils.DictLoc m_moveToLoc;
private long m_packedPosition;
private GameUtils.DictLoc m_moveFromLoc;
private GameUtils.DictLoc m_moveToLoc;
private SDCardWatcher m_cardWatcher;
private String m_moveName;
private LayoutInflater m_factory;
private class DictListAdapter implements ExpandableListAdapter {
private Context m_context;
private XWListItem[][] m_cache;
public DictListAdapter( Context context ) {
//super( context, m_dicts.length );
@ -105,29 +112,41 @@ public class DictsActivity extends ExpandableListActivity
boolean isLastChild, View convertView,
ViewGroup parent)
{
int lang = (int)getGroupId( groupPosition );
String[] dicts = DictLangCache.getHaveLang( m_context, lang );
String text;
boolean canDelete = false;
if ( null != dicts && childPosition < dicts.length ) {
text = dicts[childPosition];
canDelete = !GameUtils.dictIsBuiltin( DictsActivity.this,
text );
} else {
text = m_download;
}
XWListItem view =
(XWListItem)m_factory.inflate( R.layout.list_item, null );
view.setText( text );
if ( canDelete ) {
view.setDeleteCallback( DictsActivity.this );
return getChildView( groupPosition, childPosition );
}
private View getChildView( int groupPosition, int childPosition )
{
XWListItem view = null;
if ( null != m_cache && null != m_cache[groupPosition] ) {
view = m_cache[groupPosition][childPosition];
}
GameUtils.DictLoc loc =
GameUtils.getDictLoc( DictsActivity.this, text );
view.setComment( m_locNames[loc.ordinal()] );
view.cache( loc );
if ( null == view ) {
int lang = (int)getGroupId( groupPosition );
String[] dicts = DictLangCache.getHaveLang( m_context, lang );
String text;
boolean canDelete = false;
if ( null != dicts && childPosition < dicts.length ) {
text = dicts[childPosition];
canDelete = !GameUtils.dictIsBuiltin( DictsActivity.this,
text );
} else {
text = m_download;
}
view = (XWListItem)m_factory.inflate( R.layout.list_item, null );
view.setText( text );
if ( canDelete ) {
view.setDeleteCallback( DictsActivity.this );
}
GameUtils.DictLoc loc =
GameUtils.getDictLoc( DictsActivity.this, text );
view.setComment( m_locNames[loc.ordinal()] );
view.cache( loc );
addToCache( groupPosition, childPosition, view );
}
return view;
}
@ -188,17 +207,40 @@ public class DictsActivity extends ExpandableListActivity
public void onGroupExpanded(int groupPosition){}
public void registerDataSetObserver( DataSetObserver obs ){}
public void unregisterDataSetObserver( DataSetObserver obs ){}
protected XWListItem getSelChildView()
{
int groupPosition =
ExpandableListView.getPackedPositionGroup( m_packedPosition );
int childPosition =
ExpandableListView.getPackedPositionChild( m_packedPosition );
return (XWListItem)getChildView( groupPosition, childPosition );
}
private void addToCache( int group, int child, XWListItem view )
{
if ( null == m_cache ) {
m_cache = new XWListItem[getGroupCount()][];
}
if ( null == m_cache[group] ) {
m_cache[group] = new XWListItem[getChildrenCount(group)];
}
Assert.assertTrue( null == m_cache[group][child] );
m_cache[group][child] = view;
}
}
@Override
protected Dialog onCreateDialog( int id )
{
Dialog dialog;
DialogInterface.OnClickListener lstnr;
Dialog dialog;
String format;
String message;
boolean doRemove = true;
switch( id ) {
case PICK_STORAGE:
lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
startDownload( m_lang, m_name, item !=
@ -216,21 +258,28 @@ public class DictsActivity extends ExpandableListActivity
case MOVE_DICT:
lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
XWListItem rowView = m_adapter.getSelChildView();
if ( GameUtils.moveDict( DictsActivity.this,
m_moveName,
rowView.getText(),
m_moveFromLoc,
m_moveToLoc ) ) {
m_rowView.
rowView.
setComment( m_locNames[m_moveToLoc.ordinal()]);
m_rowView.cache( m_moveToLoc );
m_rowView.invalidate();
rowView.cache( m_moveToLoc );
rowView.invalidate();
} else {
Utils.logf( "moveDict failed" );
}
}
};
format = getString( R.string.move_dictf );
message = String.format( format,
m_adapter.getSelChildView().getText(),
m_locNames[ m_moveFromLoc.ordinal() ],
m_locNames[ m_moveToLoc.ordinal() ] );
dialog = new AlertDialog.Builder( this )
.setMessage( "" ) // will set later
.setMessage( message )
.setPositiveButton( R.string.button_ok, lstnr )
.setNegativeButton( R.string.button_cancel, null )
.create();
@ -240,18 +289,22 @@ public class DictsActivity extends ExpandableListActivity
public void onClick( DialogInterface dlg, int item ) {
if ( DialogInterface.BUTTON_NEGATIVE == item
|| DialogInterface.BUTTON_POSITIVE == item ) {
setDefault( R.string.key_default_dict, m_rowView );
setDefault( R.string.key_default_dict );
}
if ( DialogInterface.BUTTON_NEGATIVE == item
|| DialogInterface.BUTTON_NEUTRAL == item ) {
setDefault( R.string.key_default_robodict,
m_rowView );
setDefault( R.string.key_default_robodict );
}
}
};
XWListItem rowView = m_adapter.getSelChildView();
String lang =
DictLangCache.getLangName( this, rowView.getText() );
format = getString( R.string.set_default_messagef );
message = String.format( format, lang );
dialog = new AlertDialog.Builder( this )
.setTitle( R.string.query_title )
.setMessage( "" ) // or can't change it later!
.setMessage( message )
.setPositiveButton( R.string.button_default_human, lstnr )
.setNeutralButton( R.string.button_default_robot, lstnr )
.setNegativeButton( R.string.button_default_both, lstnr )
@ -259,44 +312,22 @@ public class DictsActivity extends ExpandableListActivity
break;
default:
dialog = m_delegate.onCreateDialog( id );
doRemove = false;
break;
}
if ( doRemove && null != dialog ) {
Utils.setRemoveOnDismiss( this, dialog, id );
}
return dialog;
}
@Override
public void onPrepareDialog( int id, Dialog dialog )
{
AlertDialog ad = (AlertDialog)dialog;
String format;
String message;
switch( id ) {
case PICK_STORAGE:
break;
case MOVE_DICT:
format = getString( R.string.move_dictf );
message = String.format( format, m_moveName,
m_locNames[ m_moveFromLoc.ordinal() ],
m_locNames[ m_moveToLoc.ordinal() ] );
ad.setMessage( message );
break;
case SET_DEFAULT:
String lang =
DictLangCache.getLangName( this, m_rowView.getText() );
format = getString( R.string.set_default_messagef );
message = String.format( format, lang );
ad.setMessage( message );
break;
default:
m_delegate.onPrepareDialog( id, dialog );
}
}
} // onCreateDialog
@Override
protected void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
getBundledData( savedInstanceState );
Resources res = getResources();
m_locNames = res.getStringArray( R.array.loc_names );
@ -343,8 +374,37 @@ public class DictsActivity extends ExpandableListActivity
{
super.onSaveInstanceState( outState );
m_delegate.onSaveInstanceState( outState );
outState.putLong( PACKED_POSITION, m_packedPosition );
outState.putString( NAME, m_name );
outState.putInt( LANG, m_lang );
if ( null != m_moveFromLoc ) {
outState.putInt( MOVEFROMLOC, m_moveFromLoc.ordinal() );
}
if ( null != m_moveToLoc ) {
outState.putInt( MOVETOLOC, m_moveToLoc.ordinal() );
}
}
private void getBundledData( Bundle savedInstanceState )
{
if ( null != savedInstanceState ) {
m_packedPosition = savedInstanceState.getLong( PACKED_POSITION );
m_name = savedInstanceState.getString( NAME );
m_lang = savedInstanceState.getInt( LANG );
int tmp = savedInstanceState.getInt( MOVEFROMLOC, -1 );
if ( -1 != tmp ) {
m_moveFromLoc = GameUtils.DictLoc.values()[tmp];
}
tmp = savedInstanceState.getInt( MOVETOLOC, -1 );
if ( -1 != tmp ) {
m_moveToLoc = GameUtils.DictLoc.values()[tmp];
}
}
}
@Override
protected void onPause() {
m_cardWatcher.close();
m_cardWatcher = null;
@ -402,14 +462,14 @@ public class DictsActivity extends ExpandableListActivity
return false;
}
XWListItem row = (XWListItem)info.targetView;
m_packedPosition = info.packedPosition;
int id = item.getItemId();
switch( id ) {
case R.id.dicts_item_move:
askMoveDict( row );
askMoveDict( (XWListItem)info.targetView );
break;
case R.id.dicts_item_select:
m_rowView = row;
showDialog( SET_DEFAULT );
break;
case R.id.dicts_item_details:
@ -420,13 +480,14 @@ public class DictsActivity extends ExpandableListActivity
return handled;
}
private void setDefault( int keyId, final XWListItem text )
private void setDefault( int keyId )
{
XWListItem view = m_adapter.getSelChildView();
SharedPreferences sp
= PreferenceManager.getDefaultSharedPreferences( this );
SharedPreferences.Editor editor = sp.edit();
String key = getString( keyId );
String name = text.getText();
String name = view.getText();
editor.putString( key, name );
editor.commit();
}
@ -436,14 +497,12 @@ public class DictsActivity extends ExpandableListActivity
// options for YY?
private void askMoveDict( XWListItem item )
{
m_rowView = item;
m_moveFromLoc = (GameUtils.DictLoc)item.getCached();
if ( m_moveFromLoc == GameUtils.DictLoc.INTERNAL ) {
m_moveToLoc = GameUtils.DictLoc.EXTERNAL;
} else {
m_moveToLoc = GameUtils.DictLoc.INTERNAL;
}
m_moveName = item.getText();
showDialog( MOVE_DICT );
}
@ -515,9 +574,8 @@ public class DictsActivity extends ExpandableListActivity
private void mkListAdapter()
{
m_langs = DictLangCache.listLangs( this );
//m_langs = DictLangCache.getLangNames( this );
ExpandableListAdapter adapter = new DictListAdapter( this );
setListAdapter( adapter );
m_adapter = new DictListAdapter( this );
setListAdapter( m_adapter );
}
private void expandGroups()

View file

@ -93,17 +93,6 @@ public class DlgDelegate {
return dialog;
}
protected void setRemoveOnDismiss( Dialog dialog, final int id )
{
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
public void onDismiss( DialogInterface di ) {
Utils.logf( "%s.onDismiss() called",
getClass().getName() );
m_activity.removeDialog( id );
}
} );
}
public void onPrepareDialog( int id, Dialog dialog )
{
AlertDialog ad = (AlertDialog)dialog;

View file

@ -124,7 +124,7 @@ public class GamesList extends XWListActivity
ab.setNeutralButton( R.string.button_substdict, lstnr );
}
dialog = ab.create();
setRemoveOnDismiss( dialog, id );
Utils.setRemoveOnDismiss( this, dialog, id );
break;
case SHOW_SUBST:
m_sameLangDicts =

View file

@ -22,14 +22,15 @@ package org.eehouse.android.xw4;
import android.util.Log;
import java.lang.Thread;
import android.widget.Toast;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.widget.CheckBox;
import android.app.Activity;
import android.app.Dialog;
import android.widget.Toast;
import android.widget.EditText;
import android.widget.TextView;
import android.view.LayoutInflater;
@ -105,6 +106,16 @@ public class Utils {
Toast.makeText( context, text, Toast.LENGTH_SHORT).show();
}
public static void setRemoveOnDismiss( final Activity activity,
Dialog dialog, final int id )
{
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
public void onDismiss( DialogInterface di ) {
activity.removeDialog( id );
}
} );
}
public static View inflate( Context context, int layoutId )
{
LayoutInflater factory = LayoutInflater.from( context );

View file

@ -100,11 +100,6 @@ public class XWActivity extends Activity {
return dialog;
}
protected void setRemoveOnDismiss( Dialog dialog, int id )
{
m_delegate.setRemoveOnDismiss( dialog, id );
}
@Override
protected void onPrepareDialog( int id, Dialog dialog )
{

View file

@ -105,11 +105,6 @@ public class XWListActivity extends ListActivity {
return dialog;
}
protected void setRemoveOnDismiss( Dialog dialog, int id )
{
m_delegate.setRemoveOnDismiss( dialog, id );
}
@Override
protected void onPrepareDialog( int id, Dialog dialog )
{