Java 在 Android 中在运行时更新视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4503458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 18:06:49  来源:igfitidea点击:

Update View at runtime in Android

javaandroiduser-interfaceviewhandler

提问by ferostar

The example is pretty straightforward: i want to let the user know about what the app is doing by just showing a text (canvas.drawText()). Then, my first message appears, but not the other ones. I mean, i have a "setText" method but it doesn't updates.

这个例子非常简单:我想让用户通过只显示一个文本(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");
}

The view's text drawing works by doing just a drawText in onDraw();, so setText changes the text but doesn't show it.

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

Someone recommended me replacing the view with a SurfaceView, but it would be alot of trouble for just a couple of updates, SO... how the heck can i update the view dinamically at runtime?

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

It should be quite simple, just showing a text for say 2 seconds and then the main thread doing his stuff and then updating the text...

它应该很简单,只显示一个文本 2 秒钟,然后主线程做他的事情,然后更新文本......

Thanks!

谢谢!

Update:

更新:

I tried implementing handler.onPost(), but is the same story all over again. Let me put you the code:

我尝试实现 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");
}       
}

And:

和:

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

Although splash is in other thread, i put a sleep on the main thread, i use the handler to manage UI and everything, it doesn't changes a thing, it only shows the last update.

虽然飞溅在其他线程中,但我在主线程上休眠,我使用处理程序来管理 UI 和所有内容,它不会改变任何事情,它只显示最后一次更新。

采纳答案by Dan Breslau

I haven't hit this yet, but I think the usual pattern is to do lengthy initialization in a background thread, and use Handler.post()to update the UI. See http://developer.android.com/reference/android/widget/ProgressBar.htmlfor a different, but possibly related, example.

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

Also see this answer, especially the first paragraph:

另请参阅此答案,尤其是第一段:

The problem is most likely that you are running the splash screen (some sort of Dialog such as ProgressDialog I assume) in the same thread as all the work being done. This will keep the view of the splash screen from being updated, which can keep it from even getting displayed to the screen. You need to display the splash screen, kick off an instance of AsyncTask to go download all your data, then hide the splash screen once the task is complete.

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

Update(based on your update and your comment): You are not supposed to update the UI in any thread except the one where your Activity is created. Why is it impossible for you to load your resources in a background thread?

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

回答by Franco

i suppose that your view is an extended view and you call onDraw for drawing the view, so, maybe the view isn′t 'refresh' their state, so try this

我想你的视图是一个扩展视图,你调用 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();
}

回答by Nikolay Ivanov

First: onCreateis executed on main UI thread of application so no UI updates until you leave it. Basically you need one thread to execute long running tasks and some mechanism to push updates into the UI.
Most usual approach is to extend AsyncTask see this linkfor further info

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