【问题标题】:ViewPager onPageSelected for first pageViewPager onPageSelected 用于第一页
【发布时间】:2012-08-28 07:46:15
【问题描述】:

所以看来,当使用 ViewPager 时,onPageSelected 侦听器不会为第一页调用与this 相同的问题。

我有一些逻辑可以为当前选择的页面填充一些更昂贵的 UI 元素,这在页面更改时有效,但 it doesn't work for the first page.

如果我在监听器之后设置当前项,则第一页会触发回调,但视图尚未初始化,因此我无法对其进行操作:

// Inside PagerAdapter.instantiateItem

ViewHolder vh = new ViewHolder();
cursor.moveToPosition(position);
vh.view = adapter.newView(context, cursor, null);
// Set position as tag so we can retrieve it with findViewByTag
vh.view.setTag(position); 

((ViewPager) collection).addView(vh.view,0);       

return vh;

// Inside MyActivity.onCreate

pagerAdapter = new SingleMessagePagerAdapter(this, cursor);
pager = (ViewPager)findViewById(R.id.message_pager);
pager.setAdapter(pagerAdapter);
pager.setOnPageSelectedListener(this);
pager.setCurrentItem(selectedItem);

// Inside MyActivity.onPageSelected

// Retrieve tagged view
View view = pager.findViewWithTag(position); 

这里view 最终为空,因为PagerAdapter.instantiateItem 尚未运行。所以我想我的问题是,在活动生命周期的哪个阶段,我可以确定 ViewPager 已经初始化了视图?我尝试在 Activity.onAttachedToWindowActivity.onResume 内执行此操作,但似乎这两个都在 PagerAdapter.instantiateItem 之前被解雇。

【问题讨论】:

    标签: android android-viewpager


    【解决方案1】:

    我想知道为什么您不只是在 Fragment 本身而不是在托管 Activity 中提到的逻辑。 ViewPager 在当前片段的任一侧缓冲几个片段,因此它们在后台设置,并在用户滑动到它们时准备就绪。将逻辑放在onPageSelected 中意味着绕过此功能并且在用户滑动到页面之前不执行繁重的工作。

    假设由于某种原因您不能执行上述操作,为什么不使用Interface with a callback function。在片段的onCreateView 函数中触发回调,让 Activity 知道它已完全实例化。

    【讨论】:

      【解决方案2】:

      尝试使用片段!

      public class SectionsPagerAdapter extends FragmentPagerAdapter {
      
          public SectionsPagerAdapter() {
              super(getSupportFragmentManager());
          }
      
          @Override
          public Fragment getItem(int i) {
              Fragment fr = null;
              if (i==0)
                 fr = new sec0frag();
              else if (i==1)
                 fr = new sec1frag();
              else if (i==2)
                 fr = new sec2frag();
              return fr;
          }
      
          @Override
          public int getCount() {
              return 3;
          }
      }
      

      并创建 3 个片段类

      例如:

          public static class sec0frag extends Fragment {
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
                  Bundle savedInstanceState) {
                           // here is initialize for first time to view pages.!
              }
          }
      

      【讨论】:

      • 这应该可以,但是如果您必须滚动浏览其编号未预定义的页面列表怎么办?就像从网络上获取的项目列表,并且每个项目都需要一个一个地显示在这些寻呼机中?
      • 在 FragmentPagerAdapter 中动态定义 getCount() 或尝试在 ViewPager 中启用循环!!
      【解决方案3】:

      我的解决方案是扩展寻呼机适配器并在其中创建一个接口。然后让适配器在创建适配器后只调用一次接口。在接口回调中,您可以调用 onPageChanged 方法而不会出现 nullpointerexception。将此类添加到您的项目中并从中扩展您的适配器。在将适配器设置为 viewpager 之前,不要忘记将侦听器设置为适配器。适配器类如下:

      public abstract class ExtendedPagerAdapter extends FragmentPagerAdapter {
      
      private boolean instantiated;
      private AdapterListener adapterListener;
      
      public interface AdapterListener {
          void onAdapterInstantiated();
      }
      
      public ExtendedPagerAdapter(FragmentManager fragmentManager) {
          this(fragmentManager, null);
      }
      
      public ExtendedPagerAdapter(FragmentManager fragmentManager, AdapterListener adapterListener) {
          super(fragmentManager);
          this.adapterListener = adapterListener;
          instantiated = false;
      }
      
      @Override
      public void finishUpdate(ViewGroup container) {
          super.finishUpdate(container);
          if (!instantiated) {
              instantiated = true;
              if (adapterListener != null) {
                  adapterListener.onAdapterInstantiated();
              }
          }
      }
      
      public void setAdapterInstantiatedListener(AdapterListener adapterListener) {
          this.adapterListener = adapterListener;
      }
      }
      

      活动代码:

      adapter = new ViewPagerAdapter(getChildFragmentManager());
          adapter.setAdapterInstantiatedListener(new ExtendedPagerAdapter.AdapterListener() {
              @Override
              public void onAdapterInstantiated() {
                  onPageSelected(viewPager.getCurrentItem());
              }
          });
      
          viewPager.addOnPageChangeListener(this);
          viewPager.setAdapter(adapter);
      

      【讨论】:

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