从片段ActionBarCompat中获取getSupportActionBar
我开始一个使用AppCompat/ActionBarCompat
v7
支持库的新项目。 我想弄清楚如何使用片段内的getSupportActionBar
。 我的活动,承载片段扩展ActionBarActivity
,但我没有看到类似的支持类的碎片。
从我的片段中
public class CrimeFragment extends Fragment { //... getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment //... }
谷歌页面使用它( http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html )说,应该没有变化的v4
片段。 我是否需要将所有的getActivity()
调用转换为ActionBarActivity
? 这似乎是糟糕的devise。
在Fragment.onActivityCreated(…)之后,您将拥有可通过getActivity()访问的有效活动。 您需要将其转换为ActionBarActivity,然后调用getSupportActionBar()。
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
你确实需要演员。 这不是糟糕的devise,它是向后兼容的。
虽然这个问题已经有了一个可以接受的答案,但我必须指出,这不是完全正确的:调用Fragment.onAttach()
getSupportActionBar()
Fragment.onAttach()
会导致一个NullPointerException
。
简短的回答:
在onActivityCreated()
(或其生命周期中的任意点((ActionBarActivity)getActivity()).getSupportActionBar()
中使用((ActionBarActivity)getActivity()).getSupportActionBar()
)而不是onAttach()
。
很长的回答:
原因是如果在ActionBarActivity
之后重新创build一个ActionBarActivity
,它将在实际创buildActionBar
对象之前恢复所有的Fragment。
support-v7
库中的ActionBarActivity
源代码:
@Override protected void onCreate(Bundle savedInstanceState) { mImpl = ActionBarActivityDelegate.createDelegate(this); super.onCreate(savedInstanceState); mImpl.onCreate(savedInstanceState); }
-
ActionBarActivityDelegate.createDelegate()
根据Android版本创buildmImpl
对象。 -
super.onCreate()
是FragmentActivity.onCreate()
,它在一个旋转之后恢复任何以前的片段(FragmentManagerImpl.dispatchCreate()
,&c)。 -
mImpl.onCreate(savedInstanceState)
是ActionBarActivityDelegate.onCreate()
,它从窗口样式读取mHasActionBar
variables。 - 在
mHasActionBar
为true之前,getSupportActionBar()
将始终返回null
。
ActionBarActivityDelegate.getSupportActionBar()
源代码:
final ActionBar getSupportActionBar() { // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar // could change after onCreate if (mHasActionBar || mOverlayActionBar) { if (mActionBar == null) { ... creates the action bar ... } } else { // If we're not set to have a Action Bar, null it just in case it's been set mActionBar = null; } return mActionBar; }
如果有人使用com.android.support:appcompat-v7:和AppCompatActivity作为活动,那么这将工作
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
在你的fragment.xml
添加Toolbar
标签从支持库
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
现在我们如何从MyFragment
类中控制它? 让我们来看看
在onCreateView
函数里面添加以下内容
mToolbar = (Toolbar) view.findViewById(R.id.toolbar); ((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar); //add this line if you want to provide Up Navigation but don't forget to to //identify parent activity in manifest file ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
如果你想添加items
到MyFragment
的工具栏,你must
在onCreateView
函数中添加这一行
setHasOptionsMenu(true);
这条线是重要的,如果你忘记它,android不会填充你的菜单项。
假设我们在menu/fragment_menu.xml
标识它们
之后,覆盖以下function
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.fragment_menu, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.action_1: // do stuff return true; case R.id.action_2: // do more stuff return true; } return false; }
希望这可以帮助
作为Pierre-Antoine LaFayette答案的最新答案
ActionBarActivity已弃用; 改用AppCompatActivity
((AppCompatActivity)getActivity()).getSupportActionBar();
- Kotlin和新的ActivityTestRule:@规则必须公开
- POST多部分表单数据使用Retrofit 2.0包括图像
- 使用gradle的aar库不能解决传递依赖问题
- strings.xml中的参数是可能的吗?
- 如何设置edittext显示searchbutton或键盘上的inputbutton?
- setBackgroundResource()放弃我的XML布局属性
- Android:TextView:删除顶部和底部的间距和填充
- 在Android中保存和读取来自内部存储器的位图/图像
- 无法从android.app.FragmentManager转换为android.support.v4.app.FragmentManager