Search code examples
javaandroidtimerandroid-viewpagercountdowntimer

How can I make the Viewpager go to the next page after the timer is finished?


I am currently making an exercise app and I made a Viewpager with 5 pages and has previous and next buttons that work just fine and a one-minute countdown timer that starts after the activity is opened. I am looking forward to making the Viewpager go to the next page after the timer is finished, resume the timer when the page is opened, and do the same no matter if the page is the next or previous. I am new to coding and I have no clue how to do that. If there is someone to show me what to change in the code or show me a working code it would be amazing.

The activity :

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_morning);

    findViewById(R.id.imageBackMorning).setOnClickListener(v -> onBackPressed());

    countdownText = findViewById(R.id.countdownText);
    countdownButton = findViewById(R.id.countdownButton);

    countdownButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startStop();
        }
    });

    startTimer();

    btnPrev = findViewById(R.id.prev);
    btnNext = findViewById(R.id.next);

    btnPrev.setVisibility(View.GONE);

    setupViewPager();

    pageChange();

}

private void startStop() {
    if (timerRunning) {
        stopTimer();
    } else {
        startTimer();
    }
}

private void startTimer() {
    countdownTimer = new CountDownTimer(timeLeft, 1000) {
        @Override
        public void onTick(long l) {
            timeLeft = l;
            update();
        }

        @Override
        public void onFinish() {

        }
    }.start();
    countdownButton.setText("Pause");
    timerRunning = true;

}

private void stopTimer() {
    countdownTimer.cancel();
    countdownButton.setText("Resume");
    timerRunning = false;
}

private void update() {
    int minutes = (int) timeLeft / 60000;
    int seconds = (int) timeLeft % 60000 / 1000;

    String timeLeftText;

    timeLeftText = "" + minutes;
    timeLeftText += ":";
    if (seconds < 10) timeLeftText += "0";
    timeLeftText += seconds;

    countdownText.setText(timeLeftText);
}

private void pageChange() {
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            page = position;
            switch (position) {
                case 0:
                    btnPrev.setVisibility(View.GONE);
                    btnNext.setVisibility(View.VISIBLE);
                    break;
                case 1:

                case 2:

                case 3:
                    btnPrev.setVisibility(View.VISIBLE);
                    btnNext.setVisibility(View.VISIBLE);
                    break;

                case 4:
                    btnPrev.setVisibility(View.VISIBLE);
                    btnNext.setVisibility(View.GONE);
                    break;
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
}

private void setupViewPager() {
    adapter = new Adapter(this);
    viewPager = findViewById(R.id.viewpager);
    viewPager.setAdapter(adapter);
}

public void prev(View view) {
    viewPager.setCurrentItem(viewPager.getCurrentItem() - 1, true);
}

public void next(View view) {
    viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
}

private class Adapter extends PagerAdapter {
    Context context;
    LayoutInflater inflater;

    public Adapter(Context context) {
        this.context = context;
    }

    // list img
    int[] list_img = {
            R.drawable.email_pic,
            R.drawable.email_pic,
            R.drawable.email_pic,
            R.drawable.email_pic,
            R.drawable.email_pic
    };

    // list judul
    int[] list_judul = {
            R.string.judul_1,
            R.string.judul_2,
            R.string.judul_3,
            R.string.judul_4,
            R.string.judul_5
    };

    // list deskripsi
    int[] list_desk = {
            R.string.desk_1,
            R.string.desk_2,
            R.string.desk_3,
            R.string.desk_4,
            R.string.desk_5
    };

    // list color bg
    int[] list_bg = {
            getResources().getColor(R.color.blue),
            getResources().getColor(R.color.white),
            getResources().getColor(R.color.blue),
            getResources().getColor(R.color.white),
            getResources().getColor(R.color.blue)

    };

    @Override
    public int getCount() {
        return list_judul.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return (view == object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.item_layout,container,false);
        LinearLayout linearLayout = view.findViewById(R.id.item_layout);
        ImageView imageView = view.findViewById(R.id.img);
        TextView judul = view.findViewById(R.id.judul);
        TextView desk = view.findViewById(R.id.deskripsi);

        linearLayout.setBackgroundColor(list_bg[position]);
        imageView.setImageResource(list_img[position]);
        judul.setText(list_judul[position]);
        desk.setText(list_desk[position]);
        container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((LinearLayout)object);
    }
}

The xml:

 <LinearLayout
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize"
    android:background="@color/white"
    android:backgroundTint="@color/remain_black"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    app:layout_constraintTop_toTopOf="parent">


    <ImageView
        android:id="@+id/imageBackMorning"
        android:layout_width="50dp"
        android:layout_height="45dp"
        android:paddingLeft="0sp"
        android:paddingTop="10sp"
        android:scaleX="0.9"
        android:scaleY="0.9"
        android:src="@drawable/white_arrow_back_24"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="@dimen/_40sdp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/linearLayout"></androidx.viewpager.widget.ViewPager>


<TextView
    android:id="@+id/countdownText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="01:00"
    android:textColor="@color/red"
    android:textSize="40sp"
    android:layout_marginBottom="@dimen/_8sdp"
    app:layout_constraintBottom_toTopOf="@+id/countdownButton"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

<Button
    android:id="@+id/countdownButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:scaleX="1.2"
    android:scaleY="1.2"
    android:backgroundTint="@color/red"
    android:text="Start"
    android:src="@drawable/play"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    android:layout_marginBottom="@dimen/_50sdp"/>

<Button
    android:id="@+id/prev"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:onClick="prev"
    android:text="prev"
    android:backgroundTint="@color/red"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

<Button
    android:id="@+id/next"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentBottom="true"
    android:onClick="next"
    android:text="next"
    android:backgroundTint="@color/red"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

Screenshot:

Thank you in advance.


Solution

  • making the Viewpager go to the next page after the timer is finished

    When your countdown timer has fired, it'll call onFinish(), so you could just call set next index in there.

    private void startTimer() {
        countdownTimer = new CountDownTimer(timeLeft, 1000) {
            @Override
            public void onTick(long l) {
                timeLeft = l;
                update();
            }
    
            @Override
            public void onFinish() {
                // do something in here, like
                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
                // think about what would happen if currently on the last page?
                // go back to 0, stop? reverse maybe?
            }
        }.start();
        countdownButton.setText("Pause");
        timerRunning = true;
    
    }
    

    resume the timer when the page is opened

    Do you mean that there will be a separate timer for each page? In this case you'll need to think about how to retain the timer value for each page individually. (Think about what happens when a page changes, and how you've gone about keeping resources and strings for each page.) Then when each page changes, pull out the correct value for the selected page and resume the timer from there.