如何在Android TextView中更改文本


91

我试图做到这一点

@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

Answers:


45

我刚刚在Android讨论Google组中发布了此答案

如果您只是想在视图中添加文本,使其显示为“第一步:炸鸡蛋,第二步:炸鸡蛋”,请考虑使用 t.appendText("Step Two: fry egg"); 而不是t.setText("Step Two: fry egg");

如果您想彻底改变 TextView以便在启动时显示“第一步:炸鸡蛋”,然后在每次显示“第二步:炸鸡蛋”,则可以随时使用

Sadboy给的可运行的例子

祝好运


146

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

1)onCreate 准备活动 -因此,在此方法完成之前,用户在此处所做的任何操作都不会对用户可见。例如-你将永远无法改变TextView这里的文本超过一周时间,只有最后的改动将被吸引,从而对用户可见!

2)请记住,默认情况下,Android程序只能在一个线程中运行!因此:切勿在对您的UI负责的主线程中使用Thread.sleep()或使用Thread.wait()它!(有关更多信息,阅读“保持应用程序自适应”!)

您对Activity进行的初始化是:

  • 无缘无故创建一个新TextView对象t
  • 您可以稍后TextView在变量中选择布局t
  • 您设置的文本t(但请注意:只有 onCreate()完成操作并且应用程序的主事件循环运行后,它才会显示!)
  • 您在方法中等待10秒钟onCreate - 绝不能执行此操作,因为它会停止所有UI活动,并且肯定会强制执行A​​NR(应用程序无响应,请参见上面的链接!)
  • 然后设置另一文本- onCreate()方法完成并且处理了其他几个Activity生命周期方法后,将立即显示该文本!

解决方案:

  1. 仅输入一次文本onCreate()-这必须是第一个应可见的文本。

  2. 创建一个Runnable和一个Handler

    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()


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");
            }
        };

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...");

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

其实我最后也加入了可运行的内部计数器,如果是1,文本将是这个,如果是2,文本将是这个,等
user270811

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方法中使事物保持更新。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.