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.

Пожалуйста, предоставьте мне лучший способ сделать это.

благодаря

Solutions Collecting From Web of "Android: FragmentPagerAdapter: метод getItem, вызываемый дважды в первый раз"

FragmentPagerAdapter создает два Fragments при запуске, для индекса 0 и для индекса 1. Если вы хотите получить данные из Fragment который находится на экране, вы можете использовать setOnPageChangeListener для setOnPageChangeListener чтобы получить текущую позицию. Затем используйте SparseArray с WeakReference для ваших фрагментов. Обновите этот массив в вызове getItem . Когда onPageSelected получает вызов, используйте эту позицию, чтобы получить ссылку на правый Fragment и обновить данные User .

Инициализация массива:

 private SparseArray<WeakReference<MyFragment>> mFragments = new SparseArray<WeakReference<MyFragment>>(3); 

Моя проблема: метод getItem () вызывается дважды в первый раз

Это не проблема, это default feature of FragmentPagerAdapter . Это хорошо для вас, чтобы пронести с этой страницы на следующую и предыдущую.

Представление, отображаемое в эмуляторе, является 0-м индексом, но имеет значение 1-го индекса в FragmentActivity

У меня такая же проблема, и я знаю почему. Это потому, что вы used same Fragment in View Pager .

Как исправить это separate Fragments by using different Fragment .

В методе 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». Это решает мою проблему. Раньше я был инициализирован тем же объектом со статикой как модификатор.

Надеюсь, ваше

Вы можете использовать этот метод для обновления своих представлений

 @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { // Fetch data or something... } } 

Я столкнулся с той же проблемой – метод 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 – это константа с общим количеством слайдов