Android:FragmentPagerAdapter:getItem方法第一次调用两次

Android:FragmentPagerAdapter:getItem方法第一次调用两次,android,android-pageradapter,Android,Android Pageradapter,在我的应用程序中,我使用了ViewPager。 像 适配器类如下所示: public class ViewPagerAdapter extends FragmentPagerAdapter { private Context _context; private FragmentManager manager; private Fragment f; private String classname="ViewPagerAdapter"; public Vi

在我的应用程序中,我使用了ViewPager。 像

适配器类如下所示:

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;



    }
我必须在FragmentActivity中更新从User类获得的TextView。 我的问题是getItem()方法第一次调用两次 事实上,emulator中显示的视图是第0个索引,但在FragmentActivity中获得了第一个索引值。 如果我第二次停止对getItem()方法的调用,我就可以在FragmentActivity中获取第0个索引TextView引用

_mViewPager = (ViewPager) findViewById(R.id.viewPager);

_adapter = new ViewPagerAdapter(getApplicationContext(),
         getSupportFragmentManager());

_mViewPager.setAdapter(_adapter);
请为我提供最好的方法


感谢对于索引0和索引1,
FragmentPagerAdapter
在开始时实例化了2个
片段。如果要从屏幕上的
片段
获取数据,可以使用
页面更改侦听器
获取当前位置。然后将
SparseArray
WeakReference
一起添加到片段中。在
getItem
调用中更新该数组。调用
onPageSelected
时,使用该位置获取右侧
Fragment
的引用,并更新
User
数据

数组的初始化:

private SparseArray<WeakReference<MyFragment>> mFragments = new SparseArray<WeakReference<MyFragment>>(3);
private SparseArray mffragments=新SparseArray(3);
我的问题是getItem()方法第一次调用两次

这不是问题,这是FragmentPagerAdapter的默认功能。从本页滑动到下一页和上一页对您有好处

emulator中显示的视图是第0个索引,但在FragmentActivity中获得了第一个索引值

我也有同样的问题,我知道为什么。这是因为您
在查看页面中使用了相同的片段


如何修复这个问题是我写的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;
}
注意:这里我从前面的getItem方法得到的swapitems模型对象是“final”。这解决了我的问题。之前我用static作为修饰符初始化了同一个对象


希望您的视图也能清除

您可以使用此方法更新视图

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser) {
        // Fetch data or something...
    }
}

我也面临同样的问题——getItem()方法被调用了两次。我不知道你使用我的方法的目的是在新幻灯片出现时触发宿主活动的更改

首先,getItem()不是获取新幻灯片出现事件的正确方法

为此,我在ViewPager本身上使用了ViewPager.OnPageChangeListener侦听器。 以下是我所做的:

在保存幻灯片片段的活动中:

 @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。第一张幻灯片上的按钮和最后一张幻灯片上的“禁用下一步”按钮。以下是如何在onPageScrolled()方法中执行此操作:


其中NUM_PAGES是一个常量,包含幻灯片总数

,它是一个数组,用于将对象映射到特定位置。在getItem中,您可以这样使用它:myMemberSparseArrayObject.put(位置,新WeakReference(f));好的,FragmentActivity将维护myMemberSparseArrayObject,对吗?如何初始化myMemberSparseArrayObject?请参阅我的答案如何初始化数组,3是它可以保存引用的最大值,因为这是正常的活动片段数Pager@Niko我遇到了一个问题,你能看一下吗?我实现了这个…在里面,我需要点击每个页面,它会转到其他片段…但默认情况下,它给出了错误的位置。。。我在某种程度上理解你的回答。。你能更清楚地解释一下吗看起来你又遇到了另一个问题,默认情况下它给出了错误的位置。您可以使用
viewpager.getCurrentItem(position)
指示单击一些按钮后需要转到哪个页面。@GVSharma您得到了什么解决方案?你有什么解决方案applied@GVSharma你解决了我面临的问题吗?公共片段getItem(inti)调用两次,给出了错误的位置。如果(i>0){i=i-1;},我有5个选项卡和5个片段工作,但问题是最后一个选项卡或片段没有调用b/c position=position-1您解决了这个问题吗?@GVSharma不,我没有得到它……我将在这里写下我所做的。。。。
 @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) {}
    });
}
 @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);
            }
        }