我正在尝试通过构建应用程序来学习Android应用程序编程,以便在Hearts中保持得分。游戏本身的数据按以下层次排列:
Game
代表整场比赛
Vector
代表游戏中每只手的Round
个对象。
Vector
个BoxScore
个对象代表手中的每个方框分数。此数据在ScoreTableActivity
中由TableLayout
显示,其中每个TableRow
包含标记单元格,每个BoxScore
对象的单元格以及指示的单元格手的总分是否正确。表格的最后一行显示每个玩家的总分,通过将每列中的分数加起来。
我有一个方法drawScoreTable()
,它在活动的onCreate()
方法中调用,并且按预期工作。在为分数创建单元格时,我有以下内容来捕获对这些单元格的点击:
TextView txtScore = ScoreTableCellFactory.getBoxScoreCell( this, oScore ) ;
txtScore.setOnClickListener(this) ;
rowRound.addView( txtScore ) ; // rowRound is a TableRow.
ScoreTableActivity
本身实现OnClickListener
以支持此功能;只有盒子分数是可点击的。活动的onClick()
方法如下:
public void onClick( View oClicked )
{
// A reference to the score object is built into the view's tag.
BoxScore oScore = (BoxScore)oClicked.getTag() ;
// Create the dialog where the user modifies the box score.
BoxScoreEditorDialogFragment fragBoxScoreDialog = new BoxScoreEditorDialogFragment() ;
fragBoxScoreDialog.setBoxScore(oScore) ;
fragBoxScoreDialog.setRules(m_oGame.getRules()) ;
fragBoxScoreDialog.show(getFragmentManager(), "fragBoxScore") ;
// We passed the BoxScore object across to the editor dialog by
// reference (It's Java, after all), so we should be able to
// update the text of the box score cell by simply re-examining
// the data in that BoxScore object.
((TextView)oClicked).setText(Integer.toString(oScore.getScore())) ;
// And it's at this point that something else is clearly needed.
}
此网站上的其他答案表明,setText()
方法足以说服渲染器刷新单元格,但事实并非如此。使用上面的代码,在单击单元格的 next 时间之前,单元格不会刷新。
我尝试在单元格本身,其父行和整个invalidate()
上使用TableLayout
方法,但这些方法都没有任何效果。我甚至尝试使用removeAllViews()
方法,然后再次调用drawScoreTable()
;甚至 直到下一次点击事件被捕获后才更新屏幕。
如果我将平板电脑倾斜到新的方向(从纵向到横向,反之亦然),则会重新创建整个活动,新表格会显示所有正确的数据。我宁愿不采取完全破坏和重建整个表格的方式,但我认为这就是我使用removeAllViews()
甚至所做的无法正常工作。
部分问题源于数据更新来自对话框。这是一个与基本活动不同的竞技场,因此对话框需要在退出时触发。
我的代码更专业,但我在下面创建了一个通用示例,为您提供了一个关于正在发生的事情的无上下文的想法。它实际上是基于official Android reference for "Dialogs",我不幸在发布此问题后才阅读。
/**
* Callers of this dialog must implement this interface to catch the events
* that are returned from it.
*/
public interface Listener
{
public void onDialogCommit( MyDialogClass fragDialog ) ;
}
在主要活动课程的开头:
public class MyBaseActivity
extends Activity
implements OnClickListener, MyDialogClass.Listener
我保留了OnClickListener
,因为我的代码还会捕获触发对话框创建的点击。如果使用内联内部类处理此问题,那么您的OnClickListener
子句中不需要implements
。
这是官方Android示例中遗漏的部分 - 您对此侦听器方法做了什么?嗯,答案非常糟糕。
public void onDialogCommit( MyDialogClass oDialog )
{
TableLayout oLayout = (TableLayout)(findViewById(R.id.tbl_MyTableLayout)) ;
// This is where things still seem more ugly than they should.
oLayout.removeAllViews() ;
this.recreateEverything() ; // assumes you've written a method for this
}
即使在创建这个新的界面和侦听器模型之后,使用invalidate()
和requestLayout()
方法仍然不够。我不得不removeAllViews()
并回想起重绘整个活动的方法。我仍然相信,当然,有一种更有效的方式,但我还没有找到它。