刷新 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?
}
}
我有两个问题:
- destroyItem 方法接受从
instantiateItem
返回的 Object object
。如何在销毁的同时获取这个值?我是否需要覆盖 instantiateItem
并保持从位置到对象的 Map<Integer, Object>
?
- 有没有更好的方法来更新片段的视图而不完全破坏片段?
我在使用 FragmentStatePagerAdapter 之前做了类似的事情,你可以调用 notifyDataSetChanged 和 getItemPosition如果您调用 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;
}
}
我有一个 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?
}
}
我有两个问题:
- destroyItem 方法接受从
instantiateItem
返回的Object object
。如何在销毁的同时获取这个值?我是否需要覆盖instantiateItem
并保持从位置到对象的Map<Integer, Object>
? - 有没有更好的方法来更新片段的视图而不完全破坏片段?
我在使用 FragmentStatePagerAdapter 之前做了类似的事情,你可以调用 notifyDataSetChanged 和 getItemPosition如果您调用 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;
}
}