我正在开始一个使用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
//...
}
使用它的Google页面(http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html)表示v4
片段不应有任何更改。我是否需要将getActivity()
所有来电投放到ActionBarActivity
?这看起来很糟糕。
答案 0 :(得分:263)
在 Fragment.onActivityCreated(...)之后,您将通过getActivity()访问有效活动。
您需要将其强制转换为ActionBarActivity,然后调用getSupportActionBar()。
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
你需要演员。它的设计并不差,它具有向后兼容性。
答案 1 :(得分:35)
虽然这个问题已经得到了接受,但我必须指出这并不完全正确:从getSupportActionBar()
调用Fragment.onAttach()
会在活动轮换时产生NullPointerException
。
简答:
在 ((ActionBarActivity)getActivity()).getSupportActionBar()
(或其生命周期中的任何后续点)中使用onActivityCreated()
代替onAttach()
。
答案很长:
原因是如果在轮换后重新创建ActionBarActivity
,它将在实际创建ActionBar
对象之前恢复所有碎片。
ActionBarActivity
库中support-v7
的源代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
mImpl = ActionBarActivityDelegate.createDelegate(this);
super.onCreate(savedInstanceState);
mImpl.onCreate(savedInstanceState);
}
ActionBarActivityDelegate.createDelegate()
根据Android版本创建mImpl
对象。super.onCreate()
为FragmentActivity.onCreate()
,可在轮换后恢复之前的所有片段(FragmentManagerImpl.dispatchCreate()
,& c)。mImpl.onCreate(savedInstanceState)
是ActionBarActivityDelegate.onCreate()
,它从窗口样式中读取mHasActionBar
变量。mHasActionBar
成立之前,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;
}
答案 2 :(得分:29)
如果有人使用com.android.support:appcompat-v7:和AppCompatActivity作为活动,那么这将有效
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
答案 3 :(得分:5)
来自支持库的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
之后覆盖以下功能
@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;
}
希望这会有所帮助
答案 4 :(得分:3)
作为Pierre-Antoine LaFayette回答的最新答案
不推荐使用ActionBarActivity;使用AppCompatActivity
代替
((AppCompatActivity)getActivity()).getSupportActionBar();
答案 5 :(得分:0)
对于那些使用kotlin的人,
(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
答案 6 :(得分:0)
作为 GzDev 答案的附录,如果您已经有了字符串,则可以使用 kotlin 的自动设置器:
(activity as AppCompatActivity).supportActionBar?.subtitle = my_string
您只需使用一个空字符串即可将其关闭。
请注意,这适用于 title 和 subtitle。