8

私はよく知らないFragmentPagerAdapterので、これは私たち(あなた)が説明を批判的に読んだ質問の1つになるでしょう。

構造:一度にFragmentPagerAdapter2つのフラグメントを保持する(以下のコード)があります。1つ目は本の抜粋を表示し、2つ目は本のタイトルのリストを表示します。

目標:タイトルに記載されていることを達成したい:ユーザーはポケットベルの2番目のフラグメントに移動し、タイトルをクリックしてから、ユーザーを最初のフラグメントに戻し、最初のフラグメントに更新するように指示したいテキスト。最初のフラグメントにはそのtriggerRefreshためのメソッドがあります。

コード:私の問題FragmentPagerAdapterは、フラグメントを再利用/作成する方法(私にはわかりません)が原因で発生すると思います。これは私のクラスです:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return NUM_ITEMS;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
        case 0:
            return new ExcerptsFragment();
        case 1:
            return new BookListFragment();
        default:
            throw new IllegalArgumentException("not this many fragments: " + position);
        }
    }
}

これが私が関連するメンバーを作成した方法です:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
MyFragmentPagerAdapter mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);

そして、これは、本のタイトルからコールバックを受け取ったときに、アクティビティの他の場所で試したものです。タイトルが選択されたフラグメント:

mViewPager.setCurrentItem(0); // back to excerpts screen page. It's OK.
// Here's the problem! How to identify the fragment 0 
// to ExcerptsFragment and call its triggerRefresh()?!?

一連の問題:

アダプターを呼び出すと、現在接続されているものではないのgetView()新しいインスタンスが返されるため、機能しExcerptsFragmentません(予想どおり、例外がスローされます)。

ここで多くの人(例)がフラグメントをに格納しているのを見てきましたgetView()。そうですか?公式の例を見ると、私にはアンチパターンのように見えるからです(アイテムを持って自動参照を無効にします)。そして、それはここここの意見でもあります(そして私には正しく見えます)。

助言がありますか?この一言すべてを理解していなくても驚かないでしょう...

4

3 に答える 3

7

免責事項:これは以前は完全にうまく機能していましたが、内部のプライベートな動作に依存するという古典的な落とし穴に注意する必要があります内部実装が変更された場合に最終的に警告するテストを作成しましたが、その後、より環境に優しい牧草地に移りました。そして、あなたもそうすべきです。このように、私の意見では、この質問とその答えの価値は歴史的なものにすぎません。


その質問について申し訳ありませんが、私はそれが時間だったと思います。

その問題を解決するために、私はこのソリューションをそのまま実装しました。うまく機能しているようです。したがって、IDの名前を理解することで、(現在アタッチされている)フラグメントインスタンスを見つけるだけの問題だったと思います。上記のリンクはそれがどのように作られているかを説明しています。

これらのポケットベルの私のような初心者は「実際のシナリオ」の恩恵を受けると信じているので、私はそれを削除するのではなく、自分の質問に答えることを選びました。私が見た答えのほとんどは理論について最もよく話します、それはところで正しい方法です...しかし時々私のような人々が迷子になることに取り組むための実際の例がありません。

とにかく、これが私が必要とした最後のコードです(上記のコメント部分):

int n = 0;
mViewPager.setCurrentItem(n); // in the question I had stopped here.

ExcerptsFragment f = (ExcerptsFragment) ContainerActivity.this
        .getSupportFragmentManager().findFragmentByTag(getFragmentTag(n));
f.triggerRefresh();

// ... below the helper method: used the solution from the link.

private String getFragmentTag(int pos){
    return "android:switcher:"+R.id.pager+":"+pos;
}

したがって、フラグメントへの参照を保持していないため、これは堅牢なソリューションであると感じています(したがって、参照が古くなるリスクがあります)。私は自分のコードを最小限に抑えたので、愚かなことをする可能性を最小限に抑えました。

もちろん、何か追加したり、見せたり、それを行う上で何が悪いのか、何を改善できるのかを教えていただければ、喜んでご連絡いたします。

于 2012-04-05T04:23:04.377 に答える
2

私はしばらくの間、この問題の解決策を自分で探しました。原則としてあなたのアプローチは機能しますが、Android基本クラスの実装でフラグメントタグを作成するコードが変更されると、コードが破損します。これはかなり厄介な依存関係です!

より洗練されたアプローチは、問題を回避し、基本アクティビティのインスタンスをフラグメントに保持することです。アクティビティにタグのセッターを実装し、作成時にフラグメント内で呼び出します。タグはgetTag()で簡単に使用できます。

実装例はここにあります。

于 2013-09-07T14:10:14.187 に答える
0

作成時にフラグメントへのWeakReferencesを使用することで、この問題を解決しました。参照:https ://stackoverflow.com/a/23843743/734151

このアプローチに何か問題がある場合は、コメントしてください。

于 2014-05-24T10:16:26.703 に答える