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.database.DataSetObserver;
import java.io.FileInputStream;
import java.util.HashMap;
import android.view.LayoutInflater;
import junit.framework.Assert;
@ -34,9 +35,10 @@ import org.eehouse.android.xw4.jni.*;
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
public class GameListAdapter extends XWListAdapter {
Context m_context;
LayoutInflater m_factory;
int m_layoutId;
private Context m_context;
private LayoutInflater m_factory;
private int m_layoutId;
private HashMap<String,View> m_viewsCache;
public GameListAdapter( Context context ) {
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
? R.layout.game_list_item : R.layout.game_list_item_onefive;
m_viewsCache = new HashMap<String,View>();
}
public int getCount() {
@ -58,34 +62,39 @@ public class GameListAdapter extends XWListAdapter {
public Object getItem( int position )
{
final View layout = m_factory.inflate( m_layoutId, null );
String path = GameUtils.gamesList(m_context)[position];
byte[] stream = open( path );
if ( null != stream ) {
CurGameInfo gi = new CurGameInfo( m_context );
XwJNI.gi_from_stream( gi, stream );
View layout = m_viewsCache.get( path );
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 );
String gameName = GameUtils.gameName( m_context, path );
view.setText( String.format( "%s: %s", gameName,
gi.summarizePlayers( m_context,
summary ) ) );
GameSummary summary = DBUtils.getSummary( m_context, path );
view = (TextView)layout.findViewById( R.id.state );
view.setText( gi.summarizeState( m_context, summary ) );
view = (TextView)layout.findViewById( R.id.dict );
view.setText( gi.summarizeDict( m_context ) );
TextView view = (TextView)layout.findViewById( R.id.players );
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.role );
String roleSummary = gi.summarizeRole( m_context, summary );
if ( null != roleSummary ) {
view.setText( roleSummary );
} else {
view.setVisibility( View.GONE );
view = (TextView)layout.findViewById( R.id.state );
view.setText( gi.summarizeState( m_context, summary ) );
view = (TextView)layout.findViewById( R.id.dict );
view.setText( gi.summarizeDict( m_context ) );
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;
}
@ -110,4 +119,10 @@ public class GameListAdapter extends XWListAdapter {
}
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.*;
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 CONFIRM_DELETE_ALL = Utils.DIALOG_LAST + 2;
private GameListAdapter m_adapter;
private String m_invalPath = null;
private String m_missingDict;
@Override
@ -126,7 +127,9 @@ public class GamesList extends ListActivity implements View.OnClickListener {
public void onWindowFocusChanged( boolean hasFocus )
{
super.onWindowFocusChanged( hasFocus );
if ( hasFocus ) {
if ( hasFocus && null != m_invalPath ) {
m_adapter.inval( m_invalPath );
m_invalPath = null;
onContentChanged();
}
}
@ -144,6 +147,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
{
boolean handled = true;
byte[] stream;
String invalPath = null;
AdapterView.AdapterContextMenuInfo info;
try {
@ -158,6 +162,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
if ( R.id.list_item_delete == id ) {
GameUtils.deleteGame( this, path );
invalPath = path;
} else {
String[] missingName = new String[1];
boolean hasDict = GameUtils.gameDictHere( this, path, missingName );
@ -168,16 +173,16 @@ public class GamesList extends ListActivity implements View.OnClickListener {
switch ( id ) {
case R.id.list_item_config:
doConfig( path );
break;
case R.id.list_item_delete:
GameUtils.deleteGame( this, path );
invalPath = path;
break;
case R.id.list_item_reset:
GameUtils.resetGame( this, path, path );
invalPath = path;
break;
case R.id.list_item_new_from:
String newName = GameUtils.resetGame( this, path );
invalPath = newName;
break;
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 ) {
onContentChanged();
}
@ -272,6 +281,7 @@ public class GamesList extends ListActivity implements View.OnClickListener {
Intent intent = new Intent( Intent.ACTION_EDIT, uri,
this, BoardActivity.class );
startActivity( intent );
m_invalPath = path;
}
}