结构
(活动/碎片的名称已更改)
根据 Android编程:大书呆子牧场指南中的一些建议,我有以下结构:
MyListFragment extends ListFragment
MyListActivity extends SimpleFragmentActivity
SimpleFragmentActivity extends ActionBarActivity
MyListActivity.java
public class MyListActivity extends SingleFragmentActivity {
@Override
protected Fragment createFragment() {
return new MyListFragment();
}
}
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();
}
}
}
在概述和编写了我的应用程序的基本功能(包括上下文操作栏,导航......)之后,我想确保应用程序尽可能向后兼容,而无需太多额外的工作。因此,我开始使用AppCompat(com.android.support:appcompat-v7:20+)ActionBar。
一开始让我困惑的是 - 与我读过的每个教程或Android的开发人员指南相反 - 在Android Studio中我从未使用过getSupportActionBar方法(我使用的是Android Studio v0.8.2和JRE 1.7_60)。每当我输入getActivity().getSup
时,我得到的唯一建议是getSupportFragmentManager
和getSupportLoaderManager
。
作为一种解决方法,我在ActionBar mActionBar
中创建了一个成员变量MyListFragment
并初始化它:
@Override
public void onAttach (Activity activity) {
super.onAttach(activity);
mActionBar = ((ActionBarActivity) activity).getSupportActionBar();
}
这似乎可以解决Android 4.4.4(Moto G)和2.3.4(LG E-510) - 我唯一可用的设备。
然而 - 我遇到问题 - 旋转时ActionBar赋值丢失,应用程序崩溃并出现NullPointerException。调试应用程序并在onCreate
中的以下行设置断点:
mActionBar.setTitle(R.string.title_activity_my_list);
我发现旋转后mActionBar为空。将所述行放在onCreateView
中没有帮助。
我尝试了什么
mActionBar
初始化为
onAttach
onActivityCreated
onCreate
/ onCreateView
我在这里缺乏想法并感谢您的建议。
EDIT-0(30.07。)
抛出异常(根据Alex’ suggestion编辑后)
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)
MyListFragment
第54行(使用SingleFragmentActivity 和 ActionBarActivity作为强制转换时发生异常)
((SingleFragmentActivity) getActivity()).getSupportActionBar().setTitle(R.string
.title_activity_my_list);
SingleFragmentActivity
第20-22行:
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
答案 0 :(得分:33)
将getActivity()
投放到ActionBarActivity
/ AppCompatActivity
(取决于您使用的是什么),您将可以访问支持ActionBar
。
((AppCompatActivity)getActivity()).getSupportActionBar();
或
((ActionBarActivity)getActivity()).getSupportActionBar();
在onActivityCreated(...)
方法中使用此代码,而不是onAttach(...)
答案 1 :(得分:7)
现在它应该是:
((AppCompatActivity)getActivity()).setSupportActionBar();
因为不推荐使用ActionBarActivity。
但这只是你必须在活动之外做这件事,这是最常见的活动。
答案 2 :(得分:1)
尽管这个答案很晚才给出,但它可以帮到某个人。我们可以直接调用如下代码
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("String");
它也可以正常工作。
答案 3 :(得分:-1)
有时它可以为空值。因此,只需添加如下示例即可。
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()).hide();