2013-05-21 48 views
0

我想創建一個片段,該片段在開始會顯示一個進度條,其他線程將調用一個函數,它會帶來一些信息(從遠程服務器所帶來的信息 - 需要幾秒鐘)填充一些將被添加到片段的視圖。我試圖將視圖添加到片段中,但得到了一個異常,我無法更改不在主線程上的線程的UI。所以我在UI線程上運行它,但問題在於用戶界面堆疊直到從服務器返回所有信息。異步補充意見,片段中的Android

這裏是我的代碼:

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直到點我從服務器獲取我的所有數據?

謝謝!

回答

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()線程一次。

希望這有助於和喜歡你的工作

+0

謝謝,但仍然如此,片段將等待,直到for循環結束,然後才顯示在屏幕上。我希望它出現,然後填充它。 – vlio20

+0

問題是你正在onCreate上做這件事,在片段初始化後有什麼辦法做到這一點嗎? –

+0

我不介意在創建它之後再做。如果可能。 – vlio20

3

這將是更好的開始,例如,一個的AsyncTask從服務器下載在後臺線程的所有數據。 AsyncTask具有有用的處理程序OnPreExecute和OnPostExecute,可以保證在UI線程中運行。因此,您可以在PreExecute上放置一個「加載」佔位符文本,並且當您下載數據時,使用onPostExecute填充您的Fragment。

在罕見的情況下,如果你想你下載它,你的數據的逐步顯現,使用onProgressUpdate處理程序對與publishProgress方法。

+0

的的AsyncTask是不適合我,因爲我對於我有的每個服務類都有多個任務(如SaleService) – vlio20

+0

我認爲AsyncTask as the alexei sugge sts,是你應該使用的那個。這是一個很好的_standard_組件,每個Android開發人員都知道如何使用(或應該)這會提高代碼的可維護性。請注意,如果您確實希望可以通過爲execute()方法提供不同的處理程序(針對不同的線程)來使多個AsyncTasks並行運行。但是,如果你有多個任務可以按順序執行,我會堅持Asy​​ncTask的publishProgress()方法,就像alexei也提到的那樣。 – baske

+0

因此,對於我的遠程服務器的每個調用應該在不同的AsyncTask? – vlio20