work around problems locating GameListItems when it's time to

invalidate them by adding static list of those needing invalidating
and checking it in a new onDraw override.
This commit is contained in:
Eric House 2012-12-14 18:46:54 -08:00
parent 646ec65d66
commit 3c4f266b8f
2 changed files with 79 additions and 24 deletions

View file

@ -90,10 +90,11 @@ public class GameListAdapter extends XWListAdapter {
public void inval( long rowid ) public void inval( long rowid )
{ {
GameListItem child = getItemFor( rowid ); GameListItem child = getItemFor( rowid );
if ( null != child ) { if ( null != child && child.getRowID() == rowid ) {
child.forceReload(); child.forceReload();
} else { } else {
DbgUtils.logf( "no child for rowid %d", rowid ); DbgUtils.logf( "no child for rowid %d", rowid );
GameListItem.inval( rowid );
m_list.invalidate(); m_list.invalidate();
} }
} }

View file

@ -21,8 +21,10 @@
package org.eehouse.android.xw4; package org.eehouse.android.xw4;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Handler; import android.os.Handler;
// import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.ImageButton; import android.widget.ImageButton;
@ -31,6 +33,8 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
// import java.util.Iterator;
import org.eehouse.android.xw4.jni.GameSummary; import org.eehouse.android.xw4.jni.GameSummary;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
@ -38,6 +42,8 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
public class GameListItem extends LinearLayout public class GameListItem extends LinearLayout
implements View.OnClickListener { implements View.OnClickListener {
private static HashSet<Long> s_invalRows = new HashSet<Long>();
private Context m_context; private Context m_context;
private boolean m_loaded; private boolean m_loaded;
private long m_rowid; private long m_rowid;
@ -50,6 +56,7 @@ public class GameListItem extends LinearLayout
private GameSummary m_summary; private GameSummary m_summary;
private GameListAdapter.LoadItemCB m_cb; private GameListAdapter.LoadItemCB m_cb;
private int m_fieldID; private int m_fieldID;
private int m_loadingCount;
public GameListItem( Context cx, AttributeSet as ) public GameListItem( Context cx, AttributeSet as )
{ {
@ -58,6 +65,7 @@ public class GameListItem extends LinearLayout
m_loaded = false; m_loaded = false;
m_rowid = DBUtils.ROWID_NOTFOUND; m_rowid = DBUtils.ROWID_NOTFOUND;
m_lastMoveTime = 0; m_lastMoveTime = 0;
m_loadingCount = 0;
} }
public void init( Handler handler, long rowid, int fieldID, public void init( Handler handler, long rowid, int fieldID,
@ -73,7 +81,13 @@ public class GameListItem extends LinearLayout
public void forceReload() public void forceReload()
{ {
// DbgUtils.logf( "GameListItem.forceReload: rowid=%d", m_rowid );
m_summary = null; m_summary = null;
setLoaded( false );
// Apparently it's impossible to reliably cancel an existing
// AsyncTask, so let it complete, but drop the results as soon
// as we're back on the UI thread.
++m_loadingCount;
new LoadItemTask().execute(); new LoadItemTask().execute();
} }
@ -82,6 +96,19 @@ public class GameListItem extends LinearLayout
setName(); setName();
} }
@Override
protected void onDraw( Canvas canvas )
{
super.onDraw( canvas );
if ( DBUtils.ROWID_NOTFOUND != m_rowid ) {
synchronized( s_invalRows ) {
if ( s_invalRows.contains( m_rowid ) ) {
forceReload();
}
}
}
}
private void update( boolean expanded, long lastMoveTime, boolean haveTurn, private void update( boolean expanded, long lastMoveTime, boolean haveTurn,
boolean haveTurnLocal ) boolean haveTurnLocal )
{ {
@ -108,15 +135,15 @@ public class GameListItem extends LinearLayout
showHide(); showHide();
} }
private void setLoaded() private void setLoaded( boolean loaded )
{ {
if ( !m_loaded ) { if ( loaded != m_loaded ) {
m_loaded = true; m_loaded = loaded;
// This should be enough to invalidate // This should be enough to invalidate
findViewById( R.id.view_unloaded ) findViewById( R.id.view_unloaded )
.setVisibility( m_loaded ? View.GONE : View.VISIBLE ); .setVisibility( loaded ? View.GONE : View.VISIBLE );
findViewById( R.id.view_loaded ) findViewById( R.id.view_loaded )
.setVisibility( m_loaded ? View.VISIBLE : View.GONE ); .setVisibility( loaded ? View.VISIBLE : View.GONE );
} }
} }
@ -168,16 +195,16 @@ public class GameListItem extends LinearLayout
return state; return state;
} }
private void setData() private void setData( final GameSummary summary )
{ {
if ( null != m_summary ) { if ( null != summary ) {
TextView view; TextView view;
String state = setName(); String state = setName();
setOnClickListener( new View.OnClickListener() { setOnClickListener( new View.OnClickListener() {
@Override @Override
public void onClick( View v ) { public void onClick( View v ) {
m_cb.itemClicked( m_rowid, m_summary ); m_cb.itemClicked( m_rowid, summary );
} }
} ); } );
@ -187,14 +214,14 @@ public class GameListItem extends LinearLayout
boolean haveATurn = false; boolean haveATurn = false;
boolean haveALocalTurn = false; boolean haveALocalTurn = false;
boolean[] isLocal = new boolean[1]; boolean[] isLocal = new boolean[1];
for ( int ii = 0; ii < m_summary.nPlayers; ++ii ) { for ( int ii = 0; ii < summary.nPlayers; ++ii ) {
ExpiringLinearLayout tmp = (ExpiringLinearLayout) ExpiringLinearLayout tmp = (ExpiringLinearLayout)
Utils.inflate( m_context, R.layout.player_list_elem ); Utils.inflate( m_context, R.layout.player_list_elem );
view = (TextView)tmp.findViewById( R.id.item_name ); view = (TextView)tmp.findViewById( R.id.item_name );
view.setText( m_summary.summarizePlayer( ii ) ); view.setText( summary.summarizePlayer( ii ) );
view = (TextView)tmp.findViewById( R.id.item_score ); view = (TextView)tmp.findViewById( R.id.item_score );
view.setText( String.format( " %d", m_summary.scores[ii] ) ); view.setText( String.format( " %d", summary.scores[ii] ) );
boolean thisHasTurn = m_summary.isNextToPlay( ii, isLocal ); boolean thisHasTurn = summary.isNextToPlay( ii, isLocal );
if ( thisHasTurn ) { if ( thisHasTurn ) {
haveATurn = true; haveATurn = true;
if ( isLocal[0] ) { if ( isLocal[0] ) {
@ -202,14 +229,14 @@ public class GameListItem extends LinearLayout
} }
} }
tmp.setPct( m_handler, thisHasTurn, isLocal[0], tmp.setPct( m_handler, thisHasTurn, isLocal[0],
m_summary.lastMoveTime ); summary.lastMoveTime );
list.addView( tmp, ii ); list.addView( tmp, ii );
} }
view = (TextView)findViewById( R.id.state ); view = (TextView)findViewById( R.id.state );
view.setText( state ); view.setText( state );
view = (TextView)findViewById( R.id.modtime ); view = (TextView)findViewById( R.id.modtime );
long lastMoveTime = m_summary.lastMoveTime; long lastMoveTime = summary.lastMoveTime;
lastMoveTime *= 1000; lastMoveTime *= 1000;
DateFormat df = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat df = DateFormat.getDateTimeInstance( DateFormat.SHORT,
@ -219,7 +246,7 @@ public class GameListItem extends LinearLayout
int iconID; int iconID;
ImageView marker = ImageView marker =
(ImageView)findViewById( R.id.msg_marker ); (ImageView)findViewById( R.id.msg_marker );
CommsConnType conType = m_summary.conType; CommsConnType conType = summary.conType;
if ( CommsConnType.COMMS_CONN_RELAY == conType ) { if ( CommsConnType.COMMS_CONN_RELAY == conType ) {
iconID = R.drawable.relaygame; iconID = R.drawable.relaygame;
} else if ( CommsConnType.COMMS_CONN_BT == conType ) { } else if ( CommsConnType.COMMS_CONN_BT == conType ) {
@ -232,7 +259,7 @@ public class GameListItem extends LinearLayout
marker.setImageResource( iconID ); marker.setImageResource( iconID );
view = (TextView)findViewById( R.id.role ); view = (TextView)findViewById( R.id.role );
String roleSummary = m_summary.summarizeRole(); String roleSummary = summary.summarizeRole();
if ( null != roleSummary ) { if ( null != roleSummary ) {
view.setText( roleSummary ); view.setText( roleSummary );
} else { } else {
@ -241,7 +268,7 @@ public class GameListItem extends LinearLayout
boolean expanded = DBUtils.getExpanded( m_context, m_rowid ); boolean expanded = DBUtils.getExpanded( m_context, m_rowid );
update( expanded, m_summary.lastMoveTime, haveATurn, update( expanded, summary.lastMoveTime, haveATurn,
haveALocalTurn ); haveALocalTurn );
} }
} }
@ -256,13 +283,40 @@ public class GameListItem extends LinearLayout
@Override @Override
protected void onPostExecute( GameSummary summary ) protected void onPostExecute( GameSummary summary )
{ {
if ( 0 == --m_loadingCount ) {
m_summary = summary; m_summary = summary;
setData(); setData( summary );
// setLoaded( m_view.getRowID() ); setLoaded( null != m_summary );
setLoaded(); synchronized( s_invalRows ) {
s_invalRows.remove( m_rowid );
// DbgUtils.logf( "LoadItemTask for row %d finished", m_rowid ); }
}
// DbgUtils.logf( "LoadItemTask for row %d finished; "
// + "inval rows now %s",
// m_rowid, invalRowsToString() );
} }
} // class LoadItemTask } // class LoadItemTask
public static void inval( long rowid )
{
synchronized( s_invalRows ) {
s_invalRows.add( rowid );
}
// DbgUtils.logf( "GameListItem.inval(rowid=%d); inval rows now %s",
// rowid, invalRowsToString() );
}
// private static String invalRowsToString()
// {
// String[] strs;
// synchronized( s_invalRows ) {
// strs = new String[s_invalRows.size()];
// Iterator<Long> iter = s_invalRows.iterator();
// for ( int ii = 0; iter.hasNext(); ++ii ) {
// strs[ii] = String.format("%d", iter.next() );
// }
// }
// return TextUtils.join(",", strs );
// }
} }