【问题标题】:Using AsyncTask to Update UI (Layout dynamically)使用 AsyncTask 更新 UI(动态布局)
【发布时间】:2012-09-27 00:17:54
【问题描述】:

以下代码当前在我的 main 的 onCreate() 中运行。我现在只是在测试。我一直试图在 AsyncTask 中完成这项工作,因为目标是以后能够动态更新这些,但似乎无法找到如何做到这一点。我想知道是否有人有一些见识。谢谢!

LinearLayout ObjectLayout = (LinearLayout) findViewById(R.id.LayoutObjects);

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);
    params.height = 140;
    params.width = 140;
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
    for (int i = 0; i < 10; i++) {

        Button btn = new Button(this);
        btn.setLayoutParams(params);
        btn.setPadding(0, 50, 0, 0);
        btn.setTextSize(14);
        btn.setText("MyButton");
        btn.setTextColor(color.Yellow);
        // Drawable image = Drawable.createFromPath("@drawable/add_page");
        // //
        // btn.setBackgroundDrawable(image);

        btn.setBackgroundDrawable(getResources().getDrawable(
                R.drawable.add_page));
        // btn.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);

        ObjectLayout.addView(btn);

    }




private class GetDataTask2 extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {

        // Simulates a background job.

        for (int i = 0; i < 10; i++) {
            publishProgress(btn2);
        }

        return null;
    }

    protected void publishProgress(Button btn2) {
        btn2.setLayoutParams(params2);
        btn2.setPadding(0, 50, 0, 0);
        btn2.setTextSize(14);
        btn2.setText("MyButton yo yo yo ");
        btn2.setTextColor(color.Yellow);

        btn2.setBackgroundDrawable(getResources().getDrawable(
                R.drawable.add_page));
        ObjectLayout2.addView(btn2);
        // Process width and height
    }

    protected void onPostExecute() {
        // Do some stuff here

        // Call onRefreshComplete when the list has been refreshed.

    }
}

这里的代码是我的异步代码,并将布局和按钮创建定义为 mainactivity 中的实例,只是为了测试和理解这一点,但我遇到了错误,我一直在对其进行操作,但似乎没有任何效果。

【问题讨论】:

    标签: java android android-layout user-interface android-asynctask


    【解决方案1】:

    我必须做类似的事情(一次将大约 80-120 个自定义视图膨胀/添加到可滚动布局中),我的 AsyncTask 结构是这样的:

    首先,您需要将ContextLinearLayout 传递给您的AsyncTask。只需为此使用自定义构造函数。

    onPreExecute():显示进度对话框,或显示“忙碌”的内容。

    doInBackground() :像你一样在你的循环中创建按钮,但不要超过那个线程。创造/通货膨胀部分是大部分时间,所以不用担心。在每个循环周期结束时,publishProgress(btn)

    onProgressUpdate():将按钮(从上方传递)设置为您喜欢的方式(文本/填充/等),并将其添加到布局中。

    onPostExecute():关闭你的对话。

    请注意,使用一个线程充气和一个线程布局并不会提高速度。我的从没有 AsyncTask 的大约 2.5 秒到有超过 2 秒。但是,这种方式提供了一个清晰的进度对话框,而不是 UI 在膨胀所有视图时只是挂起。它可能不会更快,但它感觉响应速度更快,这才是真正重要的。

    编辑: 有关自定义构造函数的示例,请查看 this question。它还展示了如何跳过构造函数并将其直接传递给doInBackground() 方法。无论哪种方式都很好。

    【讨论】:

    • “首先,您需要将 Context 和 LinearLayout 传递给 AsyncTask。为此使用自定义构造函数即可。”究竟会是什么样子,抱歉这个愚蠢的问题,只是有点困惑。
    • 我添加了更多关于异步的代码,在我得到这个测试并更好地理解它之后,我将使用自定义构造函数,只是好奇你是否可以看看有什么问题。
    【解决方案2】:

    AsyncTasks 通常用于长时间的后台操作。因此,除非您希望在完成此类任务后更新您的按钮,否则我不确定您为什么要使用一个?

    但是,如果这确实是您的目的,那么您将在 AsyncTask 的 doInBackground() 函数中执行您需要的任何任务/代码。完成后,您将在 AsyncTask 的 onPostExecute() 函数中相应地更新您的 UI。

    也许您可以包含更多关于“动态加载”要求的性质的详细信息,以便社区可以为您提供更具体的答案。

    【讨论】:

    • 如果您需要更多代码,请告诉我,但本质上将该按钮视为调用多达 100 或 200 个将被删除并添加到该布局之外的按钮一个可滚动的。当该代码最终确定时,这将是一个更长的操作。我还使用下拉刷新来更新这些,这就是为什么我认为异步方法是合适的。上述操作本质上是我正在测试的需要在那里完成的唯一示例。不过,感谢您迄今为止对此的见解,如果我描述性不够,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    相关资源
    最近更新 更多