在 Android 运行时更新视图

Posted

技术标签:

【中文标题】在 Android 运行时更新视图【英文标题】:Update View at runtime in Android 【发布时间】:2010-12-21 20:12:36 【问题描述】:

这个例子非常简单:我想让用户知道应用程序正在做什么,只显示一个文本 (canvas.drawText())。然后,出现了我的第一条消息,但没有出现其他消息。我的意思是,我有一个“setText”方法,但它没有更新。

onCreate(Bundle bundle) 
    super.onCreate(bundle);
    setContentView(splash); // splash is the view class
    loadResources();
    splash.setText("this");
    boundWebService();
    splash.setText("that"):
    etc();
    splash.setText("so on");

视图的文本绘制通过在 onDraw(); 中仅执行 drawText 来工作,因此 setText 更改了文本但不显示它。

有人建议我用 SurfaceView 替换视图,但是仅仅进行几次更新就会很麻烦,所以......我怎么能在运行时动态地更新视图?

应该很简单,只显示一个文本 2 秒,然后主线程执行他的操作,然后更新文本...

谢谢!

更新:

我尝试实现 handler.onPost(),但又是同一个故事。让我把代码给你:

public class ThreadViewTestActivity extends Activity 

Thread t;
Splash splash;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    splash = new Splash(this);
    t = new Thread(splash);
    t.start();

    splash.setTextow("OA");
    try  Thread.sleep(4000);  catch (InterruptedException e)  
    splash.setTextow("LALA");
       

还有:

public class Splash implements Runnable 

Activity activity;
final Handler myHandler = new Handler();

public Splash(Activity activity) 
    this.activity=activity;
   

@Override
public void run() 
    // TODO Auto-generated method stub



public synchronized void setTextow(final String textow) 
    // Wrap DownloadTask into another Runnable to track the statistics
    myHandler.post(new Runnable() 
        @Override
        public void run() 
            TextView t = (TextView)activity.findViewById(R.id.testo);
            t.setText(textow);
            t.invalidate(); 
                           
    );


虽然splash在其他线程,但我在主线程上设置了一个睡眠,我使用处理程序来管理UI和所有东西,它不会改变任何东西,它只显示最后一次更新。

【问题讨论】:

【参考方案1】:

我还没有遇到这个问题,但我认为通常的模式是在后台线程中进行冗长的初始化,并使用Handler.post() 来更新 UI。请参阅 http://developer.android.com/reference/android/widget/ProgressBar.html 了解不同但可能相关的示例。

另见this answer,尤其是第一段:

这个问题很可能是你 正在运行启动画面(一些 诸如 ProgressDialog 之类的对话框 我假设)在同一个线程中 正在做的工作。这将保持 启动画面的视图 正在更新,这可以防止它 甚至显示在屏幕上。 您需要显示启动画面, 启动 AsyncTask 的实例以 去下载你所有的数据,然后隐藏 任务完成后的启动画面 完成。

更新(基于您的更新和您的评论):您不应该在任何线程中更新 UI,除了创建您的 Activity 的线程。为什么你无法在后台线程中加载资源?

【讨论】:

感谢您的回答!我知道它一定是“与处理程序相关的”,但问题是,我必须以这种方式执行 loadResources() 和 setText(),我不能将两者都放在 Handler 中并让 UI 线程知道发生了什么.【参考方案2】:

首先:onCreate 在应用程序的主 UI 线程上执行,因此在您离开之前不会更新 UI。基本上,您需要一个线程来执行长时间运行的任务以及一些将更新推送到 UI 的机制。 最常用的方法是扩展 AsyncTask 请参阅this link 了解更多信息

【讨论】:

【参考方案3】:

我想你的视图是一个扩展视图,你调用 onDraw 来绘制视图,所以,也许视图没有“刷新”它们的状态,所以试试这个

onCreate(Bundle bundle) 
    setContentView(splash); // splash is the view class

    loadResources();
    splash.setText("this");
    splash.invalidate();
    boundWebService();
    splash.setText("that"):
    splash.invalidate();
    etc();
    splash.setText("so on");
    splash.invalidate();

【讨论】:

试过了,现在只显示最后一个(“等等”文本)。 好吧,现在不是绘制第一个视图,而是绘制最后一个视图,您的操作(loadResources()...等)运行速度太快了?在您的绘图方法上放置一个 Log.i() 条目以查看正在绘制的文本,我想该视图正在绘制所有文本... 虽然我在 onDraw 中输入了 Log.i(splashText),但 logcat 中没有显示任何内容。

以上是关于在 Android 运行时更新视图的主要内容,如果未能解决你的问题,请参考以下文章

当android应用程序后台运行时如何在android中隐藏视图(在后台运行时不停止android拍摄快照)[重复]

加载视图后如何在运行时更新 UITableView

在 Android 运行时从 xml 文件设置视图

在运行时更新 QStackedWidget 内容

如何在运行时更改动态添加的 Android 视图中的数据

Android - 多个视图或运行时片段替换​​?