在 Android 中运行时更新视图

发布于 2024-10-08 19:57:52 字数 1893 浏览 1 评论 0原文

这个例子非常简单:我想让用户通过显示文本(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和所有内容,它不会改变任何东西,它只显示最后的更新。

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.

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.

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?

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...

Thanks!

Update:

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

打小就很酷 2024-10-15 19:57:52

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

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

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

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

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.html for a different, but possibly related, example.

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.

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?

娜些时光,永不杰束 2024-10-15 19:57:52

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

First: onCreate is 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 link for further info

○愚か者の日 2024-10-15 19:57:52

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

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

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文