为什么getFragmentManager()。findFragmentById返回null(导致NullPointerException)

时间:2015-03-02 07:10:09

标签: android android-fragments nullpointerexception fragmenttransaction

我有两个片段:输入在顶部,结果在底部。

最初,只显示InputFragment。当用户单击“计算”按钮时,将显示ResultFragment。这一切都运作良好。

ResultFragment有一个“全部清除”按钮,我想清除InputFragment的字段,并使ResultFragment消失(隐藏,删除或分离,我不关心哪个,只要它变得不可见)。

但是当你点击“全部清除”按钮时它会崩溃。具体而言,clearResult()方法中会发生致命的NullPointerException

这是MainActivity.java

import android.support.v7.app.ActionBarActivity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity implements InputFragment.InputFragmentListener, ResultFragment.ResultFragmentListener {

    private static FragmentManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(savedInstanceState == null){
            Fragment inputFragment  = new InputFragment();

            manager = getFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.add(R.id.fragment_container_top,inputFragment).commit();
        }
    }

    //This gets called by the Input Fragment when the user clicks the Calculate button
    @Override
    public void createResult(String resultPhrase) {

        ResultFragment resultFragment = (ResultFragment) manager.findFragmentById(R.id.result_fragment);

        if (resultFragment != null){
            /* if resultFragment is available, we can modify it's TextView
             * by calling the method to do the updating
             */
            //ResultFragment.theResultText.setText(resultPhrase);
            resultFragment.setResultText(resultPhrase); 
        }else{
            /*...otherwise the fragment has to be created */
            ResultFragment newResultFragment = new ResultFragment();
            Bundle args = new Bundle();
            args.putString(ResultFragment.resultTxt, resultPhrase);
            newResultFragment.setArguments(args);

            FragmentTransaction transaction = manager.beginTransaction();   
            transaction.replace(R.id.fragment_container_bottom, newResultFragment);
            transaction.addToBackStack(null);
            transaction.commit();       

            //((TextView) newResultFragment.getView().get).setText(resultPhrase);

        }


    }


    //This gets called in the ResultFragment when the user clicks the Clear All button
    @Override
    public void clearResult() {
        //InputFragment inp_frag = (InputFragment) getFragmentManager().findFragmentById(R.id.fragment_input);


        // This damned object is null again 
        //inp_frag.clearFields();
        Fragment res_frag = getFragmentManager().findFragmentByTag("resultfragtag");

        FragmentTransaction transaction = getFragmentManager().beginTransaction();  
        //res_frag.clearResult();
        transaction.hide(res_frag);
        transaction.commit();   

    }

    @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.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

以下是LogCat消息:

  

03-01 23:30:34.663:E / AndroidRuntime(3399):致命异议:主要
  03-01 23:30:34.663:E / AndroidRuntime(3399):处理:com.example.amortizersandbox,PID:3399
  03-01 23:30:34.663:E / AndroidRuntime(3399):java.lang.NullPointerException:尝试在空对象引用上写入字段'int android.app.Fragment.mNextAnim'   03-01 23:30:34.663:E / AndroidRuntime(3399):在android.app.BackStackRecord.run(BackStackRecord.java:797)

3 个答案:

答案 0 :(得分:3)

替换/添加片段使用:

getSupportFragmentManager()
                            .beginTransaction()
                            .setCustomAnimations(R.anim.slide_in_top,
                                    R.anim.slide_out_top)
                            .add(R.id.list_frame, fr, "tag").commit();

现在找到这个片段使用:

Fragment fr = getSupportFragmentManager()
                .findFragmentByTag("tag");
        if (fr != null) {
            //do your stuff
        } else {
//fr is null here
        }

答案 1 :(得分:0)

添加InputFragment时不使用标记“resultfragtag”。

尝试在onCreate上添加:

 transaction.add(R.id.fragment_container_top,inputFragment,"resultfragtag").commit();

答案 2 :(得分:0)

使用:

Fragment res_frag = getFragmentManager().findFragmentById(R.id.result_fragment);

取代:

Fragment res_frag = getFragmentManager().findFragmentByTag("resultfragtag");