【问题标题】:Textview won't display data which has been updated in model (MVC)Textview 不会显示模型(MVC)中已更新的数据
【发布时间】:2013-03-03 22:26:39
【问题描述】:

我尝试了以下方法来尝试从模型中更新 TextView:

  1. TextChangeListeners - 错误
  2. 其他主题
  3. 异步任务
  4. 添加了更新数据的刷新按钮,我强制点击

场景如下:

  1. 标准线程运行,每秒更新模型 (MVC) 对象,运行良好。
  2. 当模型对象更新时,它会通知所有实现“观察者”的类。
  3. 我的 GolfHomeScreen 扩展了 Activity 并实现了 Observer(代码如下)。
  4. GolfHomeScreen.update(Observable observable,Object data)方法运行良好。它按预期每秒执行一次,并 S.O.P 正确的数据(参见 --> //* #1 *)。
  5. 然后这会启动一个线程。我在这个网站上读到,你必须使用 UI 线程来执行更新小部件的代码,然后运行“runOnUiThread”方法 - 代码看起来像我在下面所做的,但我发现它有点难以理解。无论如何,这个线程运行(参见 --> //* #2 )然后执行方法 onClick(View v) (参见 --> // # 3 *)。
  6. System.out.println("driverType :" + mvcModel.getDriverName());(参见 --> //* #4 *)完美运行。
  7. //* #5 * - 必须更新,但不会。
  8. 如果我实际单击按钮,数据会正确显示在屏幕上。我唯一的猜测是屏幕不能在强制点击时刷新,否则我没有使用 UI 线程进行更新。

注意:如果下面的代码缺少某些内容,那是因为我删除了大量代码以简化对正在发生的事情的理解。

public class GolfHomeScreen extends Activity implements Observer
{
    GolfHomeScreen golfHomeScreen = null;
    TextView driverName = null; // Type of driver used by golfer (eg: 1 wood)
    Button refreshData = null;

  @Override public void onClick(View v) //*** #3 ***
  {
    if ((v.getId()) == 12345) // ID of wood (12345 = 1 wood)
    {
                    //*** #4 ***
        System.out.println("driverType              :" + mvcModel.getDriverName()); //THIS PRINTS OUT THE LATEST DATA!!!

                    //*** #5 ***
                    driverName.setText(String.valueOf(mvcModel.getDriverName()));   //THIS DOESN'T AFFECT THE SCREEN?? WHY  :-(
    }
  }

  @Override public void onCreate(Bundle savedInstanceState)
  {
    golfHomeScreen = this;
    refreshData = indViewById(R.id.golfhomescreen_button_refreshData);
    driverName = (TextView) findViewById(R.id.golfhomescreen_text_drivername);
  }

  @Override public void update(Observable observable, Object data)
  {
     // #1 ***
    System.out.println("driverType              :" + mvcModel.getDriverName());

    golfHomeScreen.runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            refreshData.performClick(); //*** #2 ***
        }
    });
  }

}

【问题讨论】:

    标签: android multithreading android-activity action


    【解决方案1】:

    我会提出一些建议和一些修复,希望您的问题会消失。 我这么说是因为从概念上讲你确实有一些错误的东西,而我的回答是修正这些概念:

    • 删除GolfHomeScreen golfHomeScreen = null;golfHomeScreen = this; 你不需要引用自身的对象。这只是在制造混乱。这条线golfHomeScreen.runOnUiThread(new Runnable() 你应该打电话给runOnUiThread(new Runnable()
    • System.out.pr*** 更改为Log.d(TAG, MESSAGE); 只是因为这是Android 专门的转储日志方式,它对您的结果并不重要。它比标准 Java System.out 更好,因为它允许您按 TAG 和严重性过滤这些日志。
    • 切勿调用refreshData.performClick(); 或任何类似的方法,因为您希望执行该按钮内的操作。如果您希望某件事从多个来源发生,请创建一个方法doThatThing(),将操作放入其中,然后从ClickUpdate 调用该方法。你正在做的方式有点像“Rube Goldberg 机器”,它正在更新一些东西,点击一个按钮,改变一个文本。只需更改文本即可。
    • 永远不要将视图ID与数字进行比较if ((v.getId()) == 12345)从XML创建的视图ID是系统在编译过程中生成的,你无法知道它是否是一个固定的数字。您应该与该视图的静态 int ID 进行比较,如下所示:if(v.getId() == R.id.golfhomescreen_text_drivername)。如果视图不是在 XML 中创建的(这里不是这种情况),您可以与实际对象进行比较 if(v.equals(driverName))

    通过这些更改,我相信您的代码会起作用。如果确实如此,请务必让我知道并标记为正确答案。

    【讨论】:

    • 忽略上面的评论 - 我需要正确地对其进行全面测试,我在 mo 的旧笔记本电脑上运行它并且无法正确测试它,但它看起来不会工作!!!当我回到我的 dec 机器上时,我会在一段时间内报告更多信息!!!
    • 它不起作用 - 我已经改变了我的架构,因为它变得太复杂了!!!为了自己好我固执!!!感谢您的回复
    猜你喜欢
    • 1970-01-01
    • 2019-02-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多