2012-04-01 27 views
6

我有一個主要的TabActivity它有兩個選項卡,A和B(現在)。 Tab A加載一個FragmentActivity(下面給出的代碼),它僅僅包含一個FrameLayout,所以我可以加載我的碎片爲其中的特定標籤。FragmentManager.popBackStack()不會簡單地加載前一個片段

第一片段具有一些TextViews和一個的ListView。數據是從Web服務中提取的。當我點擊ListView的項目時,我在另一個Fragment(這也來自Web服務)中加載該項目的細節,並用另一個細節片段替換當前的Fragment(帶有ListView和其他控件)。

要做到這一點,我使用Android的支持,v4.jar庫使用片段作爲他們首選。

選項卡中的FragmentActivity的XML:

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:orientation="vertical" > 

     <FrameLayout 
      android:id="@+id/updates_frame" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:background="@drawable/background"/> 
    </LinearLayout> 

選項卡中的FragmentActivity Java代碼:

public class UpdatesFragmentActivity extends FragmentActivity implements 
    IUpdateNotifier { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.updates); 

     //Load Initial Fragment into FrameLayout 
     //I am adding this Fragment to BackStack 
     Fragment newFragment = new UpdatesFragment(); 
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
     ft.addToBackStack(null); 
     ft.add(R.id.updates_frame, newFragment); 
     ft.commit(); 
    } 

    //This is an Interface method which I call with the clicked "FEED" object to load its detail in another Fragment 
    @Override 
    public void onFeedSelected(Feed feed) { 
     // Instantiate a new fragment. 
     Fragment newFragment = new FeedDetailFragment(feed); 

     // Add the fragment to the activity, pushing this transaction 
     // on to the back stack. 
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
     ft.replace(R.id.updates_frame, newFragment); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
     ft.addToBackStack(null); 
     ft.commit(); 
    } 

    //This is another Interface Method which I call when the user presses "BACK". 
    //I am trying to load the previously loaded Fragment, which I added to BackStack. 
    //But this causes reconstruction of the previously loaded fragment. LIST in this case 
    //which call the web service. I DONT WANT TO CALL SERVICE AGAIN. 
    @Override 
    public void onBackPressed() { 
     FragmentManager fm = getSupportFragmentManager(); 
     if (fm.getBackStackEntryCount() > 0) { 
      fm.popBackStack(); 
     } 
    } 
} 

我已經創建了一個接口IUpdateNotifier,其中包含兩個方法:

public void onFeedSelected(Feed feed); 
public void onBackPressed(); 

UpdatesFragmentActivity實現了這些方法。我從兒童片段中調用這些方法進行下列操作。

  1. 我請onFeedSelected(進料進料)由具有的ListView的片段。我將單擊的訂閱源項目發送給父FragmentActivity,以便加載另一個包含該訂閱源細節的Fragment。
  2. 當用戶按下一個按鈕時,我會從第二個供稿細節Fragment調用onBackPressed(),該按鈕應該將包含ListView和其他控件的第一個片段帶回來。正如你所看到的,我打電話FragmentManager的popBackStack()方法帶回第一個片段...

但第一個片段得到更新並加載所有的數據從web服務。

其實我無法和存儲數據只有一次,也不是更新一些的時間間隔頻繁。用戶可以在他想要的時候更新列表。最初,列表從服務中加載前10個項目,然後如果用戶想要加載更多項目,則可以單擊列表末尾的「更多」按鈕。

它會加載下10個項目等等。但我想我可以將檢索到的ArrayList存儲在UpdatesFragmentActivity的某個變量中,然後只是將該ArrayList重新分配給列表的適配器,而不是從服務中加載數據,但我不知道如何使Fragment不再調用服務。

我希望它的行爲像我點擊標籤2然後再點擊標籤1。它只是顯示加載的數據,如同被隱藏並不會調用服務。

我該如何做到這一點?

+0

沒有u得到任何解決方案 – 2014-02-17 06:28:09

回答

4

您的設計模式有缺陷,原因是問題分離不好。數據的更新應與UI分離,因此,當用戶回到前一個Fragment時,它應該與從Web服務加載數據無關。

有幾個簡單的修復,但我不知道什麼會最好地工作,因爲你沒有給出問題的背景。

第一種選擇是在啓動時引入啓動畫面。本活動將利用AsyncTask從Web服務下載您需要的數據。如果您只希望在應用程序的運行時期間將數據下載一次,則此功能運行良好。您將確保不將此活動添加到歷史記錄中,因此當從下一活動中按下後退時,應用程序將退出。

我在許多應用程序和我喜歡的應用程序中使用的另一個選項是通過AlarmManager使用警報。您可以按特定的時間間隔設置定期更新,AlarmManager甚至可以幫助您達到包含時間枚舉的點。該警報將觸發一個broadcast receiver,它將執行您的自定義代碼,該代碼將從Web服務下載所需的數據並存儲它。

有一個關於這種方法的教程,可以在這裏找到http://android.arnodenhond.com/tutorials/alarm-notification

最後;你不需要彈出後退堆棧來解決這個問題,雖然你可能會因爲完全不同的原因來做這件事,但是如果沒有更多的信息很難說清楚。

+0

我不提供有關我面臨的問題足夠的信息真的很抱歉。我已經更新了我的問題......你現在可以看看它......我試圖解釋我的問題。 – Aamir 2012-04-01 19:06:14

+0

我不會改變我的答案,因爲我不同意你選擇了最好的方法。上面的答案應該引導你朝正確的方向發展。 – 2012-04-01 21:38:31

+0

實際上,我無法在一段時間內只讀取和存儲數據,也沒有更新頻繁的內容,用戶可以在需要時更新列表。最初列表從服務中加載前10項,然後用戶可以單擊「更多」按鈕列表末尾是否需要加載更多項目。它會加載下10個項目......等等。堅韌我明白,你指向我的AlarmManager,我在某些需要定期更新的情況下使用,但我不認爲我可以在這種情況下使用AlarmManager ..但我想我可以將檢索到的ArrayList存儲在FragmentActivity中的某個變量中。 – Aamir 2012-04-02 08:09:42

2

你提的問題不夠明確,要求更簡單且精確的問題......而當你上面說的

popBackStack不加載的最後一個片段,它通常用來彈出整個堆棧:

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 

加載另一個片段

beginTransaction() 
replace() Or add() 
commit() 

這是所有我能想到的與問題

好運

+0

我的解決方案是fragmentManager.popBackStack(0,FragmentManager.POP_BACK_STACK_INCLUSIVE); – JWqvist 2013-09-17 09:14:16

相關問題