2010-02-19 95 views
88

我试图做到这一点如何更改文本在Android中的TextView

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    t=new TextView(this); 

    t=(TextView)findViewById(R.id.TextView01); 
    t.setText("Step One: blast egg"); 

    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    t.setText("Step Two: fry egg"); 

但由于某些原因,只有第二个文本显示,当我运行它。我认为这可能与Thread.sleep()方法阻塞有关。那么有人可以告诉我如何实现“异步”的计时器?

谢谢。

+2

它只显示第二行的原因是因为'.setText()'用你告诉它设置的文本替换了整个“小部件”;包括你已经放在那里的文字。 – georgiaboy82 2015-06-01 04:11:46

回答

43

我刚刚发布了Android,讨论谷歌集团在这个答案

如果你只是想将文本添加到视图,以便它显示“步骤一:爆蛋第二步:炒鸡蛋”然后考虑使用t.appendText("Step Two: fry egg");代替t.setText("Step Two: fry egg");

如果你想彻底改变什么是在TextView以便它说:“第一步:爆蛋”的启动和然后它说“第二步:炒e GG”经过一段时间以后,你可以随时使用

Runnable的例子sadboy给

好运

14

的新文本视图的第一行是不必要的

​​

你可以做到这一点

TextView t = (TextView)findViewById(R.id.TextView01); 

至于那个睡在这一个后台线程是一个例子,但我认为有一个更好的计时器。这里是使用定时器一个很好的例子,一个链接,而不是 http://android-developers.blogspot.com/2007/11/stitch-in-time.html

Thread thr = new Thread(mTask); 
    thr.start(); 
} 

Runnable mTask = new Runnable() { 
    public void run() { 
     // just sleep for 30 seconds. 
        try { 
         Thread.sleep(3000); 
         runOnUiThread(done); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
     } 
    }; 

    Runnable done = new Runnable() { 
     public void run() { 
        // t.setText("done"); 
      } 
     }; 
3

按你的意见,我使用手柄,可运行切换使用/修改的TextView的内容“计时器”。出于某种原因,运行时,应用程序总是跳过第二步(“第二步:炒鸡蛋”),并只显示最后一步(第三步)(“第三步:服务鸡蛋”)。

TextView t; 
private String sText; 

private Handler mHandler = new Handler(); 

private Runnable mWaitRunnable = new Runnable() { 
    public void run() { 
     t.setText(sText); 
    } 
}; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    mMonster = BitmapFactory.decodeResource(getResources(), 
      R.drawable.monster1); 

    t=new TextView(this); 
    t=(TextView)findViewById(R.id.TextView01); 

    sText = "Step One: unpack egg"; 
    t.setText(sText); 

    sText = "Step Two: fry egg";   
    mHandler.postDelayed(mWaitRunnable, 3000); 

    sText = "Step three: serve egg"; 
    mHandler.postDelayed(mWaitRunnable, 4000);  
    ... 
} 
+1

这不能工作!只有一个处理程序 - 你想如何让现有的mWaitRunnable跑步者“知道”sText曾经设置为“第二步”,然后设为“第三步”? 当它被称为第一次(3秒后) - sText的值只是“第三步”! 在尝试Android编程之前,您应该熟悉基本的Java技巧! :-) – Zordid 2010-02-24 12:21:29

+0

实际上我最后做的是在runnable里面添加了一个计数器,如果它是1,那么文本就是这个,如果是2,文本就是这个,等等。 – user270811 2010-03-17 10:21:42

145

onCreate()方法有几个巨大的缺陷:

1)onCreate准备你的活动 - 让你在这里做将作出可见给用户,直到这个方法完成什么!例如 - 您将永远无法在这里更改TextView的文本超过ONE时间,因为只有最后的更改将被绘制,因此对用户可见!

2)请记住,一个Android程序将 - 默认 - 运行在ONE只有线程!因此:从不在您的主线程中使用Thread.sleep()Thread.wait(),这是您的UI的责任! (阅读"Keep your App Responsive"了解更多信息!)

你的初始化你的活动所做的是:

  • 没有任何理由,你创建一个新的TextView对象t
  • 稍后在变量t中选择布局的TextView
  • 您设置的t文本(但要记住:它会之后onCreate()饰面和应用程序运行的主事件循环只显示!)
  • 您等待10秒onCreate方法中 - 此绝不能完成,因为它会停止所有UI活动,并且肯定会强制ANR(应用程序未响应,请参阅上面的链接!)
  • 然后您设置另一个文本 - 只要您的onCreate()方法完成和其他几个Activity lifecycle方法en处理!

解决办法:

  1. 设置文本仅在onCreate()一次 - 这必须是要看得见的第一个文本。

  2. 创建RunnableHandler

    private final Runnable mUpdateUITimerTask = new Runnable() { 
        public void run() { 
         // do whatever you want to change here, like: 
         t.setText("Second text to display!"); 
        } 
    }; 
    private final Handler mHandler = new Handler(); 
    
  3. 安装此可运行的处理程序,可能在onCreate()(但是看了下面我的建议):

    // run the mUpdateUITimerTask's run() method in 10 seconds from now 
    mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 
    

忠告:是确定你知道Activity的生命周期!如果你在onCreate()这样的东西,这只会发生在你的Activity创建第一时间! Android可能会让您的Activity长时间保持活动状态,即使它不可见! 当用户再次“启动”它 - 它仍然存在 - 你不会再看到你的第一个文本!


=>总是在onResume()安装处理器和onPause()禁用它们!否则,当你的Activity根本不可见时,你会得到“更新”! 对于您的情况,如果您想在重新激活时再次看到第一个文本,则必须将其设置为onResume()而不是onCreate()

6

@ user264892

我发现,使用字符串变量,当我需要用任何的“”一个字符串前缀或显式转换为CharSequence的。

所以不是:

String Status = "Asking Server..."; 
txtStatus.setText(Status); 

尝试:

String Status = "Asking Server..."; 
txtStatus.setText((CharSequence) Status); 

或:

String Status = "Asking Server...";  
txtStatus.setText("" + Status); 

,或者因为你的字符串不是动态的,甚至更好:

txtStatus.setText("AskingServer..."); 
0

:)您以错误的方式使用该线程。 只需执行以下操作:

private void runthread() 
{ 

splashTread = new Thread() { 
      @Override 
      public void run() { 
       try { 
        synchronized(this){ 

         //wait 5 sec 
         wait(_splashTime); 
        } 

       } catch(InterruptedException e) {} 
       finally { 
        //call the handler to set the text 
       } 
      } 
     }; 

     splashTread.start(); 
} 

就是这样。

0

将文本设置为sam textview会覆盖第一个写入的文本。 所以第二遍的时候,我们使用的setText我们只是追加新的字符串像

textview.append("Step Two: fry egg"); 
0

@Zordid @Iambda答案是伟大的,但我发现,如果我把

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 

在run()方法和

mHandler.postDelayed(mUpdateUITimerTask, 0); 

在onCreate方法使事情不断更新。