我是Android的新手,我真的不明白为什么动态添加的Fragment
内容(例如,点击按钮后添加的某些图片)在滚动一些{ {1}}然后回来。
确实有简单的代码Fragment
和Activity
:
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
,结果会显示图片。
它有效。 但是 ......
当我在第一个片段上显示图像时,滚动到第三个片段并再次返回第一个片段,图像消失。
我应该怎么做才能防止这种情况发生?我应该以某种方式保存可见度吗?
答案 0 :(得分:7)
这种情况正在发生,因为FragmentStatePagerAdapter
在滚出视图时会释放与Fragment
关联的内存。来自docs:
当用户看不到页面时,它们的整个片段可能是 被破坏,只保留该片段的保存状态。这允许 寻呼机可以保持与每个访问者相关的更少内存 与FragmentPagerAdapter相比的页面可能会有代价 在页面之间切换时会产生更多开销。
您可以尝试以下四种选项之一:
1。由于您的网页数量较少,因此您可以使用FragmentPagerAdapter
代替FragmentStatePagerAdapter
。 FragmentPagerAdapter
保留在创建的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()
中使用该标记使其成为visible
或invisible
。
<强>更新强>
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消失了..
尚未检查性能