Android 刷新ViewPager中片段的布局

Android 刷新ViewPager中片段的布局,android,android-fragments,android-viewpager,fragmentpageradapter,Android,Android Fragments,Android Viewpager,Fragmentpageradapter,我有一个活动,它使用带有4个片段的ViewPager。我正在使用FragmentPagerAdapter填充页面 public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int p

我有一个活动,它使用带有4个片段的ViewPager。我正在使用FragmentPagerAdapter填充页面

public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new FragmentA()
            case 1:
                return new ProfileFragment();
            case 2:
                return new FragmentC();
            case 3:
                return new FragmentD();
        }
        return null;
    }

    @Override
    public int getCount() {
        return 4;
    }
}
其中一个片段显示了用户的详细信息(上述代码中的ProfileFragment),符合以下条件:

  • 如果用户未登录,则显示登录布局
  • 如果用户已登录,则显示配置文件布局
因此,当用户第一次打开应用程序时,将显示登录布局,当用户登录时,需要刷新片段以显示配置文件布局

我计划采取的方法是,当用户登录时,将其导航到FragmentA并销毁现有的ProfileFragment。ProfileFragment的onCreateView方法根据登录状态处理要显示的布局

public class ProfileFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        int layout = userLoggedIn() ? R.layout.fragment_user_login : R.layout.fragment_user_profile;
        return inflater.inflate(layout, container, false);
    }

    // Handler for login
    public void loginUser() {
        ((MyActivity) getActivity()).loginUser();
    }
}

public class MyActivity extends AppCompatActivity {

    private SectionsPagerAdapter mSectionsPagerAdapter;

    public void loginUser() {
        // 1. Set login details as needed
        ...
        // 2. Navigate to FragmentA
        ...
        // 3. Destroy ProfileFragment
        mSectionsPagerAdapter.destroyItem(container, 1, object); // How to get `object` here?
    }
}
关于这一点,我有两个问题:

  • destroyItem方法接受从
    实例化项
    返回的
    对象。如何在销毁时获取此值?我是否需要覆盖
    实例化项
    并维护从位置到对象的
    映射
  • 有没有更好的方法可以在不完全破坏片段的情况下更新片段的视图

  • 在使用FragmentStatePagerAdapter之前,我做了类似的事情,您可以调用notifyDataSetChanged如果调用super,则会为每个现有片段调用getItemPosition。getItemPosition返回POSITION\u UNCHANGED表示片段未更改,如果您返回POSITION\u NONE将导致片段位于该位置重新加载。您可以在getItem方法中使用它来提供概要文件片段

    在此解决方案中,您只需调用setLoggedIn

    public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
    boolean isLoggedIn = false;
    boolean userHasJustLoggedIn = false;
    
    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    
    public void setIsLoggedIn() {
        isLoggedIn = true;
        userHasJustLoggedIn = true;
        notifyDataSetChanged();
    }
    
    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new FragmentA()
            case 1:
    
                if (isLoggedIn) {
                    return new ProfileFragment();
                } else {
                    return new LoginFragment();
                }
            case 2:
                return new FragmentC();
            case 3:
                return new FragmentD();
        }
        return null;
    }
    
    @Override
    public int getItemPosition(Object object) {
        Fragment fragment = (Fragment) object;
        if (fragment instanceof LoginFragment && userHasJustLoggedIn) {
            userHasJustLoggedIn = false;
            return POSITION_NONE;
        }
    
        return super.getItemPosition(object);
    }
    
    @Override
    public int getCount() {
        return 4;
    }
    

    }

    太棒了,听起来很棒。实际上,我们可能不需要
    userHasJustLoggedIn
    标志。如果用户已登录且片段为
    loginfracent
    ,我们将始终需要更新,因此返回位置\u NONE。如果您始终需要更新,则删除条件userHasJustLoggedIn,如果只是一次更改,那么我建议保持这种状态,因为这样可以防止每次重新加载碎片。我想我接受这个条件的时间太早了。我试着编写这个,但似乎不起作用
    InstanceItem()
    按预期再次调用,但它从不调用
    getItem()
    而是使用与
    LoginView
    相同的实例。我查看了
    FragmentPagerAdapter.InstanceItem()
    的源代码,它仅在
    FragmentManager
    没有片段时调用getItem,但在这种情况下,片段永远不会从
    FragmentManager
    中删除。我使用的是FragmentStatePagerAdapter而不是FragmentPagerAdapter