Android - 回调后 Fragment 出现 NullPointerException

Android - NullPointerException in Fragment after callback

这是我第一次使用Fragments,我不太了解如何管理它们。在这种情况下,我有两个片段,它们在 FrameLayout 中动态显示,id 为 fragment_place。问题可能出在 fragmentTransaction(addtobackstack / popbackstack)。

在 Fragment2 中,当我在移动设备上按下菜单按钮时,我会显示一个弹出菜单,它第一次按预期工作,但在我返回到上一个片段并 return 现在到片段 2 之后,如果我按下menubutton 我收到以下错误

java.lang.NullPointerException
at android.support.v7.view.menu.MenuBuilder.<init>(MenuBuilder.java:216)
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:103)
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:78)
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:63)
at package.Fragment2.showPopup(Fragment2.java:93)

下面是 mainactivity 和 fragment2 的代码,这让我抓狂,任何帮助将不胜感激。

public class MainActivity extends AppCompatActivity implements Fragment1.onEvent {

Fragment1 frag;
Fragment2 frag2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    frag = new Frag1();
    // Begin the transaction
    FragmentTransaction  ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_place, frag);
    ft.commit();
}

@Override
public void onEventSelected(String key) {
    frag2 = new Frag2();
    FragmentTransaction  ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_place,frag2);
    ft.addToBackStack(null);
    ft.commit();
}

@Override
public void onBackPressed(){
    FragmentManager ft = getSupportFragmentManager();
    if (ft.getBackStackEntryCount() > 0) {
        ft.popBackStack();
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    int action = event.getAction();
    int keyCode = event.getKeyCode();
    switch (keyCode) {
        case KeyEvent.KEYCODE_MENU:
            if (action == KeyEvent.ACTION_UP) {
                Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_place);
                if (f instanceof Fragment2) {
                    sendBroadcast();
                }
            }
            return true;
        default:
            return super.dispatchKeyEvent(event);
    }
}

private void  sendBroadcast(){
    Intent intent = new Intent("popup_menu");
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}}

这是有问题的片段。错误行基本上是方法 showPopup

  public class Fragment2 extends Fragment {
private String key;
private View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment, parent, false);
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMessageReceiver,
            new IntentFilter("popup_menu"));

    return view;
}

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 
    @Override
    public void onReceive(Context context, Intent intent) {
        showPopup(view);
    }
};


public void showPopup(View v) {
    Button b = (Button) view.findViewById(R.id.b_attach);
    PopupMenu popup = new PopupMenu(getActivity(), b);

    popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
               //dosomething
            }
    });
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.menu_popup, popup.getMenu());
    popup.show();
}}

这是我的做法,对我很有效:

FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.content_frame,new fragment() ).commit();

我解决了摆脱 sendbroadcast() 和 broadcastReceiver() 的问题,现在我在需要时直接从 mainActivity 调用 showPopup()。