为啥我不能从 FragmentPagerAdapter 分离片段?
Posted
技术标签:
【中文标题】为啥我不能从 FragmentPagerAdapter 分离片段?【英文标题】:Why cannot I detach fragment from FragmentPagerAdapter?为什么我不能从 FragmentPagerAdapter 分离片段? 【发布时间】:2013-03-02 22:33:10 【问题描述】:我想从我的 FragmentPagerAdapter 中分离一个片段,但它似乎不起作用。这是我从原始代码中复制的 pageradapter 类:
public class PagerAdapter1 extends FragmentPagerAdapter
private List<String> fragments;
private static final String TAG = "FragmentPagerAdapter";
private static final boolean DEBUG = true;
private Fragment mCurrentPrimaryItem = null;
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
/**
* @param fm
* @param fragments2
*/
public PagerAdapter1(FragmentManager fm, List<String> fragments2)
super(fm);
mFragmentManager=fm;
this.fragments = fragments2;
/* (non-Javadoc)
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position)
//return this.fragments.get(position);
return Fragment.instantiate(ViewPagerActivity.context, fragments.get(position));
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount()
return this.fragments.size();
/**
* Return the Fragment associated with a specified position.
*/
@Override
public void startUpdate(ViewGroup container)
@Override
public Object instantiateItem(ViewGroup container, int position)
Log.i("asasd", "asdasdasdasdasd");
if (mCurTransaction == null)
mCurTransaction = mFragmentManager.beginTransaction();
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null)
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
else
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
// Log.i("asdJANIANI", " " + getFragmentTag(container.getId(),0));
//Log.i("JANI", " " + getItem(0));
if (fragment != mCurrentPrimaryItem)
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
**destroyItem(container,0,getItem(0));**
return fragment;
@Override
public void destroyItem(ViewGroup container, int position, Object object)
if (mCurTransaction == null)
mCurTransaction = mFragmentManager.beginTransaction();
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem)
if (mCurrentPrimaryItem != null)
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
if (fragment != null)
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
mCurrentPrimaryItem = fragment;
if (position == 0)
this.notifyDataSetChanged();
@Override
public void finishUpdate(ViewGroup container)
if (mCurTransaction != null)
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
@Override
public boolean isViewFromObject(View view, Object object)
return ((Fragment)object).getView() == view;
@Override
public Parcelable saveState()
return null;
@Override
public void restoreState(Parcelable state, ClassLoader loader)
/**
* Return a unique identifier for the item at the given position.
*
* <p>The default implementation returns the given position.
* Subclasses should override this method if the positions of items can change.</p>
*
* @param position Position within this adapter
* @return Unique identifier for the item at position
*/
public long getItemId(int position)
return position;
private static String makeFragmentName(int viewId, long id)
return "android:switcher:" + viewId + ":" + id;
我只改变了一件事,我在 instantiateItem() 方法中实现了一个destroyItem()
方法,因为我想在每次实例化片段时分离片段(位置 0)。我没有收到任何错误,它只是没有分离。为什么?
提前感谢您!
【问题讨论】:
您是否要完全删除该片段? 以后会用到,所以不想完全删除。 【参考方案1】:这让我连续忙了两天。我终于在这里找到了答案:
Update ViewPager dynamically?
基本上,不要使用 FragmentPagerAdapter,而是使用 FragmentStatePagerAdapter 并覆盖 getItemPosition() 方法。事实证明,前者不允许对其数据源进行适当的更改,也不会反映它们。
这个该死的错误花费了我大量的时间 :( 但是上面的链接帮助我在几分钟内修复了它。
【讨论】:
【参考方案2】:在FragmentPagerAdapter.java
的源码中,
82 @Override83 public Object instantiateItem(ViewGroup container, int 位置) @987654326 @ if (mCurTransaction == null) 85 mCurTransaction = mFragmentManager.beginTransaction();86 @ 987654330@ // 我们已经有这个片段了吗?89 String name = makeFragmentName(container.getId(), position);90 Fragment fragment = mFragmentManager. findFragmentByTag(name);91 if (fragment != null) 92 if ( DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);93 mCurTransaction.attach(fragment);94 else 95 fragment = getItem(position);96 if (DEBUG) Log.v(TAG, "正在添加item #" + position + ": f=" + fragment);97 mCurTransaction .add(container.getId(), 片段,98makeFragmentName(container.getId(), position));99 100 if (fragment != mCurrentPrimaryItem) 101fragment.setMenuVisibility(false);102fragment.setUserVisibleHint(false);103 105 返回片段;106 108@Override109 public void destroyItem(ViewGroup container, int position, Object object) 110 如果 (mCurTransaction == null) 111 mCurTransaction = mFragmentManager.beginTransaction();112 @987654372 @if (DEBUG) Log.v(TAG, "Detaching item #" + position + ": f=" + object114 + " v=" + ((@ 987654375@)object).getView());115 mCurTransaction.detach((Fragment)object);116
您可以看到它使用附加/分离来显示/隐藏片段。这就是它们不起作用的原因。
【讨论】:
以上是关于为啥我不能从 FragmentPagerAdapter 分离片段?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 .pushViewController 不能快速从 didSelectItemAt 工作