web-dev-qa-db-ja.com

FragmentPagerAdapterのフラグメントを更新する方法は?

TabPageIndicatorおよびFragmentPagerAdapterライブラリを使用して、tab1(ホーム)およびtab2(プロファイル)と呼ばれる2つのタブがあります。

Tab2には、「ログイン」という名前のボタンがあります(tab2はabc.xml)。

ユーザーが「ログイン」ボタンをクリックすると、アプリは新しいアクティビティのログインフォームを表示します。ログイン後、アクティビティが終了し、tab2のコンテンツビューが変更されます(膨らむため、ユーザーのプロファイルが表示されますxyz.xml)。どうやってやるの?

public class MainActivity extends SherlockFragmentActivity {
    private static String[] TAB_NAMES = null;
    private Context context = this;
    private static FragmentPagerAdapter adapter ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        if (TAB_NAMES == null) {
            TAB_NAMES = new String[] {
                    getResources().getString(R.string.tab_home),
                    getResources().getString(R.string.tab_profile) };
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        adapter = new TabsAdapter(
                getSupportFragmentManager());

        ViewPager pager = (ViewPager) findViewById(R.id.pager);

        pager.setAdapter(adapter);


        TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator);
        indicator.setViewPager(pager);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater infalter = getSupportMenuInflater();
        infalter.inflate(R.menu.main_menu, menu);
        return true;
    }

    class TabsAdapter extends FragmentPagerAdapter {
        public TabsAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
            case 0:
                return HomeFragment.getInstance();
            case 1:
                return new ProfileFragment();

            default:
                return HomeFragment.getInstance();
            }
        }
        }
13
EastBK

使用できます FragmentStatePagerAdapter FragmentPagerAdapterの代わり

あなたはこのように試すことができます:

private static FragmentStatePagerAdapter adapter ;
private static String[] TAB_NAMES = null;

@Override
protected void onCreate(Bundle savedInstanceState) {

    if (TAB_NAMES == null) {
        TAB_NAMES = new String[] {
                getResources().getString(R.string.tab_home),
                getResources().getString(R.string.tab_profile) };
    }
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return HomeFragment.getInstance();
                case 1:
                    return new ProfileFragment();

                default:
                    return HomeFragment.getInstance();
            }
        }

        @Override
        public int getCount() {
            return TAB_NAMES.length;
        }

        @Override
        public int getItemPosition(Object fragItem) {
            int position = 0;
            if (fragItem instanceof HomeFragment) {
                position = 0;
            } else if (fragItem instanceof  ProfileFragment) {
                position = 1;
            }
            return (position >= 0) ? position : POSITION_NONE;
        }
    }

    ViewPager pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);


    TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator);
    indicator.setViewPager(pager);

}

参照

this ソリューションを確認できます。

4
missionMan

StartActivityForResult(またはブロードキャスト/レシーバー)を使用して、アクティビティから結果を取得できます。次に、adapter.notifyDataSetChangedを使用してフラグメントを更新します。

ViewPagerの更新について、さらに詳しく:

ViewPager PagerAdapterがビューを更新しない

2
Loki

私も同じ問題に直面していたので、途中で解決しました:

OnResumeメソッドをオーバーライドして、HomeFragmentまたはProfileFragmentを更新するだけです。

OnResumeメソッドでは、ListFragmentまたはFragmentを簡単に更新できます。

0
Min2

私はこの問題について私がグーグルとスタックオーバーフローで見つけた多くの解決策を試しました。それらのすべてが正しく機能しませんでした。また、公式google Android開発者ページのチュートリアルは機能しませんでした。

アプリケーションにViewPageIndicatorを実装し、imagesliderを作成しようとしました。サービスのコールバックが成功したときの画像の動的URLがあります。だから私はOnResumeでviewpagerアダプタとインジケータを設定する必要があります。すべてを設定して問題がなければ、フラグメントをonResumeにロードし、OnStopの後で再ロードしました。しかし、アプリをバックグラウンドに送信し、onResumeの後でスライダーが画像をリロードできないことに気付いた他のいくつかのアプリを開くと、.

時間を浪費した後、onCreateViewイベントとonResumeイベントのロギングとデバッグを使用して、fragmentpageradapter getItemで作成したフラグメントのライフサイクルを明確に理解しようとしました。

次のようなフラグメントを作成した場合

Fragment myFragment = new Fragment(url,position);

アクティビティを停止して他のいくつかのアプリケーションを開いた後、カスタムフラグメントのコンストラクターに設定した変数を失います。この状況に気づいたとき、私はバンドルアプローチを試みました。

これが私のカスタムFragmentPagerAdapterです(Googleのサンプルを使用しました)。

public class ScreenSlidePageAdapter extends FragmentPagerAdapter implements IconPagerAdapter {

        ArrayList<String> urls;

        public ScreenSlidePageAdapter(ArrayList<String>urls,FragmentManager fm) {
            super(fm);
            this.urls = urls;
            fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }

        @Override
        public Fragment getItem(int position) {
            SliderFragment sliderFragment = new SliderFragment();
            Bundle bundle = new Bundle();
            bundle.putString("url",urls.get(position));
            sliderFragment.setArguments(bundle);
            return sliderFragment;
        }

    @Override
    public int getIconResId(int index) {
        return R.drawable.notification_circle;
    }

    @Override
    public int getCount() {
        return this.urls.size();
    }

} 

私のカスタムFragmentPagerAdapterはIconPagerAdapterを実装しています。気をつけて。

そして私のカスタムSliderFragment:

public class SliderFragment extends Fragment {

    private String url;
    private int position;
    private boolean clickable;

    public SliderFragment() {
    }

    public SliderFragment(String url, int position, boolean clickable) {

        this.url = url;
        //this.position = position;
        //this.clickable = clickable;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.layout_fragment_slider, container, false);


            this.url = getArguments().getString("url");

            ImageView imageView = (ImageView) rootView.findViewById(R.id.iv_image);
            com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(Constants.URL_PREFIX + url, imageView);


                imageView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(getActivity(),SliderActivity.class);
                        intent.putExtra("url",url);
                        startActivity(intent);
                        getActivity().overridePendingTransition(R.anim.anim_slide_in_left,
                                R.anim.anim_slide_out_left);
                    }
                });


        return rootView;
    }

そして最後に、スライダー項目をロードするloadSliderメソッド

private void loadSlider() {

        pager = (ViewPager) findViewById(R.id.dealdetailpager);

        ScreenSlidePageAdapter screenSlidePageAdapter = new ScreenSlidePageAdapter(dealDetail.getImages(),getSupportFragmentManager());
        pager.setAdapter(screenSlidePageAdapter);

        circlePageIndicator = (CirclePageIndicator) findViewById(R.id.indicator);
        circlePageIndicator.setViewPager(pager);

        sliderThread = new SliderThread(true, 0);
        sliderThread.start();
    }

スライダーのフラグメントが更新されているかどうかを確認する機会がありませんでしたが、少なくともOnStopの後にフラグメントが残っているので、これが最も必要でした。

0
savepopulation