cache games list item views in hashmap by file path, and inval

individual items when their views need to change.  This seems to
significantly speed [re]rendering the list.
This commit is contained in:
Andy2 2010-06-25 06:38:00 -07:00
parent 10286e0109
commit 05a208594c
2 changed files with 56 additions and 31 deletions

View file

@ -26,6 +26,7 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import android.database.DataSetObserver; import android.database.DataSetObserver;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.HashMap;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import junit.framework.Assert; import junit.framework.Assert;
@ -34,9 +35,10 @@ import org.eehouse.android.xw4.jni.*;
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
public class GameListAdapter extends XWListAdapter { public class GameListAdapter extends XWListAdapter {
Context m_context; private Context m_context;
LayoutInflater m_factory; private LayoutInflater m_factory;
int m_layoutId; private int m_layoutId;
private HashMap<String,View> m_viewsCache;
public GameListAdapter( Context context ) { public GameListAdapter( Context context ) {
super( context, GameUtils.gamesList(context).length ); super( context, GameUtils.gamesList(context).length );
@ -50,6 +52,8 @@ public class GameListAdapter extends XWListAdapter {
m_layoutId = sdk_int >= android.os.Build.VERSION_CODES.DONUT m_layoutId = sdk_int >= android.os.Build.VERSION_CODES.DONUT
? R.layout.game_list_item : R.layout.game_list_item_onefive; ? R.layout.game_list_item : R.layout.game_list_item_onefive;
m_viewsCache = new HashMap<String,View>();
} }
public int getCount() { public int getCount() {
@ -58,34 +62,39 @@ public class GameListAdapter extends XWListAdapter {
public Object getItem( int position ) public Object getItem( int position )
{ {
final View layout = m_factory.inflate( m_layoutId, null );
String path = GameUtils.gamesList(m_context)[position]; String path = GameUtils.gamesList(m_context)[position];
byte[] stream = open( path ); View layout = m_viewsCache.get( path );
if ( null != stream ) {
CurGameInfo gi = new CurGameInfo( m_context );
XwJNI.gi_from_stream( gi, stream );
GameSummary summary = DBUtils.getSummary( m_context, path ); if ( null == layout ) {
Utils.logf( "creating new list elem for %s", path );
layout = m_factory.inflate( m_layoutId, null );
byte[] stream = open( path );
if ( null != stream ) {
CurGameInfo gi = new CurGameInfo( m_context );
XwJNI.gi_from_stream( gi, stream );
TextView view = (TextView)layout.findViewById( R.id.players ); GameSummary summary = DBUtils.getSummary( m_context, path );
String gameName = GameUtils.gameName( m_context, path );
view.setText( String.format( "%s: %s", gameName,
gi.summarizePlayers( m_context,
summary ) ) );
view = (TextView)layout.findViewById( R.id.state ); TextView view = (TextView)layout.findViewById( R.id.players );
view.setText( gi.summarizeState( m_context, summary ) ); String gameName = GameUtils.gameName( m_context, path );
view = (TextView)layout.findViewById( R.id.dict ); view.setText( String.format( "%s: %s", gameName,
view.setText( gi.summarizeDict( m_context ) ); gi.summarizePlayers( m_context,
summary ) ) );
view = (TextView)layout.findViewById( R.id.role ); view = (TextView)layout.findViewById( R.id.state );
String roleSummary = gi.summarizeRole( m_context, summary ); view.setText( gi.summarizeState( m_context, summary ) );
if ( null != roleSummary ) { view = (TextView)layout.findViewById( R.id.dict );
view.setText( roleSummary ); view.setText( gi.summarizeDict( m_context ) );
} else {
view.setVisibility( View.GONE ); view = (TextView)layout.findViewById( R.id.role );
String roleSummary = gi.summarizeRole( m_context, summary );
if ( null != roleSummary ) {
view.setText( roleSummary );
} else {
view.setVisibility( View.GONE );
}
} }
m_viewsCache.put( path, layout );
} }
return layout; return layout;
} }
@ -110,4 +119,10 @@ public class GameListAdapter extends XWListAdapter {
} }
return stream; return stream;
} }
public void inval( String key )
{
m_viewsCache.remove( key );
}
} }

View file

@ -43,10 +43,11 @@ import junit.framework.Assert;
import org.eehouse.android.xw4.jni.*; import org.eehouse.android.xw4.jni.*;
public class GamesList extends ListActivity implements View.OnClickListener { public class GamesList extends ListActivity implements View.OnClickListener {
private GameListAdapter m_adapter;
private static final int WARN_NODICT = Utils.DIALOG_LAST + 1; private static final int WARN_NODICT = Utils.DIALOG_LAST + 1;
private static final int CONFIRM_DELETE_ALL = Utils.DIALOG_LAST + 2; private static final int CONFIRM_DELETE_ALL = Utils.DIALOG_LAST + 2;
private GameListAdapter m_adapter;
private String m_invalPath = null;
private String m_missingDict; private String m_missingDict;
@Override @Override
@ -126,7 +127,9 @@ public class GamesList extends ListActivity implements View.OnClickListener {
public void onWindowFocusChanged( boolean hasFocus ) public void onWindowFocusChanged( boolean hasFocus )
{ {
super.onWindowFocusChanged( hasFocus ); super.onWindowFocusChanged( hasFocus );
if ( hasFocus ) { if ( hasFocus && null != m_invalPath ) {
m_adapter.inval( m_invalPath );
m_invalPath = null;
onContentChanged(); onContentChanged();
} }
} }
@ -144,6 +147,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
{ {
boolean handled = true; boolean handled = true;
byte[] stream; byte[] stream;
String invalPath = null;
AdapterView.AdapterContextMenuInfo info; AdapterView.AdapterContextMenuInfo info;
try { try {
@ -158,6 +162,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
if ( R.id.list_item_delete == id ) { if ( R.id.list_item_delete == id ) {
GameUtils.deleteGame( this, path ); GameUtils.deleteGame( this, path );
invalPath = path;
} else { } else {
String[] missingName = new String[1]; String[] missingName = new String[1];
boolean hasDict = GameUtils.gameDictHere( this, path, missingName ); boolean hasDict = GameUtils.gameDictHere( this, path, missingName );
@ -168,16 +173,16 @@ public class GamesList extends ListActivity implements View.OnClickListener {
switch ( id ) { switch ( id ) {
case R.id.list_item_config: case R.id.list_item_config:
doConfig( path ); doConfig( path );
break; invalPath = path;
case R.id.list_item_delete:
GameUtils.deleteGame( this, path );
break; break;
case R.id.list_item_reset: case R.id.list_item_reset:
GameUtils.resetGame( this, path, path ); GameUtils.resetGame( this, path, path );
invalPath = path;
break; break;
case R.id.list_item_new_from: case R.id.list_item_new_from:
String newName = GameUtils.resetGame( this, path ); String newName = GameUtils.resetGame( this, path );
invalPath = newName;
break; break;
case R.id.list_item_copy: case R.id.list_item_copy:
@ -202,6 +207,10 @@ public class GamesList extends ListActivity implements View.OnClickListener {
} }
} }
if ( null != invalPath ) {
m_adapter.inval( invalPath );
}
if ( handled ) { if ( handled ) {
onContentChanged(); onContentChanged();
} }
@ -272,6 +281,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
Intent intent = new Intent( Intent.ACTION_EDIT, uri, Intent intent = new Intent( Intent.ACTION_EDIT, uri,
this, BoardActivity.class ); this, BoardActivity.class );
startActivity( intent ); startActivity( intent );
m_invalPath = path;
} }
} }