Android: FragmentPagerAdapter: метод getItem называется дважды в первый раз
В моем приложении я использовал ViewPager.
Как,
(say main.xml)
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/register_header" />
И создайте объект ViewPager и объект ViewPagerAdapter (который расширяет FragmentPagerAdapter) в FragmentActivity.
_mViewPager = (ViewPager) findViewById(R.id.viewPager);
_adapter = new ViewPagerAdapter(getApplicationContext(),
getSupportFragmentManager());
_mViewPager.setAdapter(_adapter);
И класс адаптера похож на
public class ViewPagerAdapter extends FragmentPagerAdapter {
private Context _context;
private FragmentManager manager;
private Fragment f;
private String classname="ViewPagerAdapter";
public ViewPagerAdapter(Context context, FragmentManager fm) {
super(fm);
_context=context;
manager=fm;
}
@Override
public Fragment getItem(int position) {
Log.i(classname,"getItem called"+position);
f = new Fragment();
f=MyFragment.newInstance();
Bundle args = new Bundle();
args.putInt("position", position);
f.setArguments(args);
return f;
}
@Override
public int getCount() {
return User.getPageCount();
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
И в классе MyFragment
В onResume мне нужно сохранить объект wigets в общую статическую переменную.
public void onResume() {
super.onResume();
pageIndex = getArguments().getInt("position");
User.useTextview1=textview1;
User.useTextview2= textview2;
User.current_pageIndex=pageIndex;
}
Мне нужно обновить текстовые просмотры, полученные из класса User в FragmentActivity.
Моя проблема: метод getItem() вызывается дважды в первый раз
Фактически, представление, отображаемое в эмуляторе, является 0-м индексом, но имеет значение 1-го индекса в FragmentActivity.
Если во второй раз я прекратил вызов метода getItem(), я могу получить 0-й указатель TextView в FragmentActivity.
Пожалуйста, предоставьте мне лучший способ сделать это.
Спасибо
Ответы
Ответ 1
FragmentPagerAdapter
создает <2 > t2 > для начала, для индекса 0 и для индекса 1. Если вы хотите получить данные из Fragment
, которые находятся на экране, вы можете использовать setOnPageChangeListener
для Pager
чтобы получить текущую позицию. Затем SparseArray
с WeakReference
к вашим фрагментам. Обновите этот массив в вызове getItem
. Когда вызов onPageSelected
вызывается, используйте эту позицию, чтобы получить ссылку на правый Fragment
и обновить данные User
.
Инициализация массива:
private SparseArray<WeakReference<MyFragment>> mFragments = new SparseArray<WeakReference<MyFragment>>(3);
Ответ 2
Моя проблема: метод getItem() вызывается дважды в первый раз
Это не проблема, это default feature of FragmentPagerAdapter
. Это хорошо для вас, чтобы перейти от этой страницы к следующей и предыдущей.
вид, отображаемый в эмуляторе, является 0-м индексом, но имеет значение 1-го индекса в FragmentActivity
У меня такая же проблема, и я знаю почему. Это потому, что вы used same Fragment in View Pager
.
Как исправить это separate Fragments by using different Fragment
.
Ответ 3
в методе getItem я написал это.
@Override
public Fragment getItem(int index) {
EditFragment frag = new EditFragment();
Bundle args = new Bundle();
args.putSerializable("currentItem", itemsList.get(index));
frag.setArguments(args);
return (frag);
}
здесь itemsList.get(index) - это объект класса модели, который я буду использовать в классе EditFragment.
вот что.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.pager_fragment_layout, container, false);
image = (ImageView)result.findViewById(R.id.pager_image);
text = (TextView)result.findViewById(R.id.pager_item_desc);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity()).build();
ImageLoader.getInstance().init(config);
imLoader = ImageLoader.getInstance();
****NOTE
final SwapItems itemList = (SwapItems) getArguments().getSerializable("currentItem");
imagePath = itemList.getPaths().get(0);
imLoader.displayImage(imagePath,image);
text.setText(itemList.getItemDescription());
image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Fragment fragment = new ItemImagesFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Bundle bundle = new Bundle();
bundle.putSerializable("val", itemList);
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return result;
}
ПРИМЕЧАНИЕ: здесь я получаю объект модели swapitems из предыдущего метода getItem 'final'. это решает мою проблему. Раньше я был инициализирован тем же объектом со статикой как модификатор.
надеюсь, что ваш будет также очищать
Ответ 4
вы можете использовать этот метод для обновления своих представлений
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Fetch data or something...
}
}
Ответ 5
У меня возникла одна и та же проблема - метод getItem() вызывался дважды. Я не знаю о ваших целях использования этого метода моим, чтобы инициировать изменения в активности хостинга при появлении нового слайда.
Ну, в первую очередь getItem() не является правильным методом для получения события появления нового слайда.
Я использовал прослушиватель ViewPager.OnPageChangeListener для самого ViewPager для этой цели.
Вот что я сделал:
В операции, которая содержит фрагменты слайдов:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signature_wizard_activity);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
onSlideChanged(position); // change color of the dots
}
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
});
}
onPageScrolled() вызывается каждый раз, когда отображается ваш слайд, в качестве параметра он получает текущее положение отображаемого слайда. Приятно, что он называется в том числе в первый раз, когда он появляется, а не только при изменении слайда.
Когда это можно использовать?
Например, если у вас есть активность мастера с ViewPager, где вы скользите фрагменты с некоторыми подсказками, вы, вероятно, хотели бы иметь панель с серыми точками ниже слайдера, которая будет представлять количество слайдов в целом, а одна из точек будет отличаться цвет, представляющий текущий слайд.
В этом случае лучшим вариантом будет ViewPager.OnPageChangeListener и метод onPageScrolled().
Или, если у вас есть кнопки PREV. и NEXT, которые меняют слайды, и вы хотите отключить PREV. на первом слайде и отключить кнопку NEXT на последнем слайде. Вот как вы это делаете внутри метода onPageScrolled():
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 0){
prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500));
prevBtn.setEnabled(false);
}else{
prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue));
prevBtn.setEnabled(true);
}
if(position == NUM_PAGES -1){
nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500));
nextBtn.setEnabled(false);
}else{
nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue));
nextBtn.setEnabled(true);
}
}
где NUM_PAGES - это константа с общим количеством слайдов