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.