接手别人的老项目。新版本测试提出一个bug:
点击Home最小化的应用—>系统设置界面 改变字体后—>点击进入应用—>3个由viewpager 的fragmentadapter管理的 tab页面点击都没反应。
这是一个比较蛋疼的bug,猜想了很多原因,都不对。
项目的结构是 activity 内有mainfragment,mainfragment又 包含viewpager,viewpager 使用FragmentPagerAdapter 管理3个页面。所以是 activity套2层fragment的结构。
一、大概猜想了一下可能跟这个结构有关,所以先看看FragmentPagerAdapter 的实现。
(注:本文写得比较乱,仅仅是个人笔记,很多地方带?表明本人也不确定,也没弄清楚)
public abstract class FragmentPagerAdapter extends PagerAdapter
// 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));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
实际上 只是在instantiateItem 中 调用了getItem(position); 这个抽象方法。 其他方法这个adapter 已经基本实现,所以user使用fpadapter的时候 实现getItem方法 就 是给 instantiateItem返回 fragment了。
然而 返回的是一个fragment,并不是view,且PagerAdapter中instantiateItem 要求的只是一个object。 那么ViewPager如何处理这个object?
ItemInfo addNewItem(int position, int index) {
ItemInfo ii = new ItemInfo();
ii.position = position;
ii.object = mAdapter.instantiateItem(this, position);
ii.widthFactor = mAdapter.getPageWidth(position);
if (index < 0 || index >= mItems.size()) {
mItems.add(ii);
} else {
mItems.add(index, ii);
}
return ii;
}
可见会在addNewItem中 将 这个 object封装 成 一个 iteminfo。
private final ArrayList mItems = new ArrayList();
同时将这个info 放在了一个arraylist中、
看看调用栈
04-07 18:43:48.446 14842-14842/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.testeveryting, PID: 14842
java.lang.NullPointerException
at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:85)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:943)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1091)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1545)
at android.view.View.measure(View.java:17616)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
at android.view.View.measure(View.java:17616)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:17616)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1413)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:696)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:589)
at android.view.View.measure(View.java:17616)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow DecorView.onMeasure(PhoneWindow.java:2585)atandroid.view.View.measure(View.java:17616)atandroid.view.ViewRoot