片段未被销毁,但onCreateView被称为

时间:2016-02-26 07:26:05

标签: android android-fragments android-activity android-viewpager runtime-permissions

我有一个Activity,它有ViewPager。此ViewPager使用Fragments加载Adapter。我的每个片段都被视为部分(根据应用功能)。最初我使用

加载所有ViewPager

viewPager.setOffscreenPageLimit(sectionList.size()); //sectionList is nothing but number of framgents

在片段中,我有一个名为setup的函数,在创建片段时从Adapter类调用。

InvestigationFragment

public void setup(SectionView sectionView, int pos) {
    this.sectionView = sectionView;
    this.pos = pos;
}

InvestigationAdapter

@Override
public Fragment getItem(int pos) {
    InvestigationFragment investigationFragment = new InvestigationFragment();
    investigationFragment.setup(sectionViewHashMap.get(keys.get(pos)), pos);
    fragments.add(investigationFragment);
    return investigationFragment;
}

此处SectionView是由类SimpleSection扩展的抽象类。并SimpleSection在其中添加自定义视图。自定义视图类似于大约20-30个视图类。

public abstract class SectionView {

    public Section mSection;
    public Context mContext;
    public LinkedHashMap<Integer, SectionView> subSectionViews;
    public LinkedHashMap<Integer, FieldWidget> fieldWidget;
    public int actionSaveId;
    protected LinearLayout sectionView;
    protected Toolbar toolbar;

    public final void initialiseSection(Toolbar toolbar) {
        this.toolbar = toolbar;
        createFields();
        createSubSection();
    }

    public final void buildSection(LinearLayout v) {
        sectionView = v;
        addFields();
        addSubSection();
    }

    protected abstract void createFields();
    protected abstract void createSubSection();
    protected abstract void addFields();
    protected abstract void addSubSection();
    public abstract boolean hasSubSection();
    public abstract boolean validateSection();
    protected abstract boolean persistSection();

    public final boolean saveSection() {
        boolean isSaved = true;
            if (!validateSection()) {
                isSaved = false;
            } else if (!persistSection()) {
                isSaved = false;
            }
        return isSaved;
    }
}

到此为止一切都很好。但是在我无法保留它的某些情况下,SectionView将变为null。这是方案,

  1. 我有自定义相机实现,从片段我打开我的自定义相机(不破坏片段或活动),捕获图像我回到片段onCreateView()有时被调用,所以sectionView将为空。调试时,不会调用任何生命周期方法(例如onDestroyView()onDestroy()onDetach()onLowMemeory()onConfigurationChanged())。然后如何调用onCreateView()

  2. 在Nexus 9中,在更改运行时权限的同时发生了同样的事情。我将在Fragment,向下滚动状态栏&gt;转到设置&gt;应用&gt;应用权限&gt;位置&gt;撤销位置许可。如果我授予权限它不会崩溃,但如果我撤销sectionView对象将为null

  3. WEIRD BEAVAVIOR :为了检查第二种情况,我连接了调试器以确保在撤销Location权限时是否销毁了片段/活动。 一旦我撤销了位置许可,调试器就会断开连接并且应用程序被杀死/死亡。每当我撤销任何权限时都会发生这种情况。

    现在我怎样才能确保sectionView对象被保留或不被破坏?

1 个答案:

答案 0 :(得分:0)

一些事情。您可以将屏幕外页面限制设置为size() - 1,因为其中一个始终在屏幕上。

我建议您使用所需的值来实例化片段,而不是在片段上设置方法。因此,在InvestigationFragment中创建一个名为newInstance的静态方法,该方法接受SectionView和位置参数。

E.g。

public static InvestigationFragment newInstance(SectionView sectionView, int pos) {
    final InvestigationFragment fragment = new InvestigationFragment();
    final Bundle args = new Bundle();
    args.putSerializable("SectionView", sectionView); //Depends on what type this as to what the put method is
    args.putInt("Position", position);
    fragment.setArguments(args);
    return fragment;
}

然后你应该在onCreate of InvestigationFragment中读回这些值,例如

sectionView = (SectionView) getArguments().getSerializable("SectionView");

这应该允许您的InvestigationFragment正确地保持旋转变化等。

在您的Adapter类中,我建议只做:

@Override
    public Fragment getItem(final int position) {
      return InvestigationFragment.newInstance(sectionViewHashMap.get(keys.get(position)), position);
}

如果您确实需要在寻呼机适配器中维护片段列表,则应覆盖instantiateItem和destroyItem,如下所示:

@Override
public Object instantiateItem(final ViewGroup container, final int position) {
    final InvestigationFragment fragment = (InvestigationFragment) super.instantiateItem(container, position);
    fragments.put(position, fragment);
    return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    fragments.remove(position);
    super.destroyItem(container, position, object);
}