3

我是Android新手,我不明白爲什麼Fragment的內容是動態添加的(例如點擊按鈕後添加的某個圖片)在滾動某些計數後正在消失Fragment s然後回來。Android Viewpager碎片刷新時刷新

實在是簡單的代碼ActivityFragment

public class MyActivity extends FragmentActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager); 
     final CustomAdapter adapter = new CustomAdapter(getSupportFragmentManager()); 
     viewPager.setAdapter(adapter); 
    } 

    class CustomFragment extends Fragment { 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      return inflater.inflate(R.layout.fragment, container, false); 
     } 

     @Override 
     public void onActivityCreated(Bundle savedInstanceState) { 
      super.onActivityCreated(savedInstanceState); 
      getView().findViewById(R.id.clickMeButton).setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        getView().findViewById(R.id.image).setVisibility(View.VISIBLE); 
       } 
      }); 
     } 

    } 

    class CustomAdapter extends FragmentStatePagerAdapter { 

     private List<CustomFragment> fragments = Arrays.asList(
      new CustomFragment(), 
      new CustomFragment(), 
      new CustomFragment() 
     ); 

     public CustomAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int i) { 
      return fragments.get(i); 
     } 

     @Override 
     public int getCount() { 
      return fragments.size(); 
     } 
    } 

} 

和適當的個XML:

main.xml中

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

    <android.support.v4.view.ViewPager 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:id="@+id/viewPager" /> 

</LinearLayout> 

fragment.xml之

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:orientation="vertical" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

    <Button 
      android:id="@+id/clickMeButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="click me"/> 

    <ImageView 
      android:id="@+id/image" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:src="@drawable/ic_launcher" 
      android:visibility="gone"/> 

</LinearLayout> 

邏輯很簡單。在每個Fragment上,我可以點擊Button,並顯示圖像。

它的工作原理。 但是 ...

當我在第一個片段上顯示圖像,然後滾動到第三個,然後回到第一個圖像,圖像消失了。

我應該怎麼做才能防止這種情況?我應該以某種方式保存可見度狀態嗎?

回答

7

發生這種情況的原因是FragmentStatePagerAdapter在滾動出視圖時釋放與Fragment關聯的內存。從docs

頁面時對用戶不可見的,其整個片段可能是 摧毀,只保留該片段的保存狀態。這允許 尋呼機保持與每個訪問的 頁面相比少得多的存儲器,與FragmentPagerAdapter相比,當在頁面之間切換時潛在的 更多開銷的代價。

你可以嘗試以下四個選項之一:

既然你有少量的頁面,你可以使用FragmentPagerAdapter而不是FragmentStatePagerAdapterFragmentPagerAdapter會保留在已創建的Fragment上,並且不會在刷卡時銷燬它們。

2.在你Fragment,存儲booleanSharedPreference和設置(或清除),它的價值時,你的圖像可見或不可見。然後在您的FragmentonResume()方法中,根據SharedPreference的值使圖像可見或不可見。

在你FragmentonCreate(),叫setRetainInstance(true);

4。如果碎片的數量是固定的&相對較小,那麼在你的onCreate()添加以下代碼:

mViewPager = (ViewPager)findViewById(R.id.pager); 
mViewPager.setOffscreenPageLimit(limit);   /* limit is a fixed integer*/ 
+0

感謝您的回覆。我已經嘗試過1和3項(除了第2項),但結果是一樣的。是否有其他方式來存儲碎片而不從內存中移除?我需要在Web瀏覽器中實現類似於標籤的內容。所以我會爲此使用WebView。當然,我可以在SharedPreferences頁面中存儲所選用戶。但它一直會加載該頁面。這是不正確的。所以我需要在記憶中保留片段。 – vetalitet

2

請告訴我發生的事情是

由於您使用的適配器可能會有一個數字,活性片段例如3或4的時間。

適配器將動態呈現視圖以減少內存使用量。在你的情況

Fragment 1 -> Fragment 2 - > Fragment 3

讓活性片段是3現在,所以Fragment 1可從內存中,當你向後滾動刪除,它將被

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.fragment, container, false); 
} 

重繪片段因此圖像仍然invisible並處於初始階段。

Answer

設置一個標誌來識別圖像的狀態,並用它在onCreateView()使其visibleinvisible

UPDATE

mViewPager = (ViewPager)findViewById(R.id.viewPager); 
mViewPager.setOffscreenPageLimit(yourLimit); 

yourLimit是你想永葆這不是在當前屏幕上碎片的數量。

注意:這是內存密集型。

+0

感謝您的回覆,但也許有一些方法可以在不重新創建的情況下精確保留內存碎片?我需要使用WebView組件來實現與Web瀏覽器中的選項卡類似的內容。但片段娛樂將一直加載頁面 – vetalitet

+0

請檢查我的更新 –

1

保存圖像的可見性onSaveInstance您的片段類的方法CustomFragment。覆蓋在的onSaveInstanceState在重寫的方法片段活動類onSaveInstanceState呼叫super.onSaveInstanceState(束)

 @Override 
    public void onSaveInstanceState(Bundle outState) { 

     super.onSaveInstanceState(outState); 
     outState.putString("visibility", visibility); 
     } 

然後你就可以保留在你的片段類的onActivityCreated方法狀態CustomFragment

int visibility = View.INVISIBLE; 
    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     if(savedInstanceState!=null) 
      visibility = savedInstanceState.getInt("visibility"); 
     getView().findViewById(R.id.image).setVisibility(visibility); 
     getView().findViewById(R.id.clickMeButton) 
     .setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       getView().findViewById(R.id.image).setVisibility(View.VISIBLE); 
      } 
     }); 
    } 
+0

感謝您的回覆,但可能有一些方法只是保持片段在內存中而無需重新創建片段 – vetalitet

+0

如果您有修復和相對較少數量的Fragment'viewPager .setOffscreenPageLimit(numberOfFragment)' – Pr38y

1

mViewPager.setOffscreenPageLimit(極限);

它爲我工作,謝謝! 我有一個viewpager與第一個3碎片和recyclerview。當我點擊最後一個時,我的recyclerview消失了。

還未檢查性能