rewrite list item logic. Use a single custom LinearLayout subclass

for both the loading and loaded phases, toggling its state once the
data's available.  Reuse it: pay attention to what's passed into
getView and only allocate when there's no existing View to reuse.
Stop caching Views, as that defeats Android list logic that might
limit in-memory representation to the subset that's visible on-screen,
instead tracking a set of rowids whose data is known to be good as a
way of quickly drawing when there's a refresh.
This commit is contained in:
Eric House 2012-12-08 08:47:53 -08:00
parent 83b1d4c364
commit 7efbd2697d
5 changed files with 420 additions and 324 deletions

View file

@ -3,95 +3,114 @@
<!-- top-level layout is hozontal, with an image and another layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:longClickable="true"
android:focusable="true"
android:clickable="true"
android:background="@android:drawable/list_selector_background"
>
<org.eehouse.android.xw4.GameListItem
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:longClickable="true"
android:focusable="true"
android:clickable="true"
android:background="@android:drawable/list_selector_background"
>
<ImageView android:id="@+id/msg_marker"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="0"
/>
<TextView android:id="@+id/view_unloaded"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="@string/game_list_tmp"
/>
<!-- this layout is vertical, holds everything but the status
icon[s] (plural later) -->
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<!-- This is the game name and expander -->
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<org.eehouse.android.xw4.ExpiringTextView
android:id="@+id/game_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<ImageButton android:id="@+id/expander"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/expander_ic_maximized"
/>
</LinearLayout>
<!-- This is everything below the name (which can be hidden) -->
<LinearLayout android:id="@+id/hideable"
<LinearLayout android:id="@+id/view_loaded"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4sp">
android:visibility="gone"
>
<!-- Player list plus connection status -->
<LinearLayout android:id="@+id/player_list"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:layout_marginRight="4dip"
/> <!-- end players column -->
<ImageView android:id="@+id/msg_marker"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="0"
/>
<!-- holds right column. Could hold more... -->
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/modtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
/>
<TextView android:id="@+id/state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
/>
</LinearLayout>
<!-- this layout is vertical, holds everything but the status
icon[s] (plural later) -->
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<!-- This is the game name and expander -->
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<org.eehouse.android.xw4.ExpiringTextView
android:id="@+id/game_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<ImageButton android:id="@+id/expander"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@drawable/expander_ic_maximized"
/>
</LinearLayout>
<!-- This is everything below the name (which can be hidden) -->
<LinearLayout android:id="@+id/hideable"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="4sp">
<!-- Player list plus connection status -->
<LinearLayout android:id="@+id/player_list"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:layout_marginRight="4dip"
/> <!-- end players column -->
<!-- holds right column. Could hold more... -->
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/modtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
/>
<TextView android:id="@+id/state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
/>
</LinearLayout>
</LinearLayout>
<TextView android:id="@+id/role"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
/>
</LinearLayout>
</LinearLayout>
<TextView android:id="@+id/role"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
/>
</LinearLayout>
</LinearLayout>
</org.eehouse.android.xw4.GameListItem>

View file

@ -35,7 +35,7 @@ import android.widget.TextView;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap; // class is not synchronized
import java.util.HashSet;
import java.util.Random;
import junit.framework.Assert;
@ -46,10 +46,6 @@ import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
public class GameListAdapter extends XWListAdapter {
private Context m_context;
private LayoutInflater m_factory;
private int m_fieldID;
private Handler m_handler;
private static final boolean s_isFire;
private static Random s_random;
static {
@ -59,79 +55,35 @@ public class GameListAdapter extends XWListAdapter {
}
}
private class ViewInfo implements View.OnClickListener {
private View m_view;
private View m_hideable;
private ExpiringTextView m_name;
private boolean m_expanded, m_haveTurn, m_haveTurnLocal;
private long m_rowid;
private long m_lastMoveTime;
private ImageButton m_expandButton;
public ViewInfo( View view, long rowid )
{
m_view = view;
m_rowid = rowid;
m_lastMoveTime = 0;
}
public ViewInfo( View view, long rowid, boolean expanded,
long lastMoveTime, boolean haveTurn,
boolean haveTurnLocal ) {
this( view, rowid );
m_expanded = expanded;
m_lastMoveTime = lastMoveTime;
m_haveTurn = haveTurn;
m_haveTurnLocal = haveTurnLocal;
m_hideable = (LinearLayout)view.findViewById( R.id.hideable );
m_name = (ExpiringTextView)m_view.findViewById( R.id.game_name );
m_expandButton = (ImageButton)view.findViewById( R.id.expander );
m_expandButton.setOnClickListener( this );
showHide();
}
private void showHide()
{
m_expandButton.setImageResource( m_expanded ?
R.drawable.expander_ic_maximized :
R.drawable.expander_ic_minimized);
m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE );
m_name.setBackgroundColor( android.R.color.transparent );
m_name.setPct( m_handler, m_haveTurn && !m_expanded,
m_haveTurnLocal, m_lastMoveTime );
}
public void onClick( View view ) {
m_expanded = !m_expanded;
DBUtils.setExpanded( m_rowid, m_expanded );
showHide();
}
}
private HashMap<Long,ViewInfo> m_viewsCache;
private Context m_context;
private LayoutInflater m_factory;
private int m_fieldID;
private Handler m_handler;
private DateFormat m_df;
private LoadItemCB m_cb;
// Track those rows known to be good. If a rowid is not in this
// set, assume it must be loaded. Add rowids to this set as
// they're loaded, and remove one when when it must be redrawn.
private HashSet<Long> m_loadedRows;
public interface LoadItemCB {
public void itemLoaded( long rowid );
public void itemClicked( long rowid );
}
private class LoadItemTask extends AsyncTask<Void, Void, Void> {
private long m_rowid;
private class LoadItemTask extends AsyncTask<Void, Void, GameSummary> {
private GameListItem m_view;
private Context m_context;
// private int m_id;
public LoadItemTask( Context context, long rowid/*, int id*/ )
public LoadItemTask( Context context, GameListItem view )
{
DbgUtils.logf( "Creating LoadItemTask for row %d",
view.getRowID() );
m_context = context;
m_rowid = rowid;
// m_id = id;
m_view = view;
}
@Override
protected Void doInBackground( Void... unused )
protected GameSummary doInBackground( Void... unused )
{
// Without this, on the Fire only the last item in the
// list it tappable. Likely my fault, but this seems to
@ -143,133 +95,26 @@ public class GameListAdapter extends XWListAdapter {
} catch ( Exception e ) {
}
}
View layout = m_factory.inflate( R.layout.game_list_item, null );
boolean hideTitle = false;//CommonPrefs.getHideTitleBar(m_context);
GameSummary summary = DBUtils.getSummary( m_context, m_rowid, 1500 );
if ( null == summary ) {
m_rowid = -1;
} else {
String state = summary.summarizeState();
TextView view = (TextView)layout.findViewById( R.id.game_name );
if ( hideTitle ) {
view.setVisibility( View.GONE );
} else {
String value = null;
switch ( m_fieldID ) {
case R.string.game_summary_field_empty:
break;
case R.string.game_summary_field_language:
value =
DictLangCache.getLangName( m_context,
summary.dictLang );
break;
case R.string.game_summary_field_opponents:
value = summary.playerNames();
break;
case R.string.game_summary_field_state:
value = state;
break;
}
String name = GameUtils.getName( m_context, m_rowid );
if ( null != value ) {
value = m_context.getString( R.string.str_game_namef,
name, value );
} else {
value = name;
}
view.setText( value );
}
layout.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
m_cb.itemClicked( m_rowid );
}
} );
LinearLayout list =
(LinearLayout)layout.findViewById( R.id.player_list );
boolean haveATurn = false;
boolean haveALocalTurn = false;
boolean[] isLocal = new boolean[1];
for ( int ii = 0; ii < summary.nPlayers; ++ii ) {
ExpiringLinearLayout tmp = (ExpiringLinearLayout)
m_factory.inflate( R.layout.player_list_elem, null );
view = (TextView)tmp.findViewById( R.id.item_name );
view.setText( summary.summarizePlayer( ii ) );
view = (TextView)tmp.findViewById( R.id.item_score );
view.setText( String.format( " %d", summary.scores[ii] ) );
boolean thisHasTurn = summary.isNextToPlay( ii, isLocal );
if ( thisHasTurn ) {
haveATurn = true;
if ( isLocal[0] ) {
haveALocalTurn = true;
}
}
tmp.setPct( m_handler, thisHasTurn, isLocal[0],
summary.lastMoveTime );
list.addView( tmp, ii );
}
view = (TextView)layout.findViewById( R.id.state );
view.setText( state );
view = (TextView)layout.findViewById( R.id.modtime );
long lastMoveTime = summary.lastMoveTime;
lastMoveTime *= 1000;
view.setText( m_df.format( new Date( lastMoveTime ) ) );
int iconID;
ImageView marker =
(ImageView)layout.findViewById( R.id.msg_marker );
CommsConnType conType = summary.conType;
if ( CommsConnType.COMMS_CONN_RELAY == conType ) {
iconID = R.drawable.relaygame;
} else if ( CommsConnType.COMMS_CONN_BT == conType ) {
iconID = android.R.drawable.stat_sys_data_bluetooth;
} else if ( CommsConnType.COMMS_CONN_SMS == conType ) {
iconID = android.R.drawable.sym_action_chat;
} else {
iconID = R.drawable.sologame;
}
marker.setImageResource( iconID );
view = (TextView)layout.findViewById( R.id.role );
String roleSummary = summary.summarizeRole();
if ( null != roleSummary ) {
view.setText( roleSummary );
} else {
view.setVisibility( View.GONE );
}
boolean expanded = DBUtils.getExpanded( m_context, m_rowid );
ViewInfo vi = new ViewInfo( layout, m_rowid, expanded,
summary.lastMoveTime, haveATurn,
haveALocalTurn );
if ( XWApp.DEBUG ) {
DbgUtils.logf( "created new view for rowid %d", m_rowid );
}
synchronized( m_viewsCache ) {
m_viewsCache.put( m_rowid, vi );
}
}
return null;
long rowid = m_view.getRowID();
GameSummary summary = DBUtils.getSummary( m_context, rowid, 1500 );
return summary;
} // doInBackground
@Override
protected void onPostExecute( Void unused )
protected void onPostExecute( GameSummary summary )
{
// DbgUtils.logf( "onPostExecute(rowid=%d)", m_rowid );
if ( -1 != m_rowid ) {
m_cb.itemLoaded( m_rowid );
}
setData( m_view, summary );
setLoaded( m_view.getRowID() );
m_view.setLoaded( true );
DbgUtils.logf( "LoadItemTask for row %d finished",
m_view.getRowID() );
}
} // class LoadItemTask
public GameListAdapter( Context context, Handler handler, LoadItemCB cb ) {
public GameListAdapter( Context context, Handler handler, LoadItemCB cb,
String fieldName ) {
super( DBUtils.gamesList(context).length );
m_context = context;
m_handler = handler;
@ -278,62 +123,92 @@ public class GameListAdapter extends XWListAdapter {
m_df = DateFormat.getDateTimeInstance( DateFormat.SHORT,
DateFormat.SHORT );
m_viewsCache = new HashMap<Long,ViewInfo>();
m_loadedRows = new HashSet<Long>();
m_fieldID = fieldToID( fieldName );
}
@Override
public int getCount() {
return DBUtils.gamesList(m_context).length;
}
public Object getItem( int position )
// Views. A view depends on a summary, which takes time to load.
// When one needs loading it's done via an async task.
public View getView( int position, View convertView, ViewGroup parent )
{
final long rowid = DBUtils.gamesList(m_context)[position];
View layout;
boolean haveLayout = false;
synchronized( m_viewsCache ) {
ViewInfo vi = m_viewsCache.get( rowid );
haveLayout = null != vi;
if ( haveLayout ) {
layout = vi.m_view;
} else {
layout = m_factory.inflate( R.layout.game_list_tmp, null );
vi = new ViewInfo( layout, rowid );
m_viewsCache.put( rowid, vi );
GameListItem result;
boolean mustLoad = false;
if ( null == convertView ) {
result = (GameListItem)
m_factory.inflate( R.layout.game_list_item, null );
result.setRowID( DBUtils.gamesList(m_context)[position] );
mustLoad = true;
} else {
result = (GameListItem)convertView;
long rowid = result.getRowID();
if ( isDirty(rowid) || !result.isLoaded() ) {
mustLoad = true;
}
}
if ( !haveLayout ) {
new LoadItemTask( m_context, rowid/*, ++m_taskCounter*/ ).execute();
if ( mustLoad ) {
new LoadItemTask( m_context, result ).execute();
}
// this doesn't work. Rather, it breaks highlighting because
// the background, if we don't set it, is a more complicated
// object like @android:drawable/list_selector_background. I
// tried calling getBackground(), expecting to get a Drawable
// I could then clone and modify, but null comes back. So
// layout must be inheriting its background from elsewhere or
// it gets set later, during layout.
// if ( (position%2) == 0 ) {
// layout.setBackgroundColor( 0xFF3F3F3F );
// }
return layout;
} // getItem
public View getView( int position, View convertView, ViewGroup parent ) {
return (View)getItem( position );
return result;
}
public void inval( long rowid )
{
synchronized( m_viewsCache ) {
m_viewsCache.remove( rowid );
synchronized( m_loadedRows ) {
m_loadedRows.remove( rowid );
}
}
private void dirtyAll()
{
synchronized( m_loadedRows ) {
m_loadedRows.clear();
}
}
private boolean isDirty( long rowid )
{
synchronized( m_loadedRows ) {
return ! m_loadedRows.contains( rowid );
}
}
private void setLoaded( long rowid )
{
synchronized( m_loadedRows ) {
m_loadedRows.add( rowid );
}
}
public boolean setField( String fieldName )
{
boolean changed = false;
int newID = fieldToID( fieldName );
if ( -1 == newID ) {
if ( XWApp.DEBUG ) {
DbgUtils.logf( "GameListAdapter.setField(): unable to match"
+ " fieldName %s", fieldName );
}
} else if ( m_fieldID != newID ) {
if ( XWApp.DEBUG ) {
DbgUtils.logf( "setField: clearing views cache for change"
+ " from %d to %d", m_fieldID, newID );
}
m_fieldID = newID;
dirtyAll();
changed = true;
}
return changed;
}
private int fieldToID( String fieldName )
{
int[] ids = {
R.string.game_summary_field_empty
,R.string.game_summary_field_language
@ -347,21 +222,109 @@ public class GameListAdapter extends XWListAdapter {
break;
}
}
if ( -1 == result ) {
if ( XWApp.DEBUG ) {
DbgUtils.logf( "GameListAdapter.setField(): unable to match"
+ " fieldName %s", fieldName );
}
} else if ( m_fieldID != result ) {
if ( XWApp.DEBUG ) {
DbgUtils.logf( "setField: clearing views cache for change"
+ " from %d to %d", m_fieldID, result );
}
m_viewsCache.clear();
m_fieldID = result;
changed = true;
}
return changed;
return result;
}
private void setData( GameListItem layout, GameSummary summary )
{
if ( null != summary ) {
final long rowid = layout.getRowID();
String state = summary.summarizeState();
TextView view = (TextView)layout.findViewById( R.id.game_name );
String value = null;
switch ( m_fieldID ) {
case R.string.game_summary_field_empty:
break;
case R.string.game_summary_field_language:
value =
DictLangCache.getLangName( m_context,
summary.dictLang );
break;
case R.string.game_summary_field_opponents:
value = summary.playerNames();
break;
case R.string.game_summary_field_state:
value = state;
break;
}
String name = GameUtils.getName( m_context, rowid );
if ( null != value ) {
value = m_context.getString( R.string.str_game_namef,
name, value );
} else {
value = name;
}
view.setText( value );
layout.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
m_cb.itemClicked( rowid );
}
} );
LinearLayout list =
(LinearLayout)layout.findViewById( R.id.player_list );
boolean haveATurn = false;
boolean haveALocalTurn = false;
boolean[] isLocal = new boolean[1];
for ( int ii = 0; ii < summary.nPlayers; ++ii ) {
ExpiringLinearLayout tmp = (ExpiringLinearLayout)
m_factory.inflate( R.layout.player_list_elem, null );
view = (TextView)tmp.findViewById( R.id.item_name );
view.setText( summary.summarizePlayer( ii ) );
view = (TextView)tmp.findViewById( R.id.item_score );
view.setText( String.format( " %d", summary.scores[ii] ) );
boolean thisHasTurn = summary.isNextToPlay( ii, isLocal );
if ( thisHasTurn ) {
haveATurn = true;
if ( isLocal[0] ) {
haveALocalTurn = true;
}
}
tmp.setPct( m_handler, thisHasTurn, isLocal[0],
summary.lastMoveTime );
list.addView( tmp, ii );
}
view = (TextView)layout.findViewById( R.id.state );
view.setText( state );
view = (TextView)layout.findViewById( R.id.modtime );
long lastMoveTime = summary.lastMoveTime;
lastMoveTime *= 1000;
view.setText( m_df.format( new Date( lastMoveTime ) ) );
int iconID;
ImageView marker =
(ImageView)layout.findViewById( R.id.msg_marker );
CommsConnType conType = summary.conType;
if ( CommsConnType.COMMS_CONN_RELAY == conType ) {
iconID = R.drawable.relaygame;
} else if ( CommsConnType.COMMS_CONN_BT == conType ) {
iconID = android.R.drawable.stat_sys_data_bluetooth;
} else if ( CommsConnType.COMMS_CONN_SMS == conType ) {
iconID = android.R.drawable.sym_action_chat;
} else {
iconID = R.drawable.sologame;
}
marker.setImageResource( iconID );
view = (TextView)layout.findViewById( R.id.role );
String roleSummary = summary.summarizeRole();
if ( null != roleSummary ) {
view.setText( roleSummary );
} else {
view.setVisibility( View.GONE );
}
boolean expanded = DBUtils.getExpanded( m_context, rowid );
layout.update( m_handler, expanded, summary.lastMoveTime,
haveATurn, haveALocalTurn );
}
}
}

View file

@ -0,0 +1,115 @@
/* -*- compile-command: "cd ../../../../../; ant debug install"; -*- */
/*
* Copyright 2009-2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
public class GameListItem extends LinearLayout
implements View.OnClickListener {
private Context m_context;
private boolean m_loaded;
private long m_rowid;
private View m_hideable;
private ExpiringTextView m_name;
private boolean m_expanded, m_haveTurn, m_haveTurnLocal;
private long m_lastMoveTime;
private ImageButton m_expandButton;
private Handler m_handler;
public GameListItem( Context cx, AttributeSet as )
{
super( cx, as );
m_context = cx;
m_loaded = false;
m_rowid = DBUtils.ROWID_NOTFOUND;
m_lastMoveTime = 0;
}
public void update( Handler handler, boolean expanded,
long lastMoveTime, boolean haveTurn,
boolean haveTurnLocal )
{
m_handler = handler;
m_expanded = expanded;
m_lastMoveTime = lastMoveTime;
m_haveTurn = haveTurn;
m_haveTurnLocal = haveTurnLocal;
m_hideable = (LinearLayout)findViewById( R.id.hideable );
m_name = (ExpiringTextView)findViewById( R.id.game_name );
m_expandButton = (ImageButton)findViewById( R.id.expander );
m_expandButton.setOnClickListener( this );
showHide();
}
public void setLoaded( boolean loaded )
{
if ( m_loaded != loaded ) {
m_loaded = loaded;
// This should be enough to invalidate
findViewById( R.id.view_unloaded )
.setVisibility( loaded ? View.GONE : View.VISIBLE );
findViewById( R.id.view_loaded )
.setVisibility( loaded ? View.VISIBLE : View.GONE );
}
}
public boolean isLoaded()
{
return m_loaded;
}
public void setRowID( long rowid )
{
m_rowid = rowid;
}
public long getRowID()
{
return m_rowid;
}
// View.OnClickListener interface
public void onClick( View view ) {
m_expanded = !m_expanded;
DBUtils.setExpanded( m_rowid, m_expanded );
showHide();
}
private void showHide()
{
m_expandButton.setImageResource( m_expanded ?
R.drawable.expander_ic_maximized :
R.drawable.expander_ic_minimized);
m_hideable.setVisibility( m_expanded? View.VISIBLE : View.GONE );
m_name.setBackgroundColor( android.R.color.transparent );
m_name.setPct( m_handler, m_haveTurn && !m_expanded,
m_haveTurnLocal, m_lastMoveTime );
}
}

View file

@ -282,7 +282,8 @@ public class GamesList extends XWListActivity
}
});
m_adapter = new GameListAdapter( this, new Handler(), this );
String field = CommonPrefs.getSummaryField( this );
m_adapter = new GameListAdapter( this, new Handler(), this, field );
setListAdapter( m_adapter );
NetUtils.informOfDeaths( this );
@ -391,11 +392,6 @@ public class GamesList extends XWListActivity
}
// GameListAdapter.LoadItemCB interface
public void itemLoaded( long rowid )
{
onContentChanged();
}
public void itemClicked( long rowid )
{
// We need a way to let the user get back to the basic-config

View file

@ -41,8 +41,11 @@ public abstract class XWListAdapter implements ListAdapter {
public boolean areAllItemsEnabled() { return true; }
public boolean isEnabled( int position ) { return true; }
public int getCount() { return m_count; }
public Object getItem( int position ) { return null; }
public long getItemId(int position) { return position; }
public int getItemViewType(int position) { return 0; }
public int getItemViewType( int position ) {
return ListAdapter.IGNORE_ITEM_VIEW_TYPE;
}
public int getViewTypeCount() { return 1; }
public boolean hasStableIds() { return true; }
public boolean isEmpty() { return getCount() == 0; }