刷新 ViewPager 中 Fragment 的布局

Refreshing the layout of a Fragment in ViewPager

我有一个 activity,它使用带有 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?
    }
}

我有两个问题:

  1. destroyItem 方法接受从 instantiateItem 返回的 Object object。如何在销毁的同时获取这个值?我是否需要覆盖 instantiateItem 并保持从位置到对象的 Map<Integer, Object>
  2. 有没有更好的方法来更新片段的视图而不完全破坏片段?

我在使用 FragmentStatePagerAdapter 之前做了类似的事情,你可以调用 notifyDataSetChangedgetItemPosition如果您调用 super.getItemPosition 则为每个现有片段调用它 returns POSITION_UNCHANGED 表示片段如果您 return POSITION_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;
}

}