刷新时,Android Viewpager片段会刷新

时间:2014-06-14 07:24:48

标签: java android android-fragments android-viewpager android-pageradapter

我是Android的新手,我真的不明白为什么动态添加的Fragment内容(例如,点击按钮后添加的某些图片)在滚动一些{ {1}}然后回来。

确实有简单的代码FragmentActivity

Fragment

和适当的xmls:

main.xml中

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();
        }
    }

}

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="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>

逻辑很简单。在每个<?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,结果会显示图片。

它有效。 但是 ......

当我在第一个片段上显示图像时,滚动到第三个片段并再次返回第一个片段,图像消失。

我应该怎么做才能防止这种情况发生?我应该以某种方式保存可见度吗?

4 个答案:

答案 0 :(得分:7)

这种情况正在发生,因为FragmentStatePagerAdapter在滚出视图时会释放与Fragment关联的内存。来自docs

  

当用户看不到页面时,它们的整个片段可能是   被破坏,只保留该片段的保存状态。这允许   寻呼机可以保持与每个访问者相关的更少内存   与FragmentPagerAdapter相比的页面可能会有代价   在页面之间切换时会产生更多开销。

您可以尝试以下四种选项之一:

1。由于您的网页数量较少,因此您可以使用FragmentPagerAdapter代替FragmentStatePagerAdapterFragmentPagerAdapter保留在创建的Fragment上,并且不会在轻扫时销毁它们。

2。在您的Fragment中,将boolean存储在SharedPreference中,并在图像可见或不可见时设置(或清除)其值。然后,在onResume()的{​​{1}}方法中,根据Fragment的值,使图片可见或不可见。

3。SharedPreference的{​​{1}}中,拨打onCreate()

4. 如果片段的数量是固定的&amp;相对较小,然后在Fragment添加以下代码:

setRetainInstance(true);

答案 1 :(得分:3)

发生的事情是

由于您使用的是适配器,因此可能会有一些活动的片段,例如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

<强>更新

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

yourLimit是您想要保持活动的片段数,目前不在屏幕上。

注意:这是内存密集型的。

答案 2 :(得分:1)

在片段类onSaveInstance的{​​{1}}方法中保存图像的可见性。在片段活动类CustomFragment中覆盖onSaveInstanceState,在该重写方法中调用super.onSaveInstanceState(bundle)

onSaveInstanceState

然后,您可以在片段类 @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("visibility", visibility); } 的{​​{1}}方法中保留状态

onActivityCreated

答案 3 :(得分:1)

  

mViewPager.setOffscreenPageLimit(极限);

它对我有用,谢谢! 我有一个有3个片段的viewpager和第一个片段的recyclelerview。当我点击最后一个时,我的Recyclerview消失了..

尚未检查性能