onPageSelected doesn't work for first page

前端 未结 10 1987
[愿得一人]
[愿得一人] 2021-01-30 12:30

My pager adapter ( extends PagerAdepter ) has a textview in it. And I update this textview with MainActivity\'s onPageSelected . Its update textview for position > 0 , but start

相关标签:
10条回答
  • 2021-01-30 13:08

    You can manually call onPageSelected(0) when you create your OnPageChangeListener to set the starting state:

    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());
           }
       });
    

    Edit

    Now it will not get Null Pointer exception as pointed by @metemet06

    0 讨论(0)
  • 2021-01-30 13:10

    My solution is an extend 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);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-30 13:12

    For me work next code

        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) {
        }
    };
    
    0 讨论(0)
  • 2021-01-30 13:15

    Because I did what was suggested here and it did not work I will post what did work for me was adding the instantiating function to onPageScrolled, like so:

       @Override
       public void onPageScrolled(int arg0, float arg1, int arg2) {
    
               adapter.closeText(arg0, viewPager);
    
        }
    

    Probably the reason it worked is that onPagesScrolled is activated farther down the line of the android task manager, so we prevent the unwanted situation where the page is inflated with skipping the listeners attachment to the view.

    0 讨论(0)
  • 2021-01-30 13:18

    It seems to me that what you really want to be doing is overriding getPageTitle(), and then, somewhere else, grabbing that page title and setting it as a TextView's text.

    That way when you initialize your activity, initialize the PagerAdapter and call getTitle(0). This will get you the title for page 0. Now set that in the Activity's textview. Later, whenever you change pages just call getTitle(newPosition) and update that TextView.

    0 讨论(0)
  • 2021-01-30 13:18

    Actually I found a good way based on this answer.

    The problem is that the ViewPager is not fully loaded when the listener is setup, the first page is called but the fragments inside the ViewPager are not fully initialized yet.

    In order to fix that I just keep a variable to know if the first page has been called or not:

    private boolean mFirstPageCalled = false;
    

    Then in the listener:

    @Override
    public void onPageSelected(int position) {
    
        if(mFirstPageCalled) {
            // Do your thing
        } else {
            mFirstPageCalled = true;
        }
    }
    

    The final thing to do is to handle the first page that has been missed, this can be done once the ViewPager has been fully created with:

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

    In my case I just call back here the current fragment showed and work on it:

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

    The post method is only called once, so perfect to handle the first page case.

    0 讨论(0)
提交回复
热议问题