如何在Android TextView中更改文本

时间:2010-02-19 22:50:39

标签: 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()方法阻塞有关。那么有人可以告诉我如何“异步”实现定时器吗?

感谢。

8 个答案:

答案 0 :(得分:147)

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

1)onCreate 准备您的活动 - 因此,在此方法完成之前,您在此处所做的任何操作都不会显示!例如 - 您将永远无法在此处更改TextView的文字超过一个时间,因为只会绘制最后一个更改,因此对用户可见!

2)请注意,Android程序默认只在 ONE 主题中运行!因此:永远不要在主线程中使用负责UI的Thread.sleep()Thread.wait()! (请阅读"Keep your App Responsive"了解更多信息!)

您的活动初始化的作用是:

  • 无缘无故地创建了新的TextView对象t
  • 您稍后会在变量TextView中选择您的布局t
  • 您设置了t的文字(但请记住:只有 onCreate()完成后才会显示,并且应用程序的主要事件循环会运行!)< / LI>
  • 您在onCreate方法中等待 10秒 - 此绝不能完成,因为它会停止所有UI活动并且肯定会强制ANR(应用程序)没有回复,请参阅上面的链接!)
  • 然后您设置了另一个文本 - 只要您的onCreate()方法完成并且其他几个Activity lifecycle方法已处理完毕,就会显示此文本!

解决方案:

  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. 将此runnable作为处理程序安装,可以在onCreate()中安装(但请阅读下面的建议):

    // run the mUpdateUITimerTask's run() method in 10 seconds from now
    mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
    
  4. 建议:确保你知道Activity的生命周期!如果您在onCreate()中执行此类操作,则只有在Activity创建第一次时才会发生这种情况! Android可能会让您的Activity保持更长时间的活着,即使它不可见! 当用户再次“启动”它 - 它仍然存在 - 您将不再看到您的第一个文本了!


    =&GT;始终在onResume()中安装处理程序并在onPause()中禁用它们!否则,当Activity根本不可见时,您将获得“更新”! 在您的情况下,如果您想在重新激活时再次看到第一个文字,则必须在onResume()中设置,而不是onCreate()

答案 1 :(得分:45)

我刚刚在android-discuss google group中发布了这个答案

如果您只是想在视图中添加文字,以便显示“第一步:爆蛋第二步:煎鸡蛋”然后考虑使用t.appendText("Step Two: fry egg");代替t.setText("Step Two: fry egg");

如果你想完全改变TextView中的内容,以便它在启动时说“第一步:爆蛋”然后它会说“第二步:煎鸡蛋”,你可以随时使用

Runnable example sadboy给了

祝你好运

答案 2 :(得分:14)

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

t=new TextView(this); 

你可以这样做

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 :(得分:6)

@ user264892

我发现在使用String变量时,我需要使用字符串“”加前缀或显式转换为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...");

答案 4 :(得分:3)

根据您的建议,我使用句柄和runnables使用“计时器”切换/更改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);      
    ...
}

答案 5 :(得分: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(); 
}

就是这样。

答案 6 :(得分:0)

将文本设置为sam textview两次将覆盖第一个书面文本。 所以当我们第二次使用settext时,我们只需附加新的字符串,如

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

答案 7 :(得分:0)

@Zordid @Imbda答案很棒,但我发现如果我把

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

在run()方法和

mHandler.postDelayed(mUpdateUITimerTask, 0);
在onCreate方法中

使事物不断更新。