I\'m starting a new project that uses the AppCompat/ActionBarCompat
in v7
support library. I\'m trying to figure out how to use the getSuppor
After Fragment.onActivityCreated(...) you'll have a valid activity accessible through getActivity().
You'll need to cast it to an ActionBarActivity then make the call to getSupportActionBar().
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
You do need the cast. It's not poor design, it's backwards compatibility.
If someone uses com.android.support:appcompat-v7: and AppCompatActivity as activity then this will work
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
in your fragment.xml
add Toolbar
Tag from support library
<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" />
Now how we can control it from MyFragment
class? let's see
inside onCreateView
function add the following
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);
and if you want to add items
to the toolbar within MyFragment
you must
add this line inside onCreateView
function
setHasOptionsMenu(true);
this line is important, if you forget it, android will not populate your menu Items.
assume we identify them in menu/fragment_menu.xml
after that override the following functions
@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;
}
hope this helps
For those using kotlin,
(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
As an updated answer for Pierre-Antoine LaFayette's answer
ActionBarActivity is deprecated; use AppCompatActivity
instead
((AppCompatActivity)getActivity()).getSupportActionBar();
While this question has an accepted answer already, I must point out that it isn't totally correct: calling getSupportActionBar()
from Fragment.onAttach()
will cause a NullPointerException
when the activity is rotated.
Short answer:
Use ((ActionBarActivity)getActivity()).getSupportActionBar()
in onActivityCreated()
(or any point afterwards in its lifecycle) instead of onAttach()
.
Long answer:
The reason is that if an ActionBarActivity
is recreated after a rotation, it will restore all Fragments before actually creating the ActionBar
object.
Source code for ActionBarActivity
in the support-v7
library:
@Override
protected void onCreate(Bundle savedInstanceState) {
mImpl = ActionBarActivityDelegate.createDelegate(this);
super.onCreate(savedInstanceState);
mImpl.onCreate(savedInstanceState);
}
ActionBarActivityDelegate.createDelegate()
creates the mImpl
object depending on the Android version.super.onCreate()
is FragmentActivity.onCreate()
, which restores any previous fragments after a rotation (FragmentManagerImpl.dispatchCreate()
, &c).mImpl.onCreate(savedInstanceState)
is ActionBarActivityDelegate.onCreate()
, which reads the mHasActionBar
variable from the window style.mHasActionBar
is true, getSupportActionBar()
will always return null
.Source for 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;
}