Подтвердить что ты не робот

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.

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

Спасибо

4b9b3361

Ответ 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 - это константа с общим количеством слайдов