为什么 getFragmentManager().findFragmentById 返回 null(导致 NullPointerException) [英] Why is getFragmentManager().findFragmentById returning null (causing NullPointerException)

查看:68
本文介绍了为什么 getFragmentManager().findFragmentById 返回 null(导致 NullPointerException)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two fragments: input on top, and result on bottom.

最初,只显示 InputFragment.当用户单击计算"按钮时,将显示 ResultFragment.这一切都很好.

Initially, only the InputFragment shows. When the user clicks the "Calculate" button, the ResultFragment shows. That all works well.

ResultFragment 有一个全部清除"按钮,我想清除 InputFragment 的字段,并使 ResultFragment 消失(隐藏、删除或分离,我不在乎哪个,只要它变得不可见).

The ResultFragment has a "Clear all" button, which I want to clear the InputFragment's fields, and make ResultFragment go away (hide, remove, or detach, I don't care which, so long as it becomes invisible).

但是当您点击全部清除"按钮时它会崩溃.具体来说,一个致命的 NullPointerException 发生在 clearResult() 方法中.

But it crashes when you hit "Clear all" button. Specifically, a fatal NullPointerException happens in clearResult() method.

这里是 MainActivity.java

Here is 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 消息:

Here are the LogCat messages:

03-01 23:30:34.663:E/AndroidRuntime(3399):致命异常:main
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)

03-01 23:30:34.663: E/AndroidRuntime(3399): FATAL EXCEPTION: main
03-01 23:30:34.663: E/AndroidRuntime(3399): Process: com.example.amortizersandbox, PID: 3399
03-01 23:30:34.663: E/AndroidRuntime(3399): java.lang.NullPointerException: Attempt to write to field 'int android.app.Fragment.mNextAnim' on a null object reference
03-01 23:30:34.663: E/AndroidRuntime(3399): at android.app.BackStackRecord.run(BackStackRecord.java:797)

推荐答案

用于替换/添加片段使用:

For replacing/adding fragment use:

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

现在找到这个片段使用:

Now for finding this fragment use:

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

这篇关于为什么 getFragmentManager().findFragmentById 返回 null(导致 NullPointerException)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆