【问题标题】:How to add views to layout from AsyncTask如何从 AsyncTask 向布局添加视图
【发布时间】:2014-02-15 13:37:51
【问题描述】:

根据用户输入,我动态地将许多文本视图添加到循环中的相对布局中。

问题在于,随着电视数量的增加,构建布局所需的时间也会增加,以至于用户将收到“等待/强制关闭”消息。

由于位于主 UI 线程上,我知道这一点,但据我所知,我无法将视图异步添加到布局中,例如在 doInBackground 中,当您得到“只有创建视图层次结构的原始线程才能触及其视图”时错误。

每个新电视都在前一个电视的右侧或下方,在循环中计算,因此我无法将 addview 语句移动到 AsyncTask onPostExecute。

有没有办法在使用 AsyncTask 时在 for 循环中将电视添加到布局中?

这是需要这样做的:

public class LoadData extends AsyncTask<Void, Void, Void> {

    protected void onPreExecute(){ ....

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

        while (yCoord + CellSizeH < b2.getHeight()) {
             while (xCoord + CellSizeW < b2.getWidth() ) {

                tv = new TextView(this);
                tv.setTextSize(DisplayCellSizeH * 0.5f);
                tv.setWidth(DisplayCellSizeW);
                tv.setHeight(DisplayCellSizeH);
                tv.setOnClickListener(new View.OnClickListener() {...
                }

                //this will error so needs to be in onPostExecute
                thelayout.addView(tv, params1);
              }
          }


    protected void onPostExecute(Void result){ ...

希望这是有道理的。谢谢

【问题讨论】:

  • 你不应该从差异线程访问视图
  • 使用 Traceview 确定您的时间都花在了哪里。在遇到 ANR 之前,您应该已经用完了堆空间,这表明您在主应用程序线程上做了一些错误的工作。

标签: android android-layout android-asynctask


【解决方案1】:

这就是ListViews 的用途。放入自定义适配器将起作用。从本质上讲,表中的每一行将只加载使其工作所需的内容。

本质上,ListView 是您的容器,您可以创建一个适配器来适当地填充数据。您将自定义适配器添加到 ListView,然后您就设置好了。这是一个简单的适配器布局。

public class CustomAdapter extends BaseAdapter {

    public CustomAdapter (Context c) {
    }

    public int getCount() {
        /Number of rows
    }

    public Object getItem(int position) {
        //Probably not required for your applications
    }

    public long getItemId(int position) {
        //Probably not required for your applications
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        //Create a view here, and return it.
    }
}

【讨论】:

  • 谢谢,listviews 在这种情况下不会有帮助。我的相对布局需要缩放和平移屏幕。
【解决方案2】:

将此添加到 AsyncTask doinbaground 允许在异步任务循环期间添加视图

Viewchart.this.runOnUiThread(new Runnable() {
    public void run() {
        thelayout.addView(tv, params1);
    }
});

【讨论】:

    【解决方案3】:

    这个代码来自某个项目的实现之一,试试吧

    声明你的布局和你在上面工作的活动

    LinearLayout asyncLayout;
    Activity myactivity;
    

    onCreate

    asyncLayout = (LinearLayout) findViewById(R.id.asyncLayout);
        myactivity= this;
    
        new LoadData().execute();
    

    然后是你的异步实现

    public class LoadData extends AsyncTask<Void, Void, Void> {
    
        protected void onPreExecute() {
        }
    
        protected Void doInBackground(Void... params) {
    
            myactivity.runOnUiThread(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    for (int i = 0; i < 3; i++) {
    
                         TextView text = new TextView(List_Activity.this);
                         text.setWidth(40);
                         text.setHeight(20);
                         text.setText("text : " + i);
                         asyncLayout.addView(text);
                    }
    
    
                }
            });
    
                        return null;
    
        }
    
        protected void onPostExecute(Void result) {
        }
    

    喂我回来

    【讨论】:

    • 谢谢,但我在您发布此问题前 5 分钟找到了相同的解决方案,所以我自己回答了这个问题,见下文。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多