dtgee
dtgee

Reputation: 1272

Set fragment contents before or after adding?

I'm basically trying to create this quiz system, where I have a template of questions, and I dynamically change the content of the questions: For example:

Who directed movie X?
   - Incorrect answer director
   - Correct answer director
   - Incorrect answer director
   - Incorrect answer director

I will replace X with some movie that I select from my database. Following the question will have 4 selectable options (also generated based on question), and the user can only click one of them. The question and answers are all inside a fragment .xml file. I'm trying to change the contents of the fragment before displaying it. I've read the android documents, but this section doesn't seem to have been written in enough detail.

public class QuizTemplate extends ActionBarActivity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_quiz_template);
            if (savedInstanceState == null) {
                PlaceholderFragment firstFragment = new PlaceholderFragment();

                // Trying to set question before I commit transaction
                // firstFragment.setQuestion("IT WORKS!");

                FragmentManager manager = getSupportFragmentManager();
                manager.beginTransaction()
                .add(R.id.container2, firstFragment).commit();

    //          Tried to execute pending transactions, then find view
                manager.executePendingTransactions();

                PlaceholderFragment firstFragment = (PlaceholderFragment) manager.findFragmentById(R.id.container2);
                RadioButton answer1 = (RadioButton) firstFragment.getView().findViewById(R.id.answer1);
                RadioButton answer2 = (RadioButton) firstFragment.getView().findViewById(R.id.answer2);
                RadioButton answer3 = (RadioButton) firstFragment.getView().findViewById(R.id.answer3);
                RadioButton answer4 = (RadioButton) firstFragment.getView().findViewById(R.id.answer4);
                TextView question  = (TextView) firstFragment.getView().findViewById(R.id.question);

                question.setText("test");
                answer1.setText("test");
    //          ... and so on
    }
}

Fragment Class

public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_quiz_template,
                container, false);
        return rootView;
    }

    public void setQuestion(String text){
        TextView textView = (TextView) getView().findViewById(R.id.question);
        textView.setText(text);
    }
}

(layout) fragment_quiz_template.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.moviequiz.QuizTemplate$PlaceholderFragment" >

    <TextView
        android:id="@+id/question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="65dp"
        android:text="@string/hello_world" />

    <RadioButton
        android:id="@+id/answer2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/answer3"
        android:layout_below="@+id/answer3"
        android:layout_marginTop="28dp"
        android:onClick="changeQuestion"
        android:text="@string/hello_world" />

    <RadioButton
        android:id="@+id/answer3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/answer4"
        android:layout_below="@+id/answer4"
        android:layout_marginTop="17dp"
        android:onClick="changeQuestion"
        android:text="@string/hello_world" />

    <RadioButton
        android:id="@+id/answer4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/answer1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:onClick="changeQuestion"
        android:text="@string/hello_world" />

    <RadioButton
        android:id="@+id/answer1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/answer4"
        android:layout_below="@+id/question"
        android:layout_marginTop="40dp"
        android:onClick="changeQuestion"
        android:text="@string/hello_world" />

</RelativeLayout>

None of my approaches have worked, as my app crashes upon reaching the quiz (Nothing in the log?). Any ideas what could be going wrong?

EDIT: Fixed my log, it now tells me:

Unable to start activity ComponentInfo: java.lang.NullPointerException

So my guess is when I call something like

RadioButton answer1 = (RadioButton) firstFragment.getView().findViewById(R.id.answer1);

answer1 is null. But why is this the case if I execute pending transactions?

Upvotes: 1

Views: 136

Answers (1)

Kuffs
Kuffs

Reputation: 35661

Your code that generates the UI in the fragment takes time to execute. I believe that even though you are committing the transactions, the UI is still not ready when you are trying to access it. Don't forget that your fragment lifecycle is linked to your activity lifecycle yet you are expecting to access the fragment UI in the OnCreate method of your activity.

Consider instead using the callback pattern to communicate between your activities and fragments.

http://developer.android.com/training/basics/fragments/communicating.html

Using this pattern, you can call your activity code when you are sure the UI is complete and available.

Upvotes: 1

Related Questions