Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
125 views
in Technique[技术] by (71.8m points)

java - NPE thrown when trying to Find Button ID in Android Fragment

This issue has persisted repeatedly no matter how many times I redo this. According to Android Developers, the ID to an object in the View Hierarchy of a fragment is obtained during onCreateView, and all of the questions I've pored over on here confirm this. However for some reason it ALWAYS returns null during the check I have setup and therefore I can not proceed to work with the buttons. The Fragment gets loaded during "decision events" in this project, and each event has different decisions. Thus I want to use just one fragment and change the button texts as appropriate. However I can not seem to get them not to return null. I just need help to figure out what I am doing wrong that is causing the NPE.

DecisionFragment.java:

package com.saphiric.simproject.uimanipulation;

import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.saphiric.simproject.R;
import com.saphiric.simproject.datacontrols.DataCore;

public class DecisionFragment extends Fragment {

    // Activity/Global variables
    private static final String TAG = "DecisionFragment";
    DataCore dataCore = DataCore.getInstance();

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

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.i(TAG, "Begin: Inflate");

        // Gets handles to important UI elements for scalability
        View root = inflater.inflate(R.layout.fragment_decision, container, false);
        Button buttonTrue = (Button) root.findViewById(R.id.btnChoiceOne);
        Button buttonFalse = (Button) root.findViewById(R.id.btnChoiceTwo);


        if(buttonTrue == null){
            System.out.println("buttonTrue is null");
        } else {
            System.out.println("buttonTrue is working fine");
        }

        Log.i(TAG, "Finished: Inflate");
        if (root == null){
            Log.e(TAG, "omg Inflate == null");
        }
        switch (dataCore.controller.getCurrentDecision()){
            case "OPSDecision":
//                buttonTrue.setText(R.string.ops_decision_one);
//                buttonFalse.setText(R.string.ops_decision_two);
                break;
            default:
                System.out.println("ERROR: No decision set");
        }
        return root;
    }

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

    }
}

fragment_decision.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:orientation="horizontal"
    android:weightSum="1.0"
    tools:context="com.saphiric.simproject.uimanipulation.DecisionFragment">

    <Button
        android:id="@+id/decisionOne"
        android:layout_width="0dp"
        android:layout_height="90dp"
        android:layout_weight=".5"
        android:text="@string/defaul_btn"
        android:onClick="cryingDecisionOne"/>

    <Button
        android:id="@+id/decisionTwo"
        android:layout_width="0dp"
        android:layout_height="90dp"
        android:layout_weight=".5"
        android:text="@string/defaul_btn"
        android:onClick="cryingDecisionTwo"/>
</LinearLayout>

DayOne.java:

package com.saphiric.simproject.activities;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.saphiric.simproject.R;
import com.saphiric.simproject.datacontrols.DataCore;
import com.saphiric.simproject.uimanipulation.ControlsFragment;
import com.saphiric.simproject.uimanipulation.DecisionFragment;


/**
 * Created by Saphiric on 11/12/14.
 */
public class DayOne extends Activity {

    /**
     * Necessary activity variables
     */
    ControlsFragment controlsFragment = new ControlsFragment();
    DecisionFragment decisionFragment = new DecisionFragment();
    DataCore dataCore = DataCore.getInstance();

    /**
     * Android activity methods
     *
     * @param savedInstanceState is the apps savedInstanceState
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_day_one);

        // Initializes the opening story text
        // Initializes the dayProgress variable in DataController
        String storyStart = getResources().getString(R.string.story_opening_one);
        dataCore.controller.setCurrentText(storyStart);
        dataCore.controller.setCurrentDecision("OPSDecision");

        // Handles for fragment management
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // UI will add the ControlsFragment in it's starting state for that activity.
        fragmentTransaction.add(R.id.fragmentContainer, controlsFragment);
        fragmentTransaction.commit();
    }

    @Override
    public void onResume(){
        super.onResume();

    }

    public void cryingDecisionOne(View view) {

        dataCore.controller.setDayProgress(dataCore.controller.getDayProgress());

        // Sets cryingDecision Story Lock
        dataCore.locks.setCryingDecision(true);
        dataCore.controller.setCurrentDecision("HLSOne");

        // Removes the decision fragment and replaces it with the controls fragment
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // Sets the text to be pulled to storyText
        String decision = getResources().getString(R.string.crying_decision_true);
        dataCore.controller.setCurrentText(decision);

        fragmentTransaction.replace(R.id.fragmentContainer, controlsFragment);
        fragmentTransaction.commit();
    }

    public void cryingDecisionTwo(View view) {

        dataCore.controller.setDayProgress(dataCore.controller.getDayProgress());

        // Sets cryingDecision choice
        dataCore.locks.setCryingDecision(false);
        dataCore.controller.setCurrentDecision("HWSOne");

        // Removes the decision fragment and replaces it with the controls fragment
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // Updates the currentText for updating the story view
        String decision = getResources().getString(R.string.crying_decision_false);
        dataCore.controller.setCurrentText(decision);

        fragmentTransaction.replace(R.id.fragmentContainer, controlsFragment);
        fragmentTransaction.commit();
    }

    public void advanceGameFunction(View view) {

        String textUpdate;

        // Handles for fragment management
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        // Obtains handles to UI components
        TextView storyText = (TextView) findViewById(R.id.storyText);
        RelativeLayout gameStart = (RelativeLayout) findViewById(R.id.gameStart);
        ImageView charOne = (ImageView) findViewById(R.id.char_one);
        ImageView charTwo = (ImageView) findViewById(R.id.char_two);
        ImageView charThree = (ImageView) findViewById(R.id.char_three);
        ImageView charFour = (ImageView) findViewById(R.id.char_four);

        // Increments the data variable in DataController
        dataCore.controller.setDayProgress(dataCore.controller.getDayProgress());
        System.out.println(dataCore.controller.getDayProgress());

        // Switch case for handling day progression
        switch (dataCore.controller.getDayProgress()) {
            case 1:
                textUpdate = getResources().getString(R.string.story_opening_two);
                dataCore.controller.setCurrentText(textUpdate);
                storyText.setText(dataCore.controller.getCurrentText());
                break;
            case 2:
                fragmentTransaction.replace(R.id.fragmentContainer, decisionFragment);
                fragmentTransaction.commit();
                break;
            case 3:
                if (dataCore.locks.getCryingDecision()) {
                    storyText.setText(dataCore.controller.getCurrentText());

                } else {
                    storyText.setText(dataCore.controller.getCurrentText());
                }
                break;
            case 4:
                if (dataCore.locks.getCryingDecision()) {
                    textUpdate = getResources().getString(R.string.ops_d1_line1);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                } else {
                    textUpdate = getResources().getString(R.string.ops_d2_line1);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                }
                break;
            case 5: // Transition to hurt leg scene if Crying Decision is true, hallway scene if false
                if (dataCore.locks.getCryingDecision()){
                    gameStart.setBackgroundResource(R.drawable.bg_gym_front);
                    textUpdate = getResources().getString(R.string.hls_line1);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                }else{
                    gameStart.setBackgroundResource(R.drawable.bg_hallway);
                    textUpdate = getResources().getString(R.string.hws_line1);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                }
                break;
            case 6:
                if(dataCore.locks.getCryingDecision()){
                    textUpdate = getResources().getString(R.string.hls_line2);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                }else{
                    textUpdate = getResources().getString(R.string.hws_line2);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                }
                break;
            case 7:
                if(dataCore.locks.getCryingDecision()){
                    charOne.setVisibility(View.VISIBLE);
                    textUpdate = getResources().getString(R.string.hls_line3);
                    dataCore.controller.setCurrentText(textUpdate);
                    storyText.setText(dataCore.controller.getCurrentText());
                }else {

                }
                break;
            case 8:
                if(dataCore.locks.getCryingDecision()){
                    textUpdate = getResources().getString(R.string.hls_line4);
                    dataCore.controller.setCurrentText(textUpdate);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are using the wrong ids in your code! The buttons in your layout have the id decisionOne and decisionTwo but in your code you are using btnChoiceOne and btnChoiceTwo.

To fix it replace this:

Button buttonTrue = (Button) root.findViewById(R.id.btnChoiceOne);
Button buttonFalse = (Button) root.findViewById(R.id.btnChoiceTwo);

with this in your DecisionFragment:

Button buttonTrue = (Button) root.findViewById(R.id.decisionOne);
Button buttonFalse = (Button) root.findViewById(R.id.decisionTwo);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...