Реализация Android FragmentStatePagerAdapter
Я реализую Android ViewPager. Вот пример кода для этого
public class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public int getCount() {
return 5;
}
@Override
public Fragment getItem(int position) {
return SampleItemFragment.init(position);
}
}
Файл макета
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"/>
Код фрагмента
public class SampleItemFragment extends Fragment {
int fragVal;
private ImageButton buyButton;
private boolean mShowingBack;
static SampleItemFragment init(int val) {
SampleItemFragment truitonFrag = new SampleItemFragment();
// Supply val input as an argument.
Bundle args = new Bundle();
args.putInt("val", val);
truitonFrag.setArguments(args);
return truitonFrag;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragVal = getArguments() != null ? getArguments().getInt("val") : 1;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_samplecard_item, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
buyButton = (ImageButton)getActivity().findViewById(R.id.buyButton);
buyButton.setOnClickListener(buyButtonListener);
}
View.OnClickListener buyButtonListener = new View.OnClickListener() {
@Override
public void onClick(View view)
{
if (mShowingBack) {
getFragmentManager().popBackStack();
mShowingBack = false;
return;
}
// Flip to the back.
mShowingBack = true;
// Create and commit a new fragment transaction that adds the fragment for the back of
// the card, uses custom animations, and is part of the fragment manager's back stack.
getFragmentManager()
.beginTransaction()
// Replace the default fragment animations with animator resources representing
// rotations when switching to the back of the card, as well as animator
// resources representing rotations when flipping back to the front (e.g. when
// the system Back button is pressed).
.setCustomAnimations(
R.animator.from_middle,R.animator.to_middle,R.animator.to_middle,R.animator.from_middle)
// Replace any fragments currently in the container view with a fragment
// representing the next page (indicated by the just-incremented currentPage
// variable).
.replace(R.id.placeholderItem, new SampleCardBackFragment())
// Add this transaction to the back stack, allowing users to press Back
// to get to the front of the card.
.addToBackStack(null)
// Commit the transaction.
.commit();
}
};
}
У меня есть кнопка покупки в каждом фрагменте, при нажатии я заменяю фрагмент новым фрагментом. Это отлично работает. Но моя проблема в том, что у меня есть 4 фрагмента, загруженных в пейджер просмотра. Когда я нажимаю кнопку, всегда изменяется содержимое первого фрагмента.
Когда я нажимаю кнопку внутри третьего фрагмента, я ожидаю, что замена фрагмента происходит в третьем фрагменте, но всегда для всех нажатий кнопки замена происходит в первом фрагменте.
Что здесь не так?
Благодарю.
2 ответа
Вы используете ViewPager с ViewPagerAdapter. Затем вы должны переключить фрагмент через ViewPager и ViewPagerAdapter, потому что состояния фрагментов сохраняются ими. Вот API ViewPager.setCurrentItem. Вы можете использовать этот API для переключения фрагмента внутри фрагмента.
Вам лучше не связываться с FragmentManager внутри каждого фрагмента. Например, если вы нажмете кнопку "КУПИТЬ", это изменит модель (флаг или данные где-нибудь), а затем вы инициируете обновление вашего MyAdapter, просто вызвав notifyDataSetChanged(). Этого должно быть достаточно, чтобы вызвать воссоздание фрагментов в правильный путь.
В идеале вы могли бы повторно использовать тот же экземпляр уже созданного фрагмента, например, вы просто изменили бы состояние текущего представления, но это зависит от того, что вы хотите сделать, если это совсем другое, я бы сделал MyAdapter.notifyDataSetChanged. () подход.
Вы, вероятно, задаетесь вопросом, как получить экземпляр MyAdapter. Например, вы можете создать метод доступа в своей Activity..и с помощью onClick() в вашем фрагменте, который вы сделаете:
// after changing your model with the new state
((MyActivity) getActivity()).getMyAdapter().notifyDataSetChanged();