【问题标题】:FragmentManager Error after updating from sdk 22 to 23 on Android在 Android 上从 sdk 22 更新到 23 后出现 FragmentManager 错误
【发布时间】:2016-06-07 13:40:38
【问题描述】:

我正在使用 FragmentPagerAdapter 创建一个 3 页的 viewpager,直到我升级到 sdk 23 它工作正常。我正在使用一个片段并根据 getItem(position) 发送不同的参数来填充不同的数据。升级后,Android 不承认其中一个页面,我必须到位置 2(第 3 页),然后滑回位置 0(第 1 页),然后 Android 用正确的数据填充页面。通过调试器运行确认 Android 跳过了 TabAdapter.java 中 getItem 函数中的案例 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;
        }
    }
}

bundle 中的数据是这样提取的

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 的 Activity 开始片段如下:

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

【问题讨论】:

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


    【解决方案1】:

    我不确定我是否正确理解了您的问题,但在我看来,您的最后一个(第三个)选项卡在您导航到它之前不会被创建。

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

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

    【讨论】:

    • 当应用程序启动时,它从第 1 页开始,但应该在上面的信息不存在,但如果我一直向右滑动(最后一页),最后一页的信息出现,然后当我滚动回第 1 页时,显示第 1 页的信息。这不是网络延迟之类的事情,因为我会将应用程序留在第 1 页 5 分钟,然后什么也没有发生,然后在我转到第 3 页然后返回第 1 页时工作
    • 如果您可以显示特定片段控制器的代码,我可以看一下。你在你的第一个片段上使用了任何 AsyncTasks 吗?
    • 没有使用异步任务。它的启动方式是宿主活动启动 tabfragment(见文章底部) TabFragment 膨胀视图并启动 tabadapter,然后启动 tabcontentfragment 并根据页面的位置传递不同的数据。
    • 当你一直向右滚动时(当你在最右边,第一个选项卡被破坏,因为视图寻呼机只会挂在它旁边的选项卡上)。当您滚动回第一个选项卡时,它会重新创建,并且如果您进行了设置,它将使用保存在 savedInstanceState 中的参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2014-08-24
    相关资源
    最近更新 更多