In my activity I've created a method for the fragments to update the title :
public void setTitle(String title) {
ActionBar ab = getSupportActionBar();
if (ab != null) {
if (title == null) {
title = getString(R.string.string_title);
}
ab.setTitle(title);
}
}
The toolbar is part of a CollapsingToolbarLayout.
It looks like the title is set correctly for the first fragment, however, when the second one tries to update it, it doesn't get updated.
I'm running with v 23 so this is not the known bug.
Related
I have a generic
MyActivity extends AppCompatActivity
I don't override the toolbar with a custom xml defined toolbar, just use the generated one Android provides.
I can set the title via your normal
getSupportActionBar().setTitle("foo");
but setting the subtitle via
getSupportActionBar().setSubtitle("bar");
doesn't set it. It remains blank. I'm doing this onCreate()
(I feel I've done this many times before with no fail)
Although I've noticed if I visit another activity, then return, the subtitle would then show... not on orientation change, not on recreate() but only when I'm returning from an activity.
I'm experiencing this on 5.0 and 7.0
For the time being I'll likely define my own Toolbar and move forward since that seems where most people have solutions for this same problem.
Relevant code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_replenishment_list);
ButterKnife.bind(this);
MyApplication.getInstance().getComponent().inject(this);
setupUI();
}
private void setupUI() {
setupActionBar();
}
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//TODO: not working unless activity is recreated...
// explore custom xml defined toolbar
//actionBar.setTitle("different title than what is defined in manifest"); <-- this does work, but not this
actionBar.setSubtitle(UserUtil.getFormattedFirstNameLastName(userService.getUserFromJWT(), this));
}
}
I have put the below code in my onCreate() method.
ActionBar actionBar = getActionBar();
if (actionBar==null) {
System.out.println("TEST NULL");
} else {
System.out.println("TEST NOT NULL");
}
The result is null. When I add the toolbar first it works fine.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getActionBar();
actionBar.setSubtitle("TESTING");
Your getSupportActionBar or getActionBar will return null if you didn't set toolbar to it. You need to set the toolbar to your action bar before using getSupportActionBar or getActionBar.
I'm using android.support.v7.widget.Toolbar and AppCompatActivity. I've enabled back up button like this supportActionBar.setDisplayHomeAsUpEnabled(true);.
The fragment in side the activity will set the title and subtitle in onResume() like this
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setTitle(title);
activity.getSupportActionBar().setSubtitle("Bingo");
The problem is, when the fragment shows up onResume is called but subtitle is not shown. When I press power OFF and ON, means fragment goes to pause and resumes again. Now, subtitle is visible. I've tested on other android phone as well.
Can you please help me finding out the problem?
This is because the toolbar is not rendered when you are setting the subtitle.
Try this code,Set title and subtitle inside this method
private void setupToolbar(){
toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
if(toolbar != null){
setSupportActionBar(toolbar);
}
toolbar.post(new Runnable()
{
#Override
public void run()
{
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(mTitle);
getSupportActionBar().setSubtitle("Subtitle);
}
});
}
Some where in code I add
ActionBar ab = ((AuthActivity) getActivity()).getSupportActionBar();
if (ab != null) {
ab.hide();
ab.show();
ab.setTitle(R.string.auth_tt_title);
ab.setDisplayHomeAsUpEnabled(true);
}
Later, I add fiew fragments one of which may change title and display home button.Thus, I wat to save state for ActionBar before I made changes, to be able to restore it asfter fragment will be gone.
I can get title as
private String getAbStatus(AppCompatActivity activity) {
String title="";
boolean visible;
ActionBar ab = activity.getSupportActionBar();
if (ab != null) {
if (ab.getTitle() != null) title = ab.getTitle().toString();
}
return title;
}
But how can I get state of HomeAsUp?
Short answer:
if (ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP != 0) {}
Long answer here: How do I get ActionBar attribute in my class
I have an android application that has a single main activity that employs many fragments that switch into view. I'm not sure if that's the right way to do it, but I have inherited this project and would like to avoid doing any major refactors like changing the fragments to all be activities or something like that.
According to the android documentation, it looks like calling the setDisplayHomeAsUp(bool) function should just display the up button by default:
Set whether home should be displayed as an "up" affordance. Set this
to true if selecting "home" returns up by a single level in your UI
rather than back to the top level or front page.
The main issue is that when I use the function:
actionBar.setDisplayHomeAsUpEnabled(true);
It does not set the button that opens the navigation drawer to instead turn into an 'Up' button. It just removes the 'hamburger' ic_drawer icon from the side. The navigation drawer still opens.
Here is the custom code for the NavigationDrawerFragment (I copy+pasted the exact file that you get when you create a new application with a navigation drawer within android studio):
NavigationDrawerFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
mDrawerListView = (ListView) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
PopulateAppDrawerList();
return mDrawerListView;
}
public void PopulateAppDrawerList() {
List<AppOption> allApps = getAllApps();
List<AppOption> filteredApps = new ArrayList<AppOption>();
for (int i = 0; i < allApps.size(); i++) {
if (allApps.get(i).getLaunchable()) {
filteredApps.add(allApps.get(i));
}
}
NavDrawerListAdapter adapter = new NavDrawerListAdapter(filteredApps, MainActivity.getInstance());
mDrawerListView.setAdapter(adapter);
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
}
Then, I have the other fragments that all extend 'BaseAppFragment', which contains the following:
BaseAppFragment.java
public class BaseAppFragment extends Fragment {
#Override
public void onStart() {
super.onStart();
MainActivity.getInstance().onSectionAttached(this);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
} }
This is what allows me to change the title on the action bar in one single area and set whether or not it should have the back button set by default.
MainActivity.java
public void onSectionAttached(android.app.Fragment fragment) {
Class fragmentType = fragment.getClass();
ActionBar actionBar = getActionBar();
mNavigationDrawerFragment.PopulateAppDrawerList();
if (fragmentType != null) {
if (fragmentType.equals(AuthenticationFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(MyOptionsFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "My Options";
} else if (fragmentType.equals(GLAuthenticationFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(InitialLoginFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(LoginFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(DailyOverviewFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(true);
mTitle = "Overview";
} else if (fragmentType.equals(SingleComponentFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(true);
SingleComponentFragment singleComponentFragment = (SingleComponentFragment) fragment;
if (singleComponentFragment != null && singleComponentFragment .mComponent != null) {
mTitle = String.format("Back To Day %s", singleComponentFragment.mComponent.getDay() + "");
}
else {
mTitle = "";
}
} else if (fragmentType.equals(singleDayOverviewFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(true);
mTitle = "Back To Overview";
}
}
actionBar.setTitle(mTitle);
}
The title setting works perfectly and there are no errors when the setDisplayHomeAsUpEnabled(true) is called, but it still shows no Up button. I know that right now I am not setting any type of fragment navigation hierarchy other than the addToBackStack(null) call in the Fragment Transaction, but it still seems like this code should be enough to have the up button replace the navigation drawer button.
The problem is that the navigation drawer icon hijacks the up indicator. In terms of which View in the action bar is displaying the icon, the navigation drawer icon is also the up icon. This is why you need to call actionBar.setDisplayHomeAsUpEnabled(true); for the navigation drawer icon to show.
To fix this, you need to use ActionBarDrawerToggle#setDrawerIndicatorEnabled(false). This will replace the navigation drawer icon with the up icon. From the documentation for this method:
When the indicator is disabled, the ActionBar will revert to displaying the home-as-up indicator provided by the Activity's theme in the android.R.attr.homeAsUpIndicator attribute instead of the animated drawer glyph.
Had the same problem as you, and I struggled getting a consistent Up arrow behaviour. I made this example to show how to properly do it when using a single activity with navigation drawer and multiple levels.
https://github.com/tskulbru/android-navdrawer-up-pattern-example
I have an fragment which set's the title to the entity the user is currently editing as follows:
Activity activity = this.getActivity();
CollapsingToolbarLayout appBarLayout = (CollapsingToolbarLayout) activity.findViewById(R.id.toolbar_layout);
if (appBarLayout != null) {
appBarLayout.setTitle(mItem.name);
}
In the testing code I successfully navigate to the fragment, however I'm unable to locate the element by the text as follows:
class DetailWrapper {
protected UiObject2 find( BySelector selector ){
device.wait(Until.findObject(selector), 2 * 1000);
return device.findObject(selector);
}
public ItemView hasName(String itemName) throws Exception {
UiObject2 title = find(By.text(itemName));
assertEquals(title.getText(), itemName);
return this;
}
}
title in hasName(String) is always null in the assert despite being on the correct activity with the correct title. What is the best method to assert the AppBar's title?