在Android中异步添加视图到片段

时间:2013-05-21 10:28:32

标签: android multithreading asynchronous android-ui

我正在尝试创建一个片段,在开始时将显示ProgressBar,其他线程将调用一个函数,该函数将带来一些信息(从远程服务器带来的信息 - 需要几秒钟)来填充一些将被添加的视图片段。我试图将视图添加到片段,但有一个例外,我无法更改主线程上没有的线程上的UI。所以我在UI线程上运行它,但问题是UI一直堆叠,直到所有信息从服务器返回。

这是我的代码:

public class MainSalePage extends SherlockFragment 
{
    protected View maneSalePage;
    protected List<SaleObj> saleList;
    protected int numberOfsalesOnScreen;
    protected LinearLayout saleConteiner;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        maneSalePage = inflater.inflate(R.layout.main_page_fragment, container, false);
        numberOfsalesOnScreen = 0;
        saleConteiner = (LinearLayout) maneSalePage.findViewById(R.id.salesContainer);


        getActivity().runOnUiThread(new Runnable()
        {
            @Override
            public void run() 
            {
                SaleService saleService = new SaleService();
                saleList = saleService.getNextSales(numberOfsalesOnScreen); //the operation that takes time.
                for(int i = 0; i < saleList.size(); i++)
                {
                    SaleRow saleRow = new SaleRow(getActivity());
                    saleRow.populateWith(saleList.get(i));

                    saleConteiner.addView(saleRow);
                }
            }
        });

        return maneSalePage;
    }

}

如何显示片段并且不会叠加UI,直到从服务器获取所有数据为止?

谢谢!

2 个答案:

答案 0 :(得分:3)

最好开始,例如,AsyncTask从后台线程中的服务器下载所有数据。 AsyncTask有一些有用的处理程序OnPreExecute和OnPostExecute,它们保证在UI线程中运行。因此,您可以在PreExecute上放置一个“加载”占位符文本,并在下载数据时,在onPostExecute中使用它填充Fragment。

在最罕见的情况下,如果您希望数据在下载时逐渐显示,请使用onProgressUpdate处理程序与publishProgress方法配对。

答案 1 :(得分:0)

尝试这样的东西它会起作用,而不是最干净的解决方案,但我喜欢纠正代码而不是从草图中写出新代码,这样你就可以看出你犯了哪个错误

编辑:与弗拉德聊天帮助他的解决方案指南

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        maneSalePage = inflater.inflate(R.layout.main_page_fragment, container, false);
        maneSalePage.postDelayed(new Runnable() {

            @Override
            public void run() {
                addContainer();
            }
        }               
        }, 1000);
        return maneSalePage;
    }

        private void addContainer(){
            numberOfsalesOnScreen = 0;
            saleConteiner = (LinearLayout)       maneSalePage.findViewById(R.id.salesContainer);

           SaleService saleService = new SaleService();
        saleList = saleService.getNextSales(numberOfsalesOnScreen); //the operation that takes time.
        for(int i = 0; i < saleList.size(); i++)
        {
            getActivity().runOnUiThread(new Runnable()
            {
                @Override
                public void run() 
                {                       
                        SaleRow saleRow = new SaleRow(getActivity());
                        saleRow.populateWith(saleList.get(i));  
                        saleConteiner.addView(saleRow);

                }
            });
        }
    }

你一次发送所有这些,这样你就一个一个地发送

编辑:不要忘记这将立即创建所有N = saleList.size()线程。

希望这有助于并享受您的工作