onPageSelected不适用于第一页

时间:2013-04-18 03:37:54

标签: android android-viewpager

我的寻呼机适配器(扩展PagerAdepter)中有一个textview。我用MainActivity的onPageSelected更新了这个textview。它的更新textview为position> 0,但启动页面(位置0)在启动时不会更新。当我向前滑动然后向后滑动;它为位置0设置值但是我无法设置值ON START。如何设置星空页的值?

public void onPageSelected(int position) {

             switch (position) {
                case 0: 

                     PagerAdapter.tv.setText("value"); // => doesnt work on start

                    break;

                            default:
                                   PagerAdapter.tv.setText("value");
                                         break;
}
}

完整代码:

public class QuizStart extends SlidingFragmentActivity {
 @Override
        protected void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

           this.setContentView(R.layout.activity_main);

              mPager = (ViewPager)findViewById(R.id.pager);         
            QuestionPagerAdapter mAdapter = new QuestionPagerAdapter();

            mPager.setAdapter(mAdapter);
            QuizStart.onPageSelected(0);

         mPager.setOnPageChangeListener(new OnPageChangeListener() {


            @Override
            public void onPageScrollStateChanged(int arg0) { }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) { }

            @Override
            public void onPageSelected(int position) {

             switch (position) {
                case 0: 

                     PagerAdapter.tv.setText("value"); // => doesnt work on start

                    break;

                            default:
                                   PagerAdapter.tv.setText("value");
                                         break;
                }
            }

        });
}
}

11 个答案:

答案 0 :(得分:64)

您可以在创建onPageSelected(0)时手动呼叫OnPageChangeListener以设置起始状态:

OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
    @Override
    public void onPageScrollStateChanged(int arg0) { }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) { }

    @Override
    public void onPageSelected(int position) {

        switch (position) {
        case 0: 
            QuizStart.next.setText(getmycurrentpage()+"");
            break;

        default:

            QuizStart.next.setText(getmycurrentpage()+"");
            break;
        }
    }
});

   mPager.setOnPageChangeListener(pageChangeListener);
   // do this in a runnable to make sure the viewPager's views are already instantiated before triggering the onPageSelected call
   mPager.post(new Runnable()
   {
       @Override
       public void run() 
       {
           pageChangeListener .onPageSelected(viewPager.getCurrentItem());
       }
   });

修改

现在它不会像 @metemet06

指示Null Pointer exception

答案 1 :(得分:42)

为我工作下一个代码

    viewPager.addOnPageChangeListener(myOnPageChangeListener);

    ViewPager.OnPageChangeListener myOnPageChangeListener = new ViewPager.OnPageChangeListener() {

    //declare key
    Boolean first = true;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (first && positionOffset == 0 && positionOffsetPixels == 0){
            onPageSelected(0);
            first = false;
        }
    }

    @Override
    public void onPageSelected(int position) {
        //do what need
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
};

答案 2 :(得分:4)

我的解决方案是扩展寻呼机适配器并在其中创建一个接口。然后在创建适配器后,使适配器仅调用一次接口。在内部接口回调中,您可以调用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;
}
}

答案 3 :(得分:1)

我通过在onCreate() - 我的活动方法中添加应该为第一页执行的代码来修复我的应用中的问题。

它不是最漂亮的hack并且涉及一些冗余代码,但是因为我只想在页面更改时加载一些文本数据,所以在我的情况下这是最简单的方法。

手动调用onPageSelected()导致NullPointerExceptions,只是上面其他评论中描述的das。

答案 4 :(得分:0)

在我看来,你真正希望做的是覆盖getPageTitle(),然后在其他地方,抓取该页面标题并将其设置为TextView的文本。

初始化活动时,初始化PagerAdapter并调用getTitle(0)。这将为您提供第0页的标题。现在在Activity的textview中设置它。稍后,无论何时更改页面,只需调用getTitle(newPosition)并更新TextView。

答案 5 :(得分:0)

您可能使用一些AsyncTasks来加载数据集,很难确定哪个任务将是最后完成的任务。并且只有在完成最后一个任务之后,当整个数据集完成时,您可以调用OnPageSelected,因为它在UI上对整个数据集执行刷新。

而不是在第一次加载页面时手动调用OnPageSelected函数,而是逐步构建UI“正常”。稍后,当用户更改页面时,数据集应该完整并保存以便在OnPageSelected函数中进行更新。

答案 6 :(得分:0)

因为我做了这里所建议的并且它不起作用我将发布为我工作的是将实例化函数添加到onPageScrolled,如下所示:

   @Override
   public void onPageScrolled(int arg0, float arg1, int arg2) {

           adapter.closeText(arg0, viewPager);

    }

它可能起作用的原因是onPagesScrolled在android任务管理器的下一行被激活,因此我们通过跳过监听器对视图的附件来防止页面膨胀的不必要情况。

答案 7 :(得分:0)

此代码适合我。首先初始化pagechange监听器。在setCurrentItem之后。

viewPager.setAdapter(adapter);
      viewPager.setOffscreenPageLimit(1);

      final ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() {
         @Override
         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
         }

         @Override
         public void onPageSelected(int position) {

         }

         @Override
         public void onPageScrollStateChanged(int state) {
         }
      };
      viewPager.addOnPageChangeListener(listener);
      viewPager.setCurrentItem(position);

答案 8 :(得分:0)

实际上我找到了一个基于此answer的好方法。

问题是,在设置侦听器时,ViewPager未完全加载,第一页被调用,但ViewPager内的片段尚未完全初始化。

为了解决这个问题,我只需保留一个变量来知道第一页是否已被调用:

private boolean mFirstPageCalled = false;

然后在听众中:

@Override
public void onPageSelected(int position) {

    if(mFirstPageCalled) {
        // Do your thing
    } else {
        mFirstPageCalled = true;
    }
}

最后要做的是处理错过的第一页,这可以在ViewPager完全创建后完成:

    mViewPager.post(new Runnable(){
        @Override
        public void run() {
            // Do your thing
        }
    });

在我的情况下,我只是回到这里,当前片段显示并处理它:

Fragment currentFragment = mPagerAdapter.instantiateItem(mViewPager, mViewPager.getCurrentItem());
currentFragment.customAction();

post方法只调用一次,非常适合处理第一页的情况。

答案 9 :(得分:0)

我的解决方案是一个扩展ViewPager

class MyViewPager extends ViewPager {

    private List<OnPageChangeListener> _Listeners = new ArrayList<>();

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void addOnPageChangeListener(OnPageChangeListener listener) {
        super.addOnPageChangeListener(listener);
        _Listeners.add(listener);
    }

    @Override
    public void removeOnPageChangeListener(OnPageChangeListener listener) {
        super.removeOnPageChangeListener(listener);
        _Listeners.remove(listener);
    }

    @Override
    public void setCurrentItem(final int item) {
        if (item != getCurrentItem()) {
            super.setCurrentItem(item);
        } else {
            post(new Runnable() {
                @Override
                public void run() {
                    dispatchOnPageSelected(item);
                }
            });
        }
    }

    private void dispatchOnPageSelected(int position) {
        for (int i = 0, size = _Listeners.size(); i < size; i++) {
            OnPageChangeListener listener = _Listeners.get(i);
            if (listener != null) {
                listener.onPageSelected(position);
            }
        }
    }
}

答案 10 :(得分:0)

@Override
public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
    super.addOnPageChangeListener(listener);
    if (getAdapter() != null && getAdapter().getCount() > 0) {
        post(() -> listener.onPageSelected(getCurrentItem()));
    }
}