无法将活动界面附加到Fragment。获取NullPointerException

时间:2016-04-29 20:52:52

标签: android android-fragments nullpointerexception

我正在为学校编写应用程序,当我在模拟器中运行应用程序时,一切正常。

问题在于我通过USB连接手机并在手机上运行应用程序。

每当我做一些需要mListener的事情(在整个app中的任何一个片段中)时,我的mListener上都会出现nullpointerexception。

我已搜索但未找到解决方案或类似问题。

我的所有片段都有问题,但我只会在这里显示1个片段:

片段代码:

public class QuizFragment extends Fragment {

private OnFragmentQuizInteractionListener mListener;

List<Vraag> quesList;
int qid=0;
Vraag currentQ;
TextView txtQuestion;
RadioButton rda, rdb, rdc;
Button butNext;
TextView txtResult;

Button btnToonAntwoord;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    getActivity().setTitle("Quiz");
    final View view = inflater.inflate(R.layout.quiz_layout, container, false);

    //btnStart = (Button) getActivity().findViewById(R.id.btnStart);
    //btnStart.setOnClickListener(new View.OnClickListener() {
    //    @Override
     //   public void onClick(View v) {
      //      mListener.initQuiz();
       // }
    //});

    //reset the score to 0
    mListener.resetScore();


    qid=0;

    QuizDbHelper db=new QuizDbHelper(view.getContext());
    quesList=db.getAllQuestions();
    currentQ=quesList.get(qid);
    txtQuestion=(TextView) view.findViewById(R.id.textView1);
    rda=(RadioButton)view.findViewById(R.id.radio0);
    rdb=(RadioButton)view.findViewById(R.id.radio1);
    rdc=(RadioButton)view.findViewById(R.id.radio2);

    //zet de radiobuttons klaar om geklikt te worden.
    rda.setEnabled(true);
    rdb.setEnabled(true);
    rdc.setEnabled(true);


    butNext=(Button)view.findViewById(R.id.btnNext);
    btnToonAntwoord=(Button)view.findViewById(R.id.btnToonAntwoord);
    txtResult = (TextView) view.findViewById(R.id.resultTextview);
    setQuestionView(view);

    setOnClickListeners(view);


    return view;

}

private void setOnClickListeners(View v){
    final View thisView = v;

    butNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            if(qid<8){

                //zet de radiobuttons klaar om geklikt te worden.
                rda.setEnabled(true);
                rdb.setEnabled(true);
                rdc.setEnabled(true);

                //zet het resultaat terug op niets
                txtResult.setText("");

                //Wanneer het goed is, voeg 1 bij de score bij
                RadioGroup grp = (RadioGroup) thisView.findViewById(R.id.radioGroup1);
                RadioButton answer = (RadioButton) thisView.findViewById(grp.getCheckedRadioButtonId());
                if (currentQ.getANSWER().equals(checkChecked(answer.getId()))) {
                    mListener.incrementScore();
                }


                currentQ=quesList.get(qid);
                setQuestionView(thisView);
            }else{
                //ga naar het eindscherm met het resultaat.
                mListener.navigeerEindscore();
            }
        }
    });

    btnToonAntwoord.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            RadioGroup grp = (RadioGroup) thisView.findViewById(R.id.radioGroup1);
            RadioButton answer = (RadioButton) thisView.findViewById(grp.getCheckedRadioButtonId());

            //toon de juiste boodschap aan de hand van het antwoord die gegeven is.
            if (currentQ.getANSWER().equals(checkChecked(answer.getId()))) {
                txtResult.setText(currentQ.getGoedeFeedback());
            }else{
                txtResult.setText(currentQ.getSlechteFeedback());
            }
            //zet de radiobuttons klaar om geklikt te worden.
            rda.setEnabled(false);
            rdb.setEnabled(false);
            rdc.setEnabled(false);
        }
    });


}

private String checkChecked(int id) {
    if(id == R.id.radio0){
        return "A";
    }else if(id == R.id.radio1){
        return "B";
    }else{
        return "C";
    }
}


private void setQuestionView(View v)
{
    txtQuestion.setText(currentQ.getQUESTION());
    rda.setText(currentQ.getOPTA());
    rdb.setText(currentQ.getOPTB());
    rdc.setText(currentQ.getOPTC());
    qid++;
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    if (context instanceof OnFragmentQuizInteractionListener) {
        mListener = (OnFragmentQuizInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnResultFragmentInteractionListener");
    }


}

public interface OnFragmentQuizInteractionListener {


    void incrementScore();

    void resetScore();

    void navigeerEindscore();
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

mainActivity:

{
public class MainActivity extends AppCompatActivity
    implements     NavigationView.OnNavigationItemSelectedListener,DashboardFragment.OnFragmentLoginInteractionListener,LoginFragment.OnFragmentLoginInteractionListener, RegistratieFragment.OnFragmentRegistratieInteractionListener,QuizFragment.OnFragmentQuizInteractionListener, ResultFragment.OnResultFragmentInteractionListener{


private FragmentManager fragmentManager;

public int quizScore;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    Utils.onActivityCreateSetTheme(this);
    setContentView(R.layout.activity_main);

    quizScore = 0;


    SharedPreferences pref = PreferenceManager
            .getDefaultSharedPreferences(this);
    String themeName = pref.getString("Theme1", "Blauw");


    //toolbar ophalen
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    Log.i("huidige preferences", themeName);

    //toolbar instellen
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();




    /**if (themeName.equals("Blauw")) {
        setTheme(R.style.AppTheme_blauw);

        Log.i("MyActivity", "in blauw");
    } else if (themeName.equals("Groen")) {

        this.setTheme(R.style.AppTheme_groen);
        Log.i("MyActivity", "in groen");
    } else if (themeName.equals("Roze")) {
        this.setTheme(R.style.AppTheme_roze);
        Log.i("MyActivity", "in roze");
    }**/

    fragmentManager = getFragmentManager();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    fragmentManager.beginTransaction().replace(R.id.content_frame, new DashboardFragment()).commit();

}


//backknop werkt hoe hij moet werken
@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);

    int count = getFragmentManager().getBackStackEntryCount();


    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {

        if (count == 0) {
            super.onBackPressed();
            //additional code
        } else {
            getFragmentManager().popBackStack();
        }

    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.


    switch (item.getItemId()) {
        case R.id.action_settings:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new InstellingenFragment()).commit();
            return true;
    }

    return super.onOptionsItemSelected(item);
}

//region dashboard
public void MijnProfielClicked() {
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new MijnProfielFragment())
            .addToBackStack("MijnProfiel")
            .commit();
}

public void AlarmClicked() {
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new PilAlarmFragment())
            .addToBackStack("Pilalarm")
            .commit();
}

public void KalenderClicked() {
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new MenstruatieFragment())
            .addToBackStack("Kalender")
            .commit();
}
//endregion


//Navigatiemethodes LOGIN

public void Login() {
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new DashboardFragment())
            .addToBackStack("Login")
            .commit();

}

//Navigatiemethodes REGISTREREN
public void Registreer() {
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new DashboardFragment())
            .addToBackStack("Registreer")
            .commit();
}
public void Annuleren() {
    getFragmentManager().beginTransaction().replace(R.id.content_frame, new LoginFragment())
            .addToBackStack("Registreer")
            .commit();
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.

    switch (item.getItemId()) {
        case R.id.nav_dashboard_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new DashboardFragment()).addToBackStack("dashboard").commit();
            break;
        case R.id.nav_mijnprofiel_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new MijnProfielFragment()).addToBackStack("mijnprofiel").commit();
            break;
        case R.id.nav_categorieen_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new CategorieenFragment()).addToBackStack("categorieen").commit();
            break;
        case R.id.nav_pilalarm_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new PilAlarmFragment()).addToBackStack("pilalarm").commit();
            break;
        case R.id.nav_menstruatie_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new MenstruatieFragment()).addToBackStack("menstruatie").commit();
            break;
        case R.id.nav_quiz_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new QuizFragment()).addToBackStack("quiz").commit();
            break;
        case R.id.nav_instellingen_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new InstellingenFragment()).addToBackStack("instellingen").commit();
            break;
        case R.id.nav_partners_layout:
            fragmentManager.beginTransaction().replace(R.id.content_frame, new PartnersFragment()).addToBackStack("partners").commit();
            break;


    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}


//region Partner onclick listeners
public void onVivesPartner_clicked(View view) {
    // Perform action on click

    goToUrl("http://www.vives.be/");

}

public void onSensoaPartner_clicked(View view) {
    // Perform action on click

    goToUrl("http://www.sensoa.be/");
}

public void onUgentPartner_clicked(View view) {
    // Perform action on click

    goToUrl("http://www.ugent.be/");
}

public void onUCCVPartner_clicked(View view) {
    // Perform action on click

    goToUrl("http://www.ucvvgent.be/nl/");
}

public void onOnePartner_clicked(View view) {
    // Perform action on click

    goToUrl("http://www.one.be//");
}


private void goToUrl(String url) {
    Uri uriUrl = Uri.parse(url);
    Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
    startActivity(launchBrowser);
}


//endregion


//region quizfragment
@Override
public void incrementScore() {
    quizScore++;
}

@Override
public void resetScore() {
    quizScore = 0;
}

@Override
public void navigeerEindscore() {
    fragmentManager.beginTransaction().replace(R.id.content_frame, new ResultFragment()).commit();
}


@Override
public int getScore() {
    return quizScore;
}

//endregion

我得到的错误(没有什么片段,它总是在mlistener上的nullpointerexception)

java.lang.NullPointerException: Attempt to invoke interface method 'void be.vives.pwo_kinderwens.Quiz.QuizFragment$OnFragmentQuizInteractionListener.resetScore()' on a null object reference
 at be.vives.pwo_kinderwens.Quiz.QuizFragment.onCreateView(QuizFragment.java:55)
 at android.app.Fragment.performCreateView(Fragment.java:2053)
 at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
 at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
 at android.app.BackStackRecord.run(BackStackRecord.java:834)
 at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
 at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)
 at android.os.Handler.handleCallback(Handler.java:739)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:135)
 at android.app.ActivityThread.main(ActivityThread.java:5294)
 at java.lang.reflect.Method.invoke(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:372)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

3 个答案:

答案 0 :(得分:0)

问题是您的mListener未实施。

我会尝试以下方法:

我会向QuizFragment添加一个方法,如:

public void setFragmentQuizInteractionListener(OnFragmentQuizInteractionListener  mListener)
 { 
 this.mListener = mListener;    
}    

然后

case R.id.nav_quiz_layout:    
    QuizFragment quizFragment = new QuizFragment();
    quizFragment.setFragmentQuizInteractionListener(this);
    fragmentManager.beginTransaction().replace(R.id.content_frame, quizFragment ).addToBackStack("quiz").commit();
    break;

放弃onAttach()方法 可能不是最好的方式,但值得一试。

答案 1 :(得分:0)

您需要覆盖

public void onAttach (Activity activity)

而不是

public void onAttach (Context context)

后者包含在API级别23中,因此以前版本的Android不会调用它。

请参阅onAttach (Activity activity)

答案 2 :(得分:0)

在Fragment中使用onAttach方法。检查片段生命周期

 Context context;                                
        @Override
            public void onAttach(Context context) {
            super.onAttach(context);
            this.context=context;
        }