【问题标题】:Android: FragmentPagerAdapter: getItem method called twice on First timeAndroid:FragmentPagerAdapter:第一次调用两次 getItem 方法
【发布时间】:2013-03-05 08:20:45
【问题描述】:

在我的应用程序中,我使用了 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" />

并在FragmentActivity中创建ViewPager对象和ViewPagerAdapter(扩展FragmentPagerAdapter)对象。

_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;



    }

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

请为我提供最好的方法。

谢谢

【问题讨论】:

  • 你克服了这个问题吗?
  • @GVSharma 不,我没有
  • 我明白了......我会在这里写下我所做的......

标签: android android-pageradapter


【解决方案1】:

FragmentPagerAdapter 在开始时实例化 2 个Fragments,分别用于索引 0 和索引 1。如果您想从屏幕上的 Fragment 获取数据,您可以使用 setOnPageChangeListener 为 @987654326 @ 获取当前位置。然后将SparseArrayWeakReference 添加到您的片段中。在getItem 调用中更新该数组。当onPageSelected 被调用时,使用该位置获取对Fragment 的引用并更新User 数据。

数组初始化:

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

【讨论】:

  • 这是一个将对象映射到某个位置的数组。在 getItem 你这样使用它: myMemberSparseArrayObject.put(position, new WeakReference (f));
  • ok,所以 FragmentActivity 会维护 myMemberSparseArrayObject 对吧?
  • ,如何初始化myMemberSparseArrayObject?
  • 查看我的回答如何初始化数组,3 是它可以保存引用的最大值,因为这是 Pager 存活的正常片段数
  • @Niko stackoverflow.com/q/18097567/1503130 我遇到了一个问题,你能看看这个
【解决方案2】:

在 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 模型对象是“最终的”。这解决了我的问题。早些时候,我用 static 作为修饰符初始化了同一个对象。

希望你的也能清除

【讨论】:

    【解决方案3】:

    我的问题是 getItem() 方法在第一次被调用了两次

    这不是问题,这是default feature of FragmentPagerAdapter。从这个页面滑到下一个和上一个对你有好处。

    模拟器中显示的视图是第 0 个索引,但在 FragmentActivity 中获得了第 1 个索引值

    我遇到了同样的问题,我知道为什么。这是因为你used same Fragment in View Pager

    如何解决这个问题是separate Fragments by using different Fragment

    【讨论】:

    • 我实现了这个......在里面我需要点击每个页面,这将转到其他片段......但默认情况下它给出了错误的位置......我理解你在某种程度上回答。 . 你能解释清楚一些吗
    • 看来你遇到了另一个问题it is giving by default wrong positions。您可以使用viewpager.getCurrentItem(position) 指示单击某些按钮后需要转到哪个页面。
    • @GVSharma 你有什么解决方案?以及您应用了哪种解决方案
    • @GVSharma 你解决了我面临同样问题的问题吗 public Fragment getItem(int i) 两次调用给出了错误的位置我有 5 个标签和 5 个片段 if(i>0){ i = i-1;工作,但问题是最后一个选项卡或片段没有调用 b/c position = position -1
    【解决方案4】:

    我遇到了同样的问题 - getItem() 方法被调用了两次。我不知道您使用我的方法的目的是在出现新幻灯片时触发托管活​​动的更改。

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

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

    在包含幻灯片片段的 Activity 中:

     @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 是幻灯片总数的常数

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多