我使用FragmentPagerAdapter在我的ViewPgaer中有4个片段。我尝试在持续延迟后添加每个片段,以便在切换底栏选项卡时获得无混蛋动画。
我使用this库作为具有移动动画的底栏。所有四个片段都有多个api调用,如果我在延迟后没有添加它们,那么移动动画就会生涩。
问题是我收到了一个难以复制的错误日志(如下所示)。
错误日志:
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:380)
at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:369)
at com.vanitee.services.view.FragmentFake$1.run(FragmentFake.java:46)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6585)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)
ViewPagerAdapterClass:的
class MyAccountPagerAdapter extends FragmentPagerAdapter {
public MyAccountPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if (position == ME_TAB) {
if (Utility.isEmpty(fragmentProfile)) {
fragmentProfile = FragmentFake.create(new FragmentUserProfile(), 50);
}
return fragmentProfile;
} else if (position == BOOKINGS_TAB) {
if (Utility.isEmpty(fragmentBooking)) {
fragmentBooking = FragmentFake.create(new FragmentBookings(), 100);
}
return fragmentBooking;
} else if (position == WALLET_TAB) {
if (Utility.isEmpty(fragmentWallet)) {
fragmentWallet = FragmentFake.create(new FragmentWallet(), 150);
}
return fragmentWallet;
} else if (position == LIKES_TAB) {
if (Utility.isEmpty(fragmentLikes)) {
fragmentLikes = FragmentFake.create(new FragmentLikes(), 200);
}
return fragmentLikes;
}
return null;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case ME_TAB:
return getContext().getString(R.string.me_tab);
case BOOKINGS_TAB:
return getContext().getString(R.string.bookings_tab);
case WALLET_TAB:
return getContext().getString(R.string.wallet_tab);
case LIKES_TAB:
return getContext().getString(R.string.likes_tab);
default:
return null;
}
}
@Override
public int getCount() {
return 4;
}
}
FragmentFake:的
public class FragmentFake extends Fragment {
private View root;
Fragment fragment;
public static Fragment create(Fragment frag, int timeMs) {
FragmentFake fragmentFake = new FragmentFake();
Bundle bundle = new Bundle();
fragmentFake.fragment = frag;
bundle.putInt("time", timeMs);
fragmentFake.setArguments(bundle);
return fragmentFake;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.layout_fake_fragment, container, false);
Bundle bundle = getArguments();
replaceFragment(bundle.getInt("time"));
return root;
}
private void replaceFragment(int time) {
root.postDelayed(new Runnable() {
@Override
public void run() {
if(!isAdded()){
return;
}
getChildFragmentManager().beginTransaction().add(R.id.replace_fragment_container, fragment).commit();
}
}, time);
}
}
报告的错误日志在
行 getChildFragmentManager().beginTransaction().add(R.id.replace_fragment_container, fragment).commit();
答案 0 :(得分:1)
创建一个扩展Fragment的Abstract Fragment。像这样
public abstract BaseChildFragment extends Fragment{
public void onViewPagerPagechange();
}
Make All ChildFragment扩展BaseChildFragment(FragmentUserProfile,FragmentUserLike,FragmentUserWellet,ETC),
在您的适配器上添加以下代码。
LruCache<Integer,BaseChildFragment> cache = new LruCache<>(4);
public BaseChildFragment getBaseChildFragment(int position){
return cache.get(position);
}
@Override
public Fragment getItem(int position) {
if (position == ME_TAB) {
if (Utility.isEmpty(fragmentProfile)) {
fragmentProfile = FragmentFake.create(new FragmentUserProfile(), 50);
cache.put(position,fragmentProfile );
}
return fragmentProfile;
} else if (position == BOOKINGS_TAB) {
if (Utility.isEmpty(fragmentBooking)) {
fragmentBooking = FragmentFake.create(new FragmentBookings(), 100);
cache.put(position,fragmentBooking );
}
return fragmentBooking;
} else if (position == WALLET_TAB) {
if (Utility.isEmpty(fragmentWallet)) {
fragmentWallet = FragmentFake.create(new FragmentWallet(), 150);
cache.put(position,fragmentWallet );
}
return fragmentWallet;
} else if (position == LIKES_TAB) {
if (Utility.isEmpty(fragmentLikes)) {
fragmentLikes = FragmentFake.create(new FragmentLikes(), 200);
cache.put(position,fragmentLikes );
}
return fragmentLikes;
}
return null;
}
在你的片段中有View浏览器AddpageChangeListener,就像这样
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
// optional
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
// optional
@Override
public void onPageSelected(int position) {
BaseChildFragment fragment = adapter.getBaseChildFragment(position);
fragmeng.onViewPagerPagechange();
}
// optional
@Override
public void onPageScrollStateChanged(int state) { }
});
这将调用您的ChildFragment onViewPagerPagechange();
方法。您可以在哪里加载您的子片段。
答案 1 :(得分:0)
你不能这样做
public static Fragment create(Fragment frag, int timeMs) {
FragmentFake fragmentFake = new FragmentFake();
Bundle bundle = new Bundle();
//remove this line, it won't work
fragmentFake.fragment = frag;
bundle.putInt("time", timeMs);
fragmentFake.setArguments(bundle);
return fragmentFake;
}
您可以从create语句中删除该赋值行,并在创建实例后添加另一种方法来分配该片段。你的代码应该是这样的
public static Fragment create(Fragment frag, int timeMs) {
FragmentFake fragmentFake = new FragmentFake();
Bundle bundle = new Bundle();
bundle.putInt("time", timeMs);
fragmentFake.setArguments(bundle);
return fragmentFake;
}
public void setFragment(Fragment fragment){
this.fragment = fragment;
}
//How you assign fragment
FragmentFake fakeFragment = FragmentFake.create(0);
fakeFragment.setFragment(yourFragment);
然后进行片段交易