(Android)如何更新TableLayout的显示内容以响应事件?

时间:2013-09-01 02:47:51

标签: java android tablelayout

我正在尝试通过构建应用程序来学习Android应用程序编程,以便在Hearts中保持得分。游戏本身的数据按以下层次排列:

  • Game代表整场比赛
    • Vector代表游戏中每只手的Round个对象。
      • VectorBoxScore个对象代表手中的每个方框分数。

此数据在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",我不幸在发布此问题后才阅读。

步骤1:为对话框创建自定义侦听器类。

/**
 * 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 ) ;
}

第2步:在基础活动中实现监听器。

在主要活动课程的开头:

public class MyBaseActivity
 extends Activity
 implements OnClickListener, MyDialogClass.Listener

我保留了OnClickListener,因为我的代码还会捕获触发对话框创建的点击。如果使用内联内部类处理此问题,那么您的OnClickListener子句中不需要implements

步骤3:在基本活动中实现监听器的界面。

这是官方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()并回想起重绘整个活动的方法。我仍然相信,当然,有一种更有效的方式,但我还没有找到它。

0 个答案:

没有答案