tommybuonomo / dotsindicator

Three material Dots Indicators for view pagers in Android !
Apache License 2.0
3.44k stars 353 forks source link

Dot indicator resets to the first page after the activity is rotated #126

Closed nachogoro closed 2 years ago

nachogoro commented 3 years ago

As the title states. I set the ViewPager2 object for the SpringDotsIndicator in the onCreate() method of my activity, and don't do anything else with the SpringDotsIndicator:

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        ...
        final ViewPager2 viewPager = findViewById(R.id.tutorial_pager);
        final FragmentStateAdapter pageAdapter = new MyPageAdapter(this);
        viewPager.setAdapter(pageAdapter);
        final SpringDotsIndicator dotsIndicator = (SpringDotsIndicator) findViewById(R.id.spring_dots_indicator);
        dotsIndicator.setViewPager2(viewPager);
        ...

It behaves correctly normally. However, if I'm on e.g. my third fragment and rotate the screen, when the activity is recreated the fragment shown in the new orientation is still the third one, but the dot indicates that we are on the first fragment.

As soon as I slide the fragment slightly the dot catches up and goes to the correct position.

Is this a bug or am I missing some code in order to handle these cases?

nachogoro commented 3 years ago

The issue is still unresolved, but I did a bit more digging.

The current item of the ViewPager2 object is reset after a screen rotation, due to the activity being recreated, see this question in StackOverflow. Indeed, I checked getCurrentItem() in my original onStart() method and it was reporting 0 regardless of the fragment being shown.

However, I have fixed this issue by saving the current item as the original activity is being destroyed and restoring it in my onCreate(final Bundle bundle) method, and the issue still persists. The ViewPager2 object now correctly reports the current item after the rotation, but the dot is still in the first position.

    private ViewPager2 mViewPager;
    private SpringDotsIndicator mDotsIndicator;
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        ...
        viewPager = findViewById(R.id.tutorial_pager);
        final FragmentStateAdapter pageAdapter = new MyPageAdapter(this);
        viewPager.setAdapter(pageAdapter);
        if (savedInstanceState != null) {
            final int position = savedInstanceState.getInt("current_position");
            mViewPager.setCurrentItem(position);
        }
        mDotsIndicator = (SpringDotsIndicator) findViewById(R.id.spring_dots_indicator);
        mDotsIndicator.setViewPager2(mViewPager);
        ...
    }

    @Override
    public void onSaveInstanceState(final @NonNull Bundle bundle) {
        super.onSaveInstanceState(bundle);
        bundle.putInt("current_position", mViewPager.getCurrentItem());
    }

I can see that I'm setting the right position in the ViewPager2 object in onCreate() and that it remains correct in onStart(). For some reason, though, it doesn't seem to be picked up by the SpringDotsIndicator object. Invoking refreshDots() in onStart() also has no effect.

nachogoro commented 3 years ago

The issue can be reproduced easily with the provided sample. Surprisingly, it seems to happen with the SpringDotsIndicator but not with the WormDotsIndicator.

nachogoro commented 3 years ago

It looks like this issue has been reported several times. The best explanation I've found is by @krodyrobi here (issue #57 ).

Since issue 57 is a fairly old issue, I was wondering if there are any plans yo look into this @tommybuonomo

Cheers and thanks for the nice library :)

tommybuonomo commented 2 years ago

Hello @nachogoro 👋 I am sorry for this very late reply, but this issue will be fixed in the coming 4.3 version

tommybuonomo commented 2 years ago

Hello, thanks for your contribution ! This issue is now fixed in the new version 4.3 Thanks 🔥