I'm extending AppCompatActivity and setting ActionBar using setSupportActionBar().
There's a bit of confusion in setting the title.
If I do -
Toolbar toolbar = (Toolbar) findViewById(R.id.titlebar);
setSupportActionBar(toolbar);
toolbar.setTitle("Title 1"); // Does not work
setTitle("Title 2"); // Works
getSupportActionBar().setTitle("Title 3"); // Works
setTitle("Title 4"); // Does not work. Why?
What I see is that getSupportActionBar().setTitle() is creating a new view for the title and then the activity is losing the reference to it.
Is this the intended behavior or a bug in Android?
If you call setSupportActionBar(Toolbar), then the Action Bar is then responsible for handling the title, therefore you need to call getSupportActionBar().setTitle("My Title"); to set a custom title.
Also check this link where toolbar.setTitle("My title"); may cause problem like below:- In android app Toolbar.setTitle method has no effect – application name is shown as title
And toolbar is the general form of action bar.
We can have multiple toolbars as layout widget but action is not.
Thus better approach is to use getSupportActionBar().setTitle("My Title");
copy this line
setSupportActionBar(toolbar);
add the end of your line.
Toolbar toolbar = (Toolbar) findViewById(R.id.titlebar);
setSupportActionBar(toolbar);
toolbar.setTitle("Title 1");
setTitle("Title 2");
getSupportActionBar().setTitle("Title 3");
setTitle("Title 4");
setSupportActionBar(toolbar);
It's an intended behaviour once your set setSupportActionBar(Toolbar). support library internal creates new view for display title.
setTitle() is method of Activity it'll update only title if used setActionBar(Toolbar). But, it doesn't have backward compatability.
Ref
AppCompatDelegateImplBase
AppCompatDelegateImplV9
Related
I set up a toolbar in my main activity and when I go inside a fragment, I want to add a slider on it. If I had had the access to the Toolbar object, I would simply do:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Spinner mNavigationSpinner = new SpinnerTrigger(getSupportActionBar().getThemedContext());
toolbar.addView(mNavigationSpinner);
But if I get it using
((ActionBarActivity) getActivity()).getSupportActionBar()
I don't have any addView() method. So my question is, how can I add a view to the Toolbar in fragment if the Toolbar itself was created in an Activity.
I'm not sure if this is the best view of going about this, but I don't think I can have the Spinner in defined in the layout, because most of my fragments don't use it, they simply set a title to the toolbar. But at the same time, it would be great if I could define the toolbar once in the main activity and not redo it for every fragment.
Another way of achieving the same thing from Ellitz answer, inside the fragment access the toolbar (or any other view inside activity) directly:
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
you can get it using
Toolbar refTool = ((NameOfClass)getActivity()).toolbar;
or, create an instance of your MainActivity, then, override onAttach(Activity activity) and assign your instance object of MainActivity to the activity in onAttach()
See toolbar main purpose is https://developer.android.com/reference/android/widget/Toolbar.html read here so there are nothing deference in toolbar and actionbar. so if you want to add view to toolbar before it set to Actionbar then toolbar.addView(your view); is fine but after apply apply to setactionbar(toolbar) or setSupportActionbar(toolbar) you can set view to actionbar.
ex. ((ActionBarActivity) getActivity()).getSupportActionBar().setView(Your view)
Thats it...
I would like to add a casting to what Budius said.
Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
is the right way of doing it. Because
getActivity().findViewById(R.id.toolbar);
returns a view. This will give you error and you should cast it to Toolbar.
I am using Android Studio 1.0.1. I created a new Navigation Drawer Activity that is by default provided by this IDE. It created 2 Java files -
HomePage.javathat extends android.support.v7.app.AndroidBarActivity
NavigationDrawerFragment that extends Fragment
Along with that it provided me with 3 layout files -
activity_home_page.xml
fragment_home_page.xml
fragment_navigation_drawer.xml
Now what I wanted to do was hide the Action Bar and instead get the Toolbar as I wanted to do some detailed designing. For that I took the following steps -
Created a new style in styles.xml
true
false
Changed the theme of the application in AndroidManifest.xml
android:theme="#style/AppTheme"
Created a toolbar layout and included it in activity_home_page.xml
Added a Toolbar object to HomePage.java
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);
But unfortunately, my app force closes whenever I launch HomePage activity. Any suggestions?
Logcat
activity_home_page.xml
HomePage.java
NavigationDrawerFragment.java
custom_toolbar.xml
The problem:
In your fragment you have:
toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
...
toolbar.getContext()
However when you call findViewById the activity has not yet called setContentView. That means toolbar was not yet inflated and toolbar is set to null. Therefore toolbar.getContext() throws an NPE.
Fix:
Instead of toolbar.getContext() simply call getActivity(), to get the context.
If your fragment really does need the toolbar, you should call it after your activity's onCreate. A good place for that is onActivityCreated:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
}
Now all methods related to navigation modes in the ActionBar class, such as setNavigationMode()... are now deprecated.
The documentation explains:
Action bar navigation modes are deprecated and not supported by inline toolbar action bars. Consider using other common navigation patterns instead.
In my current application, there is a spinner on ActionBar. How do I apply NAVIGATION_MODE_LIST on the new widget Toolbar in the new version appcompat v7 21.
Thanks in advance.
With the API 21 the method setNavigationMode(ActionBar.NAVIGATION_MODE_LIST) is deprecated.
The best way to work with a spinner is to use a Toolbar like this:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_actionbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:background="?attr/colorPrimary">
<Spinner
android:id="#+id/spinner_toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
You can find an example in the Google IO 2014
As usual Gabriele is right, so your code will look like that:
So It will look like something like that:
private ActionBar actionBar;
private Toolbar toolbar;
private Spinner spinner;
private List<String> mNavigationItems;
private ArrayAdapter<CharSequence> mArrayAdapter;
/***
* Boolean to know which version is running
*/
private boolean postICS,postLollipop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_list);//find the toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
postLollipop =getResources().getBoolean(R.bool.postLollipop);
if(postLollipop){
toolbar.setElevation(15);
}
//define the toolbar as the ActionBar
setSupportActionBar(toolbar);
actionBar=getSupportActionBar();
//now manage the spinner
mNavigationItems=new ArrayList<String>();
mNavigationItems.add("navigation 1");
mNavigationItems.add("nav 2");
mNavigationItems.add("navigation 3");
spinner= (Spinner) findViewById(R.id.action_bar_spinner);
mArrayAdapter = new ArrayAdapter(this, R.layout.actionbar_spinner_dropdown_item, mNavigationItems);
mArrayAdapter.setDropDownViewResource(R.layout.actionbar_spinner_dropdown_item);
spinner.setAdapter(mArrayAdapter);
}
And take care not to use spinnerAdapter (because you won't be able to manage its style using the AppTheme).
And if you want to use Tab (NavigationMode.Tabs) you should use now the Design library (explained here:http://android-developers.blogspot.fr/2015/05/android-design-support-library.html?m=1)and copy paste below
"
Tabs Switching between different views in your app via tabs is not a
new concept to material design and they are equally at home as a top
level navigation pattern or for organizing different groupings of
content within your app (say, different genres of music).
The Design library’s TabLayout implements both fixed tabs, where the
view’s width is divided equally between all of the tabs, as well as
scrollable tabs, where the tabs are not a uniform size and can scroll
horizontally. Tabs can be added programmatically:
TabLayout tabLayout = ...;
tabLayout.addTab(tabLayout.newTab().setText("Tab 1")); However, if you
are using a ViewPager for horizontal paging between tabs, you can
create tabs directly from your PagerAdapter’s getPageTitle() and then
connect the two together using setupWithViewPager(). This ensures that
tab selection events update the ViewPager and page changes update the
selected tab.
"
I have a login screen with two options in my app - "login" and "create account". I want to implement the following thing, for example, on login screen :
I've got one activity and another, by tapping on "UP" button i want to return back. I have the following constructor of desired activity:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bl__login_form_view_controller);
getActionBar().setDisplayHomeAsUpEnabled(true);
//----------------------added source - no effect-----------------------
getActionBar().setDisplayShowHomeEnabled(true);
getActionBar().setIcon(R.drawable.circle) ;
getActionBar().setTitle("A title");
//---------------------------------------------------------------------
setTitle ("Вход") ;
}
And i have UP button. How can i add circle image and some text? All tutorials say, that i can set app icon in AppManifest, but it would change app icon on main screen. And how can i add text to back button? I don't wanna implement any navigation logic or set parent activity for whole app, because it's a login screen, and the main menu with the navigation logic will be shown only after authorization. Thanks in advance!
setTitle will set the title and setIcon will set the icon to the ActionBar.
getActionBar().setTitle("Your Title");
getActionBar().setDisplayShowHomeEnabled(true);
getActionBar().setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setIcon(R.drawable.youricon);
Reference :Adding Up Action and http://developer.android.com/guide/topics/ui/actionbar.html
What about:
getActionBar().setIcon(R.drawable.circle);
use getActionBar().setIcon(R.drawable.youricon) for setting the icon and getActionBar().setTitle("A title"); for setting the text next to the icon.
For the icon:
getActionBar().setIcon(R.drawable.youricon);
For the title:
getActionBar().setTitle("A title");
you can use custom action bar using your own layout
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
final ViewGroup actionBarLayout = (ViewGroup)getLayoutInflater().inflate(R.layout.yourXML, null);
actionBarLayout.findViewById(R.id.buttonId).setOnClickListener(this);
actionBar.setCustomView(actionBarLayout);
its work for me. so i hope its work for you.
The accepted answer serves the problem well. I'm just adding some additional information of using a custom action bar layout.
getActionBar().setTitle("Your Title");
getActionBar().setDisplayShowHomeEnabled(true);
getActionBar().setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setIcon(R.drawable.youricon);
// You can use setLogo instead like
// getActionBar().setIcon(R.drawable.youricon);
// In case of support action bar, if its not showing properly, you need to add display options
//getActionBar().setDisplayOptions(actionBar.getDisplayOptions() | ActionBar.DISPLAY_SHOW_CUSTOM);
Now here's a code segment describing how to use a custom layout in android actionbar.
// Make a layout named 'custom_actionbar' and simply add elements you want to show in your actionbar.
final ViewGroup actionBarLayout = (ViewGroup) getLayoutInflater()
.inflate(R.layout.custom_actionbar, null);
// Now for support action bar, get the action bar
actionBar = getSupportActionBar();
// Set necessary attributes
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setElevation(0);
// Set the custom layout in actionbar here
actionBar.setCustomView(actionBarLayout);
actionBar.setDisplayOptions(actionBar.getDisplayOptions()
| ActionBar.DISPLAY_SHOW_CUSTOM);
// Now handle the elements of the custom layout here
Button b1 = (Button) findViewById(R.id.button1);
// Set actions for Button 1 here
b1.setText("Button 1");
// Another element in custom actionbar
ImageView iv1 = (ImageView) findViewById(R.id.myImage);
iv1.setBackgroundResource(R.drawable.myImagePlaceHolder);
Place the codes in onCrate and check yourself.
I apply a custom View to the ActionBar, like this
// Inflate the "Done/Discard" custom ActionBar view.
LayoutInflater inflater = (LayoutInflater) DetailsHost.mActionBar
.getThemedContext().getSystemService(DetailsHost.LAYOUT_INFLATER_SERVICE);
final View customActionBarView = inflater.inflate(
R.layout.actionbar_custom_view_done_discard, null);
// Show the custom ActionBar view and hide the normal Home icon and title.
DetailsHost.mActionBar.setDisplayOptions(
ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE);
DetailsHost.mActionBar.setCustomView(customActionBarView,
new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
(based on Roman Nuriks code).
How do I restore the initial layout? Note: I use ActionBarSherlock
Show/hide custom actionbar view
Since you only added a custom view to the bar without removing the title it should be sufficient to hide that custom View. You can use method setDisplayShowCustomEnabled(). Just call:
getActivity().getActionBar().setDisplayShowCustomEnabled(false);
And enable home functionality again:
getActivity().getActionBar().setDisplayShowHomeEnabled(true);
(Note in all code examples use getSupportActionBar() instead of getActionBar() if you're using actionbar compat. Also the getActivity() is only needed from fragments, in activities refer to the activity itself, in most cases this)
Restore actionbar title
If however you also removed the title when creating your custom view you'll have to enable that again also.
getActivity().getActionBar().setDisplayShowTitleEnabled(true);
Restore completely
You can also call the setDisplayOptions() method with a combination of options to reconfigure the actionbar in one call. The below example removes the custom view and shows the title.
getActivity().getActionBar().setDisplayOptions(
ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
See Android API docs for more details on these options.
ActionBar actionbar;
actionbar = getActionBar();
Button cls = (Button)findViewById(R.id.btn_close);
cls.setOnClickListener(new OnClickListener(){
public void onClick(View view){
actionbar.setDisplayShowCustomEnabled(false);
}
});
Note:
The button with id 'btn_close' was located in the custom actionbar layout.This function was written in mainactivity.
Hope this Helps!!