在Android上从sdk 22更新到23后,FragmentManager出错

时间:2016-06-07 13:40:38

标签: java android android-fragments android-viewpager fragmentmanager

我使用FragmentPagerAdapter创建一个3页的viewpager,直到我升级到sdk 23它运行正常。我正在使用一个片段并根据getItem(位置)发送不同的args来填充不同的数据。在升级之后,Android不确认其中一个页面,我必须到达位置2(第3页),然后滑回到位置0(第1页),然后Android使用正确的数据填充页面。通过调试器运行确认Android跳过了TabAdapter.java中getItem函数中的case 2。我也来了 W/FragmentManager: moveToState: Fragment state for TabContentFragment{3ac2d125 #3 id=0x7f0f0097} not updated inline; expected state 3 found 2。我一直在使用this similar question as reference,但仍然无法使用它,但我已将问题归咎于我正在使用的FragmentManager。但是在弄乱了好几个小时后,我还没有能够让Android看到有3页不是2页。

TabAdapter.java

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import com.movies.R;
import com.movies.date.LiveStatus;
import com.movies.fragments.TabContentFragment;
import com.movies.fragments.TabFragment;
import com.movies.utils.BundleKeys;

public class TabAdapter extends FragmentPagerAdapter {

private Context context;

public TabAdapter(FragmentManager fm, Context context) {
    super(fm);
    this.context = context;
}

/**
 * Return fragment with respect to Position .
 */

@Override
public Fragment getItem(int position) {
    TabContentFragment fragment = new TabContentFragment();
    Bundle args = new Bundle();
    switch (position){
        case 0:
            args.putInt(BundleKeys.STATE_KEY, LiveStatus.EVENT_STARTED);
            break;
        case 1:
            args.putInt(BundleKeys.STATE_KEY, LiveStatus.EVENT_NOT_STARTED);
            break;
        case 2:
            args.putInt(BundleKeys.STATE_KEY, LiveStatus.EVENT_OVER);
            break;
    }
    fragment.setArguments(args);
    return fragment;
}

@Override
public int getCount() {
    return TabFragment.MAX_TABS;
}

/**
 * This method returns the title of the tab according to the position.
 */

@Override
public CharSequence getPageTitle(int position) {

    switch (position) {
        case 0:
            return this.context.getString(R.string.tab_title_live);
        case 1:
            return this.context.getString(R.string.tab_title_upcoming);
        case 2:
            return this.context.getString(R.string.tab_title_replay);
        default:
            return null;
        }
    }
}

捆绑数据就像这样拉

this.state = getArguments().getInt(BundleKeys.STATE_KEY);

TabFragment.java

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.movies.R;
import com.movies.adapters.TabAdapter;

public class TabFragment extends Fragment {

public static final int MAX_TABS = 3;
public static TabLayout tabLayout;
public static ViewPager viewPager;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    /**
     * Inflate tab_layout and setup Views.
     */
    View view = inflater.inflate(R.layout.tab_layout, null);
    tabLayout = (TabLayout) view.findViewById(R.id.tabs);
    viewPager = (ViewPager) view.findViewById(R.id.event_info_viewpager);

    /**
     * Set an Adapter for the View Pager
     */
    viewPager.setAdapter(new TabAdapter(getFragmentManager(), getContext()));

    /**
     * Now , this is a workaround ,
     * The setupWithViewPager doesn't works without the runnable .
     * Maybe a Support Library Bug .
     */

    tabLayout.post(new Runnable() {
        @Override
        public void run() {
            tabLayout.setupWithViewPager(viewPager);
        }
    });
    return view;
    }
}

保持TabFragment的活动开始像这样的片段:

mFragmentManager = getSupportFragmentManager();
    mFragmentTransaction = mFragmentManager.beginTransaction();
    mFragmentTransaction.replace(R.id.container_view, new TabFragment()).commit();

1 个答案:

答案 0 :(得分:1)

我不确定我是否正确理解了你的问题,但听起来像你的最后一个(第三个)标签在你导航到之前没有创建。

默认情况下,ViewPager仅限于创建2个屏幕外视图(一个在左侧,一个在右侧)。通常,应用程序从最左边的选项卡开始,这意味着,如果您总共有3个,则在您靠近它之前不会创建最右边的选项卡。

您可以使用ViewPager.setOffScreenPageLimit(#)在MainActivity中覆盖此项,其中ViewPager实际上是ViewPager的名称,而#是您要从头开始创建的选项卡数。在你的情况下,听起来你想要这个数字是2。