在ViewPager中刷新片段的布局

时间:2016-01-01 21:20:50

标签: android android-fragments android-viewpager fragmentpageradapter

我有一个使用ViewPager和4个片段的活动。我正在使用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从Object object返回instantiateItem。如何在破坏时获得此值?我是否需要覆盖instantiateItem并从位置维护Map<Integer, Object>对象?
  2. 是否有更好的方法来更新片段视图而不会完全破坏片段?

1 个答案:

答案 0 :(得分:0)

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

}