.getSupportActionBar在Fragment中不可用; 变通方法导致旋转时出现NullPointerException

Pat*_*Feu 9 android android-appcompat android-fragments android-actionbar-compat android-actionbaractivity

结构体

(活动/碎片的名称已更改)

根据Android编程中的一些建议:The Big Nerd Ranch Guide,我有以下结构:

  • MyListFragment extends ListFragment
  • MyListActivity extends SimpleFragmentActivity
  • SimpleFragmentActivity extends ActionBarActivity

MyListActivity.java

public class MyListActivity extends SingleFragmentActivity {

    @Override
    protected Fragment createFragment() {
        return new MyListFragment();
    }
}
Run Code Online (Sandbox Code Playgroud)

SingleFragmentActivity.java

public abstract class SingleFragmentActivity extends ActionBarActivity {

    protected abstract Fragment createFragment ();

    @Override
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);

        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);

        if (fragment == null) {
            fragment = createFragment();
            fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在概述并编写了我的应用程序的基本功能(包括上下文操作栏,导航......)之后,我想确保应用程序尽可能向后兼容,而无需太多额外的工作.因此,我开始使用AppCompat(com.android.support:appcompat-v7:20+)ActionBar.

一开始让我感到困惑的是 - 与我读过的每个教程或Android的开发人员指南相反 - 在Android Studio中我从未使用过getSupportActionBar方法(我使用的是Android Studio v0.8.2和JRE 1.7_60).每当我输入时getActivity().getSup,我得到的唯一建议是getSupportFragmentManagergetSupportLoaderManager.

作为一种变通方法,我创建了一个成员变量ActionBar mActionBarMyListFragment,并初始化它:

@Override
public void onAttach (Activity activity) {
    super.onAttach(activity);
    mActionBar = ((ActionBarActivity) activity).getSupportActionBar();
}
Run Code Online (Sandbox Code Playgroud)

这似乎可以解决Android 4.4.4(Moto G)和2.3.4(LG E-510) - 我唯一可用的设备.

但是,我遇到了问题 - 旋转时ActionBar赋值丢失,应用程序崩溃并出现NullPointerException.调试应用程序并在以下行中设置断点onCreate:

mActionBar.setTitle(R.string.title_activity_my_list);
Run Code Online (Sandbox Code Playgroud)

我发现旋转后mActionBar为空.放置所述线onCreateView并没有帮助.

我尝试了什么

  • 配售的初始化mActionBar
    • onAttach
    • onActivityCreated
    • onCreate/ onCreateView在.setTitle被调用之前

我在这里缺乏想法,并感谢您的建议.

编辑0(30.07.)

抛出异常(根据Alex的建议编辑后)

07-30 15:05:25.239    5049-5049/MYAPPNAME E/AndroidRuntime? [Blue Error Handler] Make Debugging Report file for main
java.lang.RuntimeException: Unable to start activity ComponentInfo{MYAPPNAME/MYAPPNAME.MYLISTACTIVITY}: java.lang.NullPointerException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1653)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1669)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838)
    at android.app.ActivityThread.access$1600(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3737)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at MYAPPNAME.MYLISTFRAGMENT.onCreate(MYLISTFRAGMENT.java:54)
    at android.support.v4.app.Fragment.performCreate(Fragment.java:1481)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:908)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
    at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1896)
    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:216)
    at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98)
    at MYAPPNAME.SingleFragmentActivity.onCreate(SingleFragmentActivity.java:22)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1617)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1669)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2838)
    at android.app.ActivityThread.access$1600(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3737)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:894)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
    at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

MyListFragment第54行(使用SingleFragmentActivity ActionBarActivity作为强制转换发生异常)

((SingleFragmentActivity) getActivity()).getSupportActionBar().setTitle(R.string
            .title_activity_my_list);
Run Code Online (Sandbox Code Playgroud)

SingleFragmentActivity 第20-22行:

@Override
public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 33

将您getActivity()转移到ActionBarActivity/ AppCompatActivity(取决于您使用的是什么),您将可以访问该支持ActionBar.

((AppCompatActivity)getActivity()).getSupportActionBar();
Run Code Online (Sandbox Code Playgroud)

要么

((ActionBarActivity)getActivity()).getSupportActionBar();
Run Code Online (Sandbox Code Playgroud)

onActivityCreated(...)方法中使用此代码而不是onAttach(...)

  • 我之前在`onCreate()`中有过它.把它放在`onActivityCreated()`似乎工作.我会尝试在整个应用程序中更改事件; 如果它到处工作,我会接受你的回答.谢谢到目前为止! (2认同)

dev*_*ife 7

现在它应该是:

((AppCompatActivity)getActivity()).setSupportActionBar();
Run Code Online (Sandbox Code Playgroud)

因为不推荐使用ActionBarActivity.

但这只有在你必须在一项活动之外进行的时候,这是最常见的活动.