如何刷新FragmentPagerAdapter中的一个Fragment?

14

我使用了 TabPageIndicatorFragmentPagerAdapter 库创建了两个标签页,分别叫做 tab1 (主页) 和 tab2 (个人资料)。

在 tab2 标签页里,我有一个名为 "Log in" 的按钮(tab2 会引入 abc.xml)。

当用户点击 "log in" 按钮时,应用程序将在一个新的活动中显示登录表单。登录后,该活动将结束并且 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();
            }
        }
        }

1
你尝试过使用 FragmentStatePagerAdapter 吗? - Ye Lin Aung
没有,你能告诉我如何使用它吗?请修改上面的代码。 - EastBK
尝试将TabsAdapter扩展为FragmentStatePagerAdapter,而不是FragmentPagerAdapter。这样它就会像class TabsAdapter extends FragmentStatePagerAdapter一样。 - Ye Lin Aung
完成登录活动后,我需要做什么才能将abc.xml切换到xyz.xml? - EastBK
4个回答

5
您可以使用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);

}
参考资料

您可以查看这篇解决方案。


谢谢你的警告 @GhostCat - missionMan
感谢您完美地处理我的反馈方式;-) - GhostCat
1
FragmentStatePagerAdapter从API 27开始已被弃用。 - Iman Marashi

2
您可以使用startActivityForResult(或广播/接收器)从活动中获取结果,然后使用adapter.notifyDataSetChanged来刷新片段。
关于刷新ViewPager的更多细节: 请参考链接:ViewPager PagerAdapter not updating the View

1
我也遇到了同样的问题,所以我用自己的方法解决了它:
只需通过覆盖 onResume 方法刷新 HomeFragment 或 ProfileFragment 即可。
在 onResume 方法中,您可以轻松地刷新 ListFragment 或 Fragment。

0

我尝试了很多在谷歌和stackoverflow上找到的解决方案,都没有正常工作。甚至官方谷歌Android开发者页面上的教程也没用。

我在我的应用程序中实现了ViewPageIndicator,并尝试创建一个图片滑动器。我有动态的图片URL来自服务回调成功。所以我必须在OnResume中设置我的viewpager适配器和指示器。当我一切都设置好后,在OnResume中加载片段,然后在OnStop之后重新加载它们。但是当我把应用程序发送到后台并打开其他应用程序后,我意识到在OnResume之后,我的滑动器无法重新加载图片。

浪费了很多时间后,我尝试理解我在fragmentpageradapter getItem中创建的片段的生命周期,通过日志记录和调试onCreateView和onResume事件。

如果您像这样创建您的片段:

Fragment myFragment = new Fragment(url,position);

当您停止活动并打开其他应用程序时,您将丢失在自定义片段构造函数中设置的变量。当我意识到这种情况时,我尝试了Bundle方法。

这是我的自定义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之后片段仍然存在,这是我最需要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接