2

私には がありActivity、それには がありViewPagerます。これはを使用してViewPagerロードされます。私の各フラグメントはセクションと見なされます(アプリの機能による)。最初は一度使用してすべてのアイテムをロードしますが、FragmentsAdapterViewPager

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

フラグメントには、フラグメントの作成中にクラスsetupから呼び出される関数があります。Adapter

調査フラグメント

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

調査アダプター

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

ここで、SectionViewは class によって拡張された抽象クラス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()時々呼び出されるため、sectionViewnullになります。デバッグすると、ライフサイクル メソッドが呼び出されません ( onDestroyView()onDestroy()onDetach()onLowMemeory()などonConfigurationChanged())。では、どのようonCreateView()に呼び出すことができますか?

  2. Nexus 9 では、実行時のパーミッションを変更すると同じことが起こりました。Fragmentステータス バーを下にスクロールし、[設定] > [アプリ] > [アプリのアクセス許可] > [位置情報] > [位置情報のアクセス許可を取り消す] に移動します。パーミッションを付与するとクラッシュしませんが、セクションビュー オブジェクトを取り消すと null になります

WEIRD BEHAVIOR : 2 番目のシナリオを確認するために、デバッガーを接続して、Location権限の取り消し中にフラグメント/アクティビティが破棄されているかどうかを確認しました。場所のアクセス許可を取り消すとすぐに、デバッガーが切断され、アプリケーションが強制終了/DEAD されました。これは、権限を取り消すたびに発生します。

sectionViewオブジェクトが保持されているか、破棄されていないことを確認するにはどうすればよいですか?

4

1 に答える 1

0

いくつかのこと。Offscreen page limit を size() -1 に設定できます。これは、いずれかが常に画面に表示されるためです。

フラグメントにセットアップ メソッドを用意するのではなく、必要な値でフラグメントをインスタンス化することをお勧めします。そのため、SectionView および position パラメータを受け取る newInstance という名前の InvestigationFragment に静的メソッドを作成します。

例えば

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;
}

次に、InvestigationFragment の onCreate でこれらの値を読み取る必要があります。

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);
}
于 2016-02-26T17:31:27.177 に答える