Обновление макета фрагмента в ViewPager
У меня есть активность, которая использует 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. Метод onCreateView в ProfileFragment обрабатывает отображаемый макет в зависимости от состояния входа в систему.
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 принимает
Object object
вернулся изinstantiateItem
, Как получить это значение при уничтожении? Нужно ли перезаписыватьinstantiateItem
и поддерживатьMap<Integer, Object>
с позиции на объект? - Есть ли лучший способ обновить вид фрагмента, не разрушая фрагмент полностью?
1 ответ
Я сделал что-то подобное, прежде чем использовать 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;
}
}