3

I have 3 pages in my viewpager. Each page has a button that is initially set to be a start button. After the start button is pressed, it changes to a pause button. My problem is that if I'm on the first page and click start (changing it to pause) and then scroll to the last page and back to the first page, the button says start again. It lost the state of being already pressed. This only occurs after scrolling TWO pages though. It doesn't lose state if only scrolling one page and then back.

public Object instantiateItem(ViewGroup collection, int position) {

        RelativeLayout wholeView = new RelativeLayout(collection.getContext());

            // images
            final ImageView workoutWidget = new ImageView(collection.getContext());
            workoutWidget.setImageResource(R.drawable.workout_widget_master);

            final ImageButton resetButton = new ImageButton(collection.getContext());
            resetButton.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.reset_button_master));
            RelativeLayout.LayoutParams resetButtonParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            resetButtonParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            resetButtonParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            resetButtonParams.height = 150;
            resetButtonParams.width = 150;
            resetButton.setLayoutParams(resetButtonParams);
            resetButton.setVisibility(View.GONE);

            final ImageButton startButton = new ImageButton(collection.getContext());
            startButton.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.start_button_master));
            startButton.setTag(context.getString(R.string.wtrStartButtonTag));
            RelativeLayout.LayoutParams startButtonParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            startButtonParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            startButtonParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            startButtonParams.height = 150;
            startButtonParams.width = 150;
            startButton.setLayoutParams(startButtonParams);
            startButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startButton.setAlpha(1.0f);

                    if (startButton.getTag() == context.getString(R.string.wtrStartButtonTag)) {
                        startButton.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.pause_button_master));
                        startButton.setTag(context.getString(R.string.wtrPauseButtonTag));
                        resetButton.setVisibility(View.VISIBLE);
                    }
                    else if (startButton.getTag() == context.getString(R.string.wtrPauseButtonTag)) {
                        startButton.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.start_button_master));
                        startButton.setTag(context.getString(R.string.wtrStartButtonTag));
                    }
                }
            });

            // text labels view
            LinearLayout textLabels = new LinearLayout(collection.getContext());
            textLabels.setOrientation(LinearLayout.VERTICAL);

                TextView activityDescription = new TextView(collection.getContext());
                activityDescription.setText("Warm-up");
                activityDescription.setPadding(200, 200, 0, 0);
                activityDescription.setTextSize(30);
                textLabels.addView(activityDescription);

                TextView timeLeftForThisActivity = new TextView(collection.getContext());
                timeLeftForThisActivity.setText("00:00");
                timeLeftForThisActivity.setPadding(200, 0, 0, 0);
                timeLeftForThisActivity.setTextSize(60);
                textLabels.addView(timeLeftForThisActivity);

                LinearLayout elapsedLabels = new LinearLayout(collection.getContext());
                elapsedLabels.setOrientation(LinearLayout.HORIZONTAL);

                    TextView elapsedTimeStatic = new TextView(collection.getContext());
                    elapsedTimeStatic.setText("Elapsed Time: ");
                    elapsedTimeStatic.setPadding(200, 0, 0, 0);
                    elapsedTimeStatic.setTextSize(20);

                    TextView elapsedTimeDynamic = new TextView(collection.getContext());
                    elapsedTimeDynamic.setText("00:00");
                    elapsedTimeDynamic.setPadding(0, 0, 0, 0);
                    elapsedTimeDynamic.setTextSize(20);

                elapsedLabels.addView(elapsedTimeStatic);
                elapsedLabels.addView(elapsedTimeDynamic);

            textLabels.addView(elapsedLabels);

        // adding images and text to overall view
        wholeView.addView(workoutWidget);
        wholeView.addView(startButton);
        wholeView.addView(resetButton);
        wholeView.addView(textLabels);

    collection.addView(wholeView, 0);

    return wholeView;
}
Adam Johns
  • 35,397
  • 25
  • 123
  • 176

2 Answers2

12

it loses the state because the viewpager by default only hold the previous and next page (an off screen page limit of 1). if you scroll to the last page then the first page will get destroyed.

you can increase the number of pages saved in memory by using setOffscreenPageLimit(2);

tyczj
  • 71,600
  • 54
  • 194
  • 296
  • thanks! i found another answer here: http://stackoverflow.com/questions/8891968/android-viewpager-saving-data-and-views that includes code example – Adam Johns Jul 09 '13 at 16:13
  • but will it not lose state after given off sreen page limit ? – Alex Jul 27 '18 at 16:20
2

Viewpager works according to current positions. There is the current position previous and next position depending on how many tabs or fragment your android app has. View pager only keeps memory of the next and previous pages. So you have to increase the number of off screen page limits to fit the number of screens to be swiped. You can do it by adding

  viewPager.setOffscreenPageLimit(2); to your code. 

I hope that works. Thank You in advance.

David Kariuki
  • 1,522
  • 1
  • 15
  • 30