Reputation: 4422
I have an Activity which has a
android.support.v4.widget.DrawerLayout
, which in turn has a FrameLayout
and A Side Menu Fragment
.
The side menu has 3 options.
Each option will dynamically add a new fragment to the FrameLayout
and any action done on the Fragment will keep adding few more fragment.
Eg: If I select option-1 it is a 5 step process. Lets say a Quiz. You submit 1st answer, 2nd fragment with a new question comes up(while the previous question being in the back stack) and so on. Finally ending at question 5. Option-2 has a similar kind of process with 3 stages and so does Option-3.
My requirement is to Put the Actionbar title as "Option-1" whenever there is a fragment of that sequence visible to the user.
What I tried:
I made a super fragment which every other fragment extends and this super fragment has a fields title, which I set when I am adding it to the FrameLayout. And onBackStackChanged I would get the top most fragment using the entry count and get the title from it and set as the Action bar title.
fragmentManager.addOnBackStackChangedListener(new
FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
int count = fragmentManager.getBackStackEntryCount();
Fragment visibleFragment = fragmentManager.getFragments().get(count > 0 ? count - 1 : count);
Log.d("onBackStackChanged", "" + visibleFragment);
//actionBar.setTitle(visibleFragment.title);
}
});
But the problem here is, when I see the logs, it is not the visible fragment that comes in the visibleFragment
field, it is something random. I mean sometimes even I get SideMenuFragment there which is actually static in the xml
Is there an easy and better way to do this?
Upvotes: 1
Views: 1397
Reputation: 20513
Create an interface as @Jibbo suggested (documentation), that is the right way Fragments and Activities should communicate (what @Hiren Patel said, is not the way, because Fragments aren't reusable with other Activities - he used a public method in the activity).
Your comment: How to handle the back pressed and title you could override the onBackPressed method in your MainActivity and check the fragment TAG, to determine on which Fragment we pressed back, and than set the title according to this.
You set the TAG when starting the Fragment
getSupportFragmentManager()
.beginTransaction()
.add(R.id.content_frame, new QuizFragment(), FRAGMENT_TAG_QUIZ)
.addToBackStack(FRAGMENT_TAG_QUIZ)
.commit();
Detect back pressed
@Override
public void onBackPressed()
{
// Check fragment back stack so we can set the right action bar title
int fragmentCount = fragmentManager.getBackStackEntryCount();
if (fragmentCount != 0)
{
FragmentManager.BackStackEntry backEntry = fragmentManager.getBackStackEntryAt(fragmentCount - 1);
String fragmentTag = backEntry.getName();
if (fragmentTag != null)
{
// If back pressed when on Quiz
switch (fragmentTag) {
case FRAGMENT_TAG_QUIZ:
setActionBarTitle("Quiz");
break;
....
}
}
}
super.onBackPressed();
}
Upvotes: 2
Reputation: 442
I would do it in the following way:
I'll create an interface like:
public interface ChangeTitleListener{
public void setTitle(String title);
}
And I'll make the activity implement it. Then, In the fragments:
private ChangeListener mListener;
@Override
public void OnAttach(Activity activity){
if(activity instanceof ChangeTitleListener){
mListener = (ChangeListener) activity;
}
else{
throw new RuntimeException("The activity must implement ChangeListener");
}
}
Now you can call mListener.setTitle(SOMETHING);
when you need. I'll suggest calling it in the onResume()
method since it's not an expensive action and you need it every time a fragment is displayed.
Upvotes: 1
Reputation: 52810
You can do in this way:
In your Activity:
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
Set Actionbar title from Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Set title bar
((MainFragmentActivity) getActivity())
.setActionBarTitle("Your title");
}
Hope it will help you.
Upvotes: 0