0

I am trying to build a quiz app that keeps score as the user answers questions. I'm also using Google's ViewPager for screen slides which employs Fragments to keep different individual pages (code: http://developer.android.com/training/animation/screen-slide.html). I have a TextView (@id/txtvw_score) that is designed to keep score across the entire quiz session. This txtvw_score is placed within fragment_screen_slide_page.xml.

The problem I'm having is that, in order to access said TextView, I have to do it in ScreenSlidePageFragment's onCreateView() method. But, because Android calls this onCreateView() method twice for every new Fragment, it makes it so that the TextView's score is completely outdated. For example, page 1 would display the current score, then page 2 would display page 0 (uninitialized score), then page 3 would display page 1's score, etc.

I'm using SharedPreferences to keep the actual score updated. I've been able to keep track of the score perfectly fine when I use the ActionBar. This is only for confirmation purposes though, as I don't actually want to use the ActionBar.

Further complicating the problem is that I can't update the TextView within the Fragment's onCreate() method. I've also tried calling the TextView and changing it from ScreenSlideActivity (source: How to change fragment's textView's text from activity), but that ended up as NullPointerException no matter what I did.

So, long story short, how can I keep a TextView's content consistent across all Fragments? (This is a significant point for me, because, in the future, I want to use a TextView as a display for a timer as well, and that definitely needs to stay consistent).

EDIT (added simplified code):

fragment_screen_slide_page.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ScrollView
        android:id="@+id/scrlvw_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="15dp" >

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp" >

                <TextView
                    android:id="@+id/txtvw_score"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:textStyle="bold" />

            </RelativeLayout>
        </LinearLayout>
    </ScrollView>

</RelativeLayout>

ScreenSlidePageFragment.java

public class ScreenSlidePageFragment extends Fragment
{
    //The argument key for the page number this fragment represents.
    public static final String ARG_PAGE = "page";
    ArrayList<String> argAnswerList = new ArrayList<String>();

    //The fragment's page number, which is set to the argument value for {@link #ARG_PAGE}.
    private int mPageNumber;
    //preferences
    SharedPreferences sharedPrefs;
    SharedPreferences preferences;
    SharedPreferences.Editor editor;
    final int DEFAULT = 0;
    final int CHOSEN1 = 1;
    final int CHOSEN2 = 2;
    final int CHOSEN3 = 3;
    final int CHOSEN4 = 4;

    TextView txtvwScore;
    int questionsTotal;
    int numChosenCorrect, numChosenTotal, ratio;

    //Factory method for this fragment class. Constructs a new fragment for the given page number.
    public static ScreenSlidePageFragment create(int pageNumber)
    {
        ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, pageNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public ScreenSlidePageFragment() 
    {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);

        getActivity().getActionBar().show();

        fillArgAnswerList();
        //fillAnswerList();

        mPageNumber = getArguments().getInt(ARG_PAGE);

        getPrefs();
        preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
        editor = preferences.edit();

        numChosenCorrect = sharedPrefs.getInt("numChosenCorrect", DEFAULT);
        numChosenTotal = sharedPrefs.getInt("numChosenTotal", DEFAULT);
        ratio = sharedPrefs.getInt("ratio", DEFAULT);
        getActivity().getActionBar().setTitle("Score: " + numChosenCorrect + "/" + numChosenTotal + " (" + ratio + "%)");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        //Inflate the layout containing a title and body text.
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_screen_slide_page, container, false);

        //setting the score
        txtvwScore = (TextView) rootView.findViewById(R.id.txtvw_score);

        setButtonOnClickListener();

        return rootView;
    }

    private void setButtonOnClickListener()
    {
            button.setOnClickListener(new View.OnClickListener() 
            {
                @Override
                public void onClick(View v) 
                {
                    numChosenCorrect = sharedPrefs.getInt("numChosenCorrect", DEFAULT);
                    numChosenTotal = sharedPrefs.getInt("numChosenTotal", DEFAULT);
                    ratio = sharedPrefs.getInt("ratio", DEFAULT);

                    String answer = button.getText().toString();
                    if(answer.equals(correct))
                    {
                        numChosenCorrect++;
                        numChosenTotal++;
                    }
                    else
                        numChosenTotal++;

                    //update the actionBar score
                    ratio = Math.round(((float) numChosenCorrect)/((float) numChosenTotal)*100);

                    //setting the score
                    getActivity().getActionBar().setTitle("Score: " + numChosenCorrect + "/" + numChosenTotal + " (" + ratio + "%)");
                    editor.putInt("numChosenCorrect", numChosenCorrect);
                    editor.putInt("numChosenTotal", numChosenTotal);
                    editor.putInt("ratio", ratio);
                    editor.commit();
                }
            });
    }

    /**
     * Get the preferences saved.
     */
    private void getPrefs()
    {
        sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
    }

    /**
     * Returns the page number represented by this fragment object.
     */
    public int getPageNumber() 
    {
        return mPageNumber;
    }
}

All codes have been simplified to show what the question revolves around. All removed code has been tested and they work up until this point.

Community
  • 1
  • 1
user2323030
  • 1,193
  • 4
  • 16
  • 37
  • I think it would be best it you supplied a little code. You're using the same code for all `Fragments` of course, but when are you saving the score in `SharedPreferences` and when are you fetching it again? You could also just pass the next score inside the `Bundle` to the next `Fragment` but I guess that could make a mess if the user is going back in the backstack. – Darwind Feb 25 '14 at 22:42
  • Sure thing. Code's been added. – user2323030 Feb 25 '14 at 22:57

0 Answers0