3

This is a follow up of this question ViewPager and fragments — what's the right way to store fragment's state?. I need someone to interpret this part of the answer in code.

Another approach is to override FragmentPageAdapter.instantiateItem(View, int) and save a reference to the fragment returned from the super call before returning it (it has the logic to find the fragment, if already present).

I am using using a PagerAdapter to load data from a cursor into a viewpager. I have already overridden the PagerAdapter.intantiateItem. All i need is to be able to save the state of the Button that was clicked. This is my code

    public class CustomQuestionPagerAdapter extends PagerAdapter {

private Cursor cursor;
private Cursor cursorCategory;
private LayoutInflater inflater;
private Context context;
private ArrayList<String> optionsArray; 
String rightAnswer;
String wrongAnswer1;
String wrongAnswer2;
Button option1;
Button option2;
Button option3;

public CustomQuestionPagerAdapter(Context context, Cursor cursor1, Cursor cursor2) {
    this.context = context;
    this.cursor = cursor1;
    this.cursorCategory = cursor2;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}        

public void swapCursor(Cursor cursor) {
    this.cursor = cursor;
}

public void swapAnotherCursor(Cursor cursor) {
    this.cursorCategory = cursor;
}


public void destroyItem(View view, int position, Object object) {
    ((ViewPager) view).removeView((ScrollView) object);
}

@Override
public int getCount() {
    if (cursor == null) {
        return 0;
    }else {
        return cursor.getCount();
    }
}



/* (non-Javadoc)
 * @see android.support.v4.view.PagerAdapter#instantiateItem(android.view.View, int)
 */


@Override
public Object instantiateItem(View view, int position) {

    cursor.moveToPosition(position);
    final ViewPager pager = (ViewPager) view.findViewById(R.id.pager_nav);
    ScrollView layout = (ScrollView) inflater.inflate(R.layout.question_activity, null);
    if (cursorCategory != null && cursorCategory.moveToFirst()){
        String s = cursorCategory.getString(cursorCategory.getColumnIndex("name"));
        ((TextView)layout.findViewById(R.id.text_category)).setText(s);
    }

    Typeface tpf = Typeface.createFromAsset(context.getAssets(), "Roboto-Light.ttf");
    String text = cursor.getString(cursor.getColumnIndex("question_text"));
    TextView question_text =  (TextView)layout.findViewById(R.id.text_question);
    question_text.setText(text);
    question_text.setTypeface(tpf);

    String qPos = Integer.toString(position + 1) + ".";
    TextView question_position = (TextView) layout.findViewById(R.id.text_position);
    question_position.setText(qPos);
    question_position.setTypeface(tpf);

    this.rightAnswer = cursor.getString(cursor.getColumnIndex(DBHelper.RIGHT_ANSWER));
    this.wrongAnswer1 = cursor.getString(cursor.getColumnIndex(DBHelper.WRONG_ANSWER1));
    this.wrongAnswer2 = cursor.getString(cursor.getColumnIndex(DBHelper.WRONG_ANSWER2));

    optionsArray = new ArrayList<String>();
    optionsArray.clear();
    optionsArray.add(this.rightAnswer);
    optionsArray.add(this.wrongAnswer1);
    optionsArray.add(this.wrongAnswer2);
    Collections.shuffle(optionsArray);

    option1 = (Button) layout.findViewById(R.id.button_option1);
    option1.setText((CharSequence) this.optionsArray.get(0));

    option2 = (Button) layout.findViewById(R.id.button_option2);
    option2.setText((CharSequence) this.optionsArray.get(1));

    option3 = (Button) layout.findViewById(R.id.button_option3);
    option3.setText((CharSequence) this.optionsArray.get(2));


    final Button next = (Button) layout.findViewById(R.id.next_button);
    next.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            int j = getItem(+1) + 1;
            Toast.makeText(context, context.getResources().getString(R.string.question_no) + " " + j, Toast.LENGTH_SHORT).show();
            pager.setCurrentItem(getItem(+1), true);
            next.setBackgroundColor(0xffeeeeee); // i need to save this new bacground color
        }

        private int getItem(int i) {
            return i += pager.getCurrentItem();
        }
    });

I tried this answer too but it didn't work Saving Fragment state in ViewPager

Thanks in advance.

Community
  • 1
  • 1
Jimi
  • 539
  • 5
  • 21

2 Answers2

2

PagerAdapter doesn't automatically save and restore the views on state restoration.
You need the equivalent of FragmentStatePagerAdapter but for Views. You can choose whether implement it on your own or extend a component already available. On GitHub there are some: for instance https://github.com/NightlyNexus/ViewStatePagerAdapter.
If you need to recycle the view holder there is even a view pager adapter from the great Jake Wharton https://github.com/JakeWharton/salvage. I've used the former as for my case it suited better, just replace your PageAdapter with the new ViewStatePagerAdapter and override createView(ViewGroup, int) and destroyView(ViewGroup, int).
Check the example is really easy to follow.

Sarpe
  • 5,747
  • 2
  • 28
  • 26
1

Dynamically save the button_id which are clicked in shared pref. You have already done everything, you need to restore button state from you shared pref and when you are clicking any button add the button in the shared pref.
Update:

 public static final String PREFS_NAME = "MyPrefsFile";
 ------
final Button next = (Button) layout.findViewById(R.id.next_button);
 SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean isClicked = settings.getBoolean(getCurrentItemPosition(), false);
        if(isClicked)
        {
        next.setBackgroundColor(0xffeeeeee);
        }

    next.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            int j = getItem(+1) + 1;
            Toast.makeText(context, context.getResources().getString(R.string.question_no) + " " + j, Toast.LENGTH_SHORT).show();
            pager.setCurrentItem(getItem(+1), true);
             // i need to save this new bacground color
        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(getCurrentItemPosition(), true);
        editor.commit();
        }

        private int getItem(int i) {
            return i += pager.getCurrentItem();
        }
    });

getCurrentItemPosition() is the current itemposition.

Pradip
  • 3,189
  • 3
  • 22
  • 27
  • I would appreciate it if i can get some code. I understand the concept of sharedPreferences and i have used it in other parts of my project but i don't know how to get the button_id for each view. Thanks. – Jimi Nov 27 '13 at 11:05
  • You have the pager View_Id and corresponding button_id-> Now when your saving it to shared pref save in your custom format like `viewId_buttonId`, and at the time of restoring if button_id and view_id matched then restore. got my point? – Pradip Nov 27 '13 at 11:12
  • Unfortunately, i don't. – Jimi Nov 27 '13 at 13:11
  • It worked after some modification to your code. The problem now is when the button is clicked, it doesn't take immediate effect (until the user swipes about two views before or after) and then returns that screen. How can this be solved? – Jimi Nov 27 '13 at 16:31
  • Update your pager adapter, to reflect effect properly. – Pradip Nov 27 '13 at 18:05