如何让fragmentpageadapter不fragment缓存数据据

15:14 提问
求指导,谢谢各位大神。 ViewPager和FragmentPagerAdapter实现切换,但是无法显示数据
想做个应用市场,效果如图,下面的是一级标签,用的TabHost跳转Activity实现。然后上面这一排是二级标签,想用TextView + ViewPager + Fragment 实现,现在滑动有效,但是数据加载不出来。求指教,捉急一整天了。
这是“推荐”对应的Activity:
public class CommendActivity extends FragmentActivity {
private static final int INDEX_COM = 0;
private static final int INDEX_NEW = 1;
private static final int INDEX_HOT = 2;
private static final int INDEX_GUESS = 3;
private ImageView comP // 指针
private TextView comCom, comNew, comHot, comG // 标签
private ViewPager comP
private PagerAdapter pagerA
private List&CommendFragment&
private int currentPage = 0; // 当前二级页
private int delta = 0; // 指针单位移动量
private int offset = 0; // 指针移动偏移值
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_commend);
initPointer();
initTextView();
initViewPager();
* 配置标签
private void initTextView() {
comCom = (TextView) findViewById(Com);
comNew = (TextView) findViewById(New);
comHot = (TextView) findViewById(Hot);
comGuess = (TextView) findViewById(Guess);
comClickListener listener = new comClickListener();
comCom.setOnClickListener(listener);
comNew.setOnClickListener(listener);
comHot.setOnClickListener(listener);
comGuess.setOnClickListener(listener);
* 配置标签指针
private void initPointer() {
comPointer = (ImageView) findViewById(Pointer);
int imageWidth = BitmapFactory.decodeResource(getResources(), R.drawable.pointer).getWidth();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
delta = dm.widthPixels / 4;
offset = (delta - imageWidth) / 2;
Matrix matrix = new Matrix();
matrix.postTranslate(offset, 0);
comPointer.setImageMatrix(matrix);
* 配置ViewPager
private void initViewPager() {
comPager = (ViewPager) findViewById(Pager);
fragments = new ArrayList&CommendFragment&();
CommendFragment comFragment = CommendFragment.newInstance(INDEX_COM);
CommendFragment newFragment = CommendFragment.newInstance(INDEX_NEW);
CommendFragment hotFragment = CommendFragment.newInstance(INDEX_HOT);
CommendFragment guessFragment = CommendFragment.newInstance(INDEX_GUESS);
fragments.add(comFragment);
fragments.add(newFragment);
fragments.add(hotFragment);
fragments.add(guessFragment);
comPager.setAdapter(new TabsAdapter(getSupportFragmentManager(),
fragments));
comPager.setCurrentItem(currentPage);
comPager.setOnPageChangeListener(new ComPageChangeListener());
private class comClickListener implements OnClickListener {
public void onClick(View v) {
int id = v.getId();
switch (id) {
comPager.setCurrentItem(INDEX_COM);
comPager.setCurrentItem(INDEX_NEW);
comPager.setCurrentItem(INDEX_HOT);
case Guess:
comPager.setCurrentItem(INDEX_GUESS);
private class ComPageChangeListener implements OnPageChangeListener {
public void onPageScrollStateChanged(int state) {
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
public void onPageSelected(int position) {
Toast.makeText(
CommendActivity.this,
"this is "
+ ((TabsAdapter)comPager.getAdapter()).getItem(position), Toast.LENGTH_SHORT)
Animation anim = new TranslateAnimation(delta * currentPage, delta
* position, 0, 0);
currentPage =
anim.setFillAfter(true);
anim.setDuration(300);
comPointer.startAnimation(anim);
Adapter的java代码:
public class TabsAdapter extends FragmentPagerAdapter {
private List&CommendFragment&
public TabsAdapter(FragmentManager fm, List&CommendFragment& list) {
super(fm);
this.fragments =
public int getCount() {
return fragments.size();
public boolean isViewFromObject(View view, Object obj) {
return view ==
public Fragment getItem(int position) {
return fragments.get(position);
Fragment的java代码:
public class CommendFragment extends Fragment {
private static final int DEFAULT_TAG = -1;
private TextV
* 添加标识,返回带标识的对象。
* @param tag
* @return 带标识的Fragment
public static CommendFragment newInstance(int tag) {
CommendFragment fragment = new CommendFragment();
Bundle b = new Bundle();
b.putInt("tag", tag);
fragment.setArguments(b);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getArguments();
tag = (null == b ? DEFAULT_TAG : b.getInt("tag"));
* 解析布局
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_com, container, false);
tv = (TextView) view.findViewById(R.id.empty);
tv.setText(tv.getText().toString() + tag);
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
按赞数排序
public boolean isViewFromObject(View view, Object obj) {
return view ==
把适配器里面的这个方法去掉就可以了,我也是折腾了一天
就是下面这个答案:@Override
public boolean isViewFromObject(View view, Object obj) {
return view ==
我的情况是,使用toolbar + tablayout + viewpager 做了一个滑动的选项卡效果。结果 fragment里面数据显示不出来。 注意我这里只有ViewPager下面是fragment,外面并没有包裹fragment。 至于有的人外面还有一层fragment,可能使用 getSupportFragmentManager 能够解决。还是要明白原理才行啊。
6666666啊,虽然出错的原因有很多种,但是这个方法的确帮助我了,搞了半天,泥煤。
54关注|941收录
169关注|154收录
594关注|1706收录
其他相似问题
相关参考资料求大神替我想想android fragment如何保存切换状态!!_百度知道
求大神替我想想android fragment如何保存切换状态!!
if (savedInstanceSft.import android, id);if (details == null || details,希望吧友助我.}public void showDetails(int index) {curPositionChecked = index://d这个问题苦恼好几天了.util, long id) {super.setChoiceMode(ListView, Data.java的代码;showDetails(position);@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.ArrayList, details),所以问题应该不大.R.jpg" esrc="http.details).FragmentTransaction ft = getFragmentManager()./zhidao/pic/item/86df3ea24b899a901f243.view.ListVDetailsFragment details = (DetailsFragment) getFragmentManager().details.View,可是不会保存状态;DetailsFragment standardFragment = dl = new ArrayList&lt.example.Bundle, position!= null) {}getListView(), mit().setItemChecked(outSDetailsFragment&我点击了皇家马德里这个fragment的bale和C罗变成红色可是点回去一直无法保存这个状态主要代码如下;if (standardFragment .support.hide(standardFragment), curPositionChecked).TITLES)).setTransition(FragmentTString&;setListAdapter(new ArrayAdapter&lt.add(R:package com.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink"><img class="ikqb_img" src="http://d.layout, 0)!= index) {details = DetailsFragment, int position。这是个效果图 &nbsp.import android.support.findFragmentById(R.FragmentTransaction.CHOICE_MODE_SINGLE).ArrayAdapter, true).curChoice&quot:这个是TitlesFragment://d;/zhidao/wh%3D450%2C600/sign=ad43c0b2fb/86df3ea24b899a901f243.List&lt.public class TitlesFragment extends ListFragment {int curPositionChecked = 0;(getActivity()!,在网上看了看一些方法但是还是没路.addToBackStack(null);}}@Overridepublic void onListItemClick(ListVft!这些代码也是基本上从书上看来的
提问者采纳
直接mViewpager.setOffscreenPageLimit(4);里面额参数几时你要缓存页面的个数 建议不要设置太大啊;/&#47如果你用的Fragment嵌套的是ViewPager的话就简单点
提问者评价
其他类似问题
为您推荐:
android的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁caching - Android: Viewpager and FragmentStatePageAdapter - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
I'm designing an app that allows users to flip between multiple pages in a ViewPager.
I've been struggling trying to figure out how it is possible to remove a Fragment instance from a page when it is no longer visible on screen, cache it (to, say, a HashMap), and then restore it so that when the user flips back to that page, the views and everything else in it will be in the same state it was before removal.
For example, my first page is a login screen that makes certain layout elements on that particular page visible/invisible on a successful login.
When I flip forward enough pages then flip back to the first page, the layout is reset.
This becomes more of a problem for another one of my pages which contains a huge, horizontal/vertical scrolling grid of data that I use a thread in the background to draw when it initializes.
I use a progress dialog to notify the user of loading progress and that becomes really annoying everytime I have to load it.
So I did some research...
I browsed through the source code for FragmentStatePageAdapter and in the destroyItem() callback, the state of the Fragment instance being removed is saved to an ArrayList.
When a new instance of the Fragment is being created in the instantiateItem() callback, if an instance of an item doesn't already exist (they keep track of this by using an ArrayList), a new Fragment instance is created and its saved state is initialized with the corresponding Fragment.SavedState data.
Unfortunately, this data does not include the state that the Views were in although I noticed that for pages with a GridView/ListView, the state of the Views were somehow restored (if I scrolled to some random position, flipped a few pages and came back, it would not be reset).
According to the API:
The saved state can not contain dependencies on other fragments --
that is it can't use putFragment(Bundle, String, Fragment) to store a
fragment reference because that reference may not be valid when this
saved state is later used. Likewise the Fragment's target and result
code are not included in this state.
Being a noob to Android, I'm not quite sure I understand the last statement.
That being said, is there any way to cache View state?
If not, I think I'll just go ahead and go with leaving all the fragment
pages in memory.
I had the same problem problem and solved it by implementing these two functions
public void onSaveInstanceState (Bundle outState)
public void onActivityCreated (Bundle savedInstanceState)
on the fragments that I wanted to save. On the first function, you should save in the Bundle the date that you need to restore the views ( in my case I had a bunch of spinner so I used
an int array to save their positions). The second function, which is called when restoring your fragment, is where you implement the restoring process.
I hope this helps. I also made my adapter to inherit from FragmentStatePageAdapter but I am not sure that this is mandatory.
6,09511016
Listing of main.xml
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"&
&TextView android:text="Page 1" android:id="@+id/textViewHeader"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:gravity="center" android:padding="10dip" android:textStyle="bold"&&/TextView&
&android.support.v4.view.ViewPager
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:id="@+id/viewPager" /&
&/LinearLayout&
Setting up the ViewPager
ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
MyPagerAdapter adapter = new MyPagerAdapter(this);
viewPager.setAdapter(adapter);
The PagerAdapter
public void destroyItem(View view, int arg1, Object object) {
((ViewPager) view).removeView((View)object);
public int getCount() {
return views.size();
public Object instantiateItem(View view, int position) {
View view = views.get(position);
((ViewPager) view).addView(view);
public boolean isViewFromObject(View view, Object object) {
return view ==
look here for more details
2,23431942
Looking at the various documentation pieces, my best guess is that the views you are creating do not have an ID attached to them.
Assuming that the fragment's saved state is created from Fragment.onSaveInstanceState, then the fragment will automatically save any view's state that has an id.
You probably have a default id associated with your ListView/GridView if you created them from a layout file.
You can also associate an id with the views by calling setId.
Also, for your custom filled fragment, you may also have to do something custom in onSaveInstanceState.
Here's an example of how I implemented caching in PagerAdapter. After filling the cache all future view requests are served from cache, only data is replaced.
public class TestPageAdapter extends PagerAdapter{
private int MAX_SIZE = 3;
private ArrayList&SoftReference&View&& pageCache = new ArrayList&SoftReference&View&&(3);
public TestPageAdapter(Context context){
// do some initialization
public int getCount() {
// number of pages
private void addToCache(View view){
if (pageCache.size() & MAX_SIZE){
pageCache.add(new SoftReference&View&(view));
for(int n = (pageCache.size()-1); n &= 0; n--) {
SoftReference&View& cachedView = pageCache.get(n);
if (cachedView.get() == null){
pageCache.set(n, new SoftReference&View&(view));
private View fetchFromCache(){
for(int n = (pageCache.size()-1);
n&= 0; n--) {
SoftReference&View& reference = pageCache.remove(n);
View view = reference.get();
if (view != null) {
public Object instantiateItem(View collection, int position) {
View view = fetchFromCache();
if (view == null) {
// not in cache, inflate manually
LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.page, null);
setData(view, position);
((ViewPager) collection).addView(view, 0);
private void setData(View view, int position){
// set page data (images, text ....)
public void setPrimaryItem(ViewGroup container, int position, Object object) {
currentItem = (View)
public View getCurrentItem() {
return currentI
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
public void destroyItem(View collection, int arg1, Object view) {
((ViewPager) collection).removeView((View) view);
addToCache((View) view);
3,50831926
I also ran into this problem when I was using PagerSlidingTabStrip and using and instance of FragmentPagerAdapter, switching to FragmentStatePagerAdapter definitely worked.
Then I use onSaveInstanceState() to save sate
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you&#39;re looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabledAndroid fragment 缓存view - 简书
下载简书移动应用
写了41058字,被58人关注,获得了60个喜欢
Android fragment 缓存view
private View rootV// 缓存Fragment view@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.v("onCreateView", "onCreateView");
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_main_tab, null);
// 缓存的rootView需要判断是否已经被加过parent,
// 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
return rootV
如果您觉得我写的文章对您有用,有一定的帮助或者有一些感悟,您可以请我吃根冰淇淋吧。嘿嘿
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
如果您觉得我写的文章对您有用,有一定的帮助或者有一些感悟,您可以请我吃根冰淇淋吧。嘿嘿
选择支付方式:}

我要回帖

更多关于 fragment缓存数据 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信