I'm trying the new Toolbar component and having some trouble with the navigation icon.
I want to implement a custom icon for back navigation :
In my manifest i set a parent to my activity :
<activity android:name=".CardsActivity" android:parentActivityName=".MainActivity">
<!-- Parent activity meta-data to support API level 7+ -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
I declare the toolbar like this :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.lollitest.MainActivity" >
<android.support.v7.widget.Toolbar
android:id="#+id/my_awesome_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:layout_marginBottom="10dp"
android:background="?attr/colorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/my_awesome_toolbar"
android:text="#string/hello_world" />
</RelativeLayout>
Then in my activity i configure the Toolbar like this :
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
toolbar.setNavigationIcon(R.drawable.ic_good);
toolbar.setTitle("Title");
toolbar.setSubtitle("Sub");
toolbar.setLogo(R.drawable.ic_launcher);
setSupportActionBar(toolbar);
Which giving me :
The back icon is not the one i set with setNavigationIcon() ! Whatever drawable i give to the method the navigation icon is always the back arrow.
I have tried to remove the parent association in the manifest but the only effect is (obviously) to prevent the button to go back.
On contrary if i want the default back arrow icon and don't call setNavigationIcon() i don't have any icon at all.
What is the correct way to handle the navigation icon in toolbar (custom and default) ?
NOte : i'm running my test on Android 4.4
Currently you can use it, changing the order: (it seems to be a bug)
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_good);
toolbar.setTitle("Title");
toolbar.setSubtitle("Sub");
toolbar.setLogo(R.drawable.ic_launcher);
Specific to the navigation icon, this is the correct order
// get the actionbar as Toolbar and set it up
Toolbar toolbar = (Toolbar) findViewById(R.id.signIn_toolbar);
setSupportActionBar(toolbar);
Inform the Toolbar to provide back navigation. This will set the icon to the default material icon
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Later override the icon with the custom one, in my case the Holo back icon
toolbar.setNavigationIcon(R.drawable.ic_chevron_left_white_36dp);
(The answer to user802421)
private void setToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_action_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
toolbar.xml
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_height"
android:background="?attr/colorPrimaryDark" />
Use setNavigationIcon to change it. don't forget create ActionBarDrawerToggle first!
sample code work for me:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout)findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
toolbar.setNavigationIcon(R.drawable.ic_menu);
I had simillar problem. After a big headache I found, that my ActionBarDrawerToggle was modifying the icon, also when it should not modify the icon (because I didn't give reference to toolbar to the toggle component). So in my NavigationDrawerFragment class (that handles the opening and closing) in setUp(...) method I set mDrawerToggle.setHomeAsUpIndicator(R.drawable.app_icon);
and finally it worked.
I tried to set up toolbar like #Gabriele Mariotti, but I had some problem with title. So then I set order to
toolbar.setTitle("Title")
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_good);
and it works.
I just found the solution. It is really very simple:
mDrawerToggle.setDrawerIndicatorEnabled(false);
Hope it will help you.
I used the method below which really is a conundrum of all the ones above. I also found that onOptionsItemSelected is never activated.
mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setHomeButtonEnabled(true);
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
if (toolbar != null) {
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
You can use invalidate() method to change toolbar state in any place.
Example:
Toolbar toolbar = (Toolbar)findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.mipmap.arrow_white);
toolbar.invalidate(); // restore toolbar
Remove this line from activity if you have added
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
Then set icon
getSupportActionBar().setHomeAsUpIndicator(icon);
work for me...
<android.support.v7.widget.Toolbar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/toolBar"
android:background="#color/colorGreen"
app:title="Title"
app:titleTextColor="#color/colorBlack"
app:navigationIcon="#drawable/ic_action_back"/>
In case you don't wish to set the toolbar as the action bar, you can use this:
val toggle = ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
toggle.isDrawerSlideAnimationEnabled = false
toggle.isDrawerIndicatorEnabled = false
toggle.setHomeAsUpIndicator(AppCompatResources.getDrawable(this, ...))
drawer!!.addDrawerListener(toggle)
toggle.setToolbarNavigationClickListener {
setDrawerOpened(!isDrawerOpened())
}
toggle.syncState()
fun setDrawerOpened(open: Boolean) {
if (open == drawerLayout.isDrawerOpen(GravityCompat.START))
return
if (open)
drawerLayout.openDrawer(GravityCompat.START)
else drawerLayout.closeDrawer(GravityCompat.START)
}
Try this:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:toolbar="http://schemas.android.com/apk/res-auto"
android:id="#+id/tool_drawer"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
toolbar:navigationIcon="#drawable/ic_navigation">
</android.support.v7.widget.Toolbar>
Related
I made a NavigationView and included getSupportActionBar().setDisplayHomeAsUpEnabled(true);in my code to show the hamburger button, and it worked. but then i removed the default toolbar (by setting AppTheme in styles values to parent="Theme.AppCompat.Light.NoActionBar"), and implemented my own toolbar in the layout. And now instead of the Hamburger button, it shows the back button, although clicking on it draws the NavigationView. What should i do?
My Java code:
private DrawerLayout sideBar;
private ActionBarDrawerToggle sideBarToggle;
private Toolbar actionToolbar;
#Override
public void onCreate(...) {
sideBar = (DrawerLayout) findViewById(R.id.sqliteLayout);
sideBarToggle = new ActionBarDrawerToggle(this, sideBar, actionToolbar, R.string.sideBarOpen, R.string.sideBarClose);
actionToolbar = (Toolbar) findViewById(R.id.navAction);
sideBar.addDrawerListener(sideBarToggle);
sideBarToggle.syncState();
setSupportActionBar(actionToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(sideBarToggle.onOptionsItemSelected(item)){
return true;}
return super.onOptionsItemSelected(item);
}
My Toolbar code:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/navAction"
android:background="#color/colorPrimary"
app:theme="#style/Base.Theme.AppCompat.Light.DarkActionBar">
</android.support.v7.widget.Toolbar>
SOLUTION:
I reordered the java code to this, and removed the 3rd argument in new ActionBarDrawerToggle(...) and it worked!
actionToolbar = (Toolbar) findViewById(R.id.navAction);
setSupportActionBar(actionToolbar);
sideBar = (DrawerLayout) findViewById(R.id.sqliteLayout);
sideBarToggle = new ActionBarDrawerToggle(this, sideBar, R.string.sideBarOpen, R.string.sideBarClose);
sideBar.addDrawerListener(sideBarToggle);
sideBarToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Call setSupportActionBar(actionToolbar); before you set up your ActionBarDrawerToggle.
ActionBarDrawerToggle uses getSupportActionBar() under the hood, so all the work it is doing is wiped out when you call setSupportActionBar afterwards.
Make sure you have added:
actionBar.setDisplayHomeAsUpEnabled(true);
Not this one:
getSupportActionBar().setHomeAsUpIndicator(true);
I have an app that displays the default activity as:
When clicked the hamburger icon opens left main navigation drawer as:
And when clicked the FILTER button opens another drawer from the right as:
I know how the left navigation drawer is displayed (all java codes and layouts)
What is the code for displaying the drawer that is opening from the right ?
and also i wanna know, how the on click listener is set up even if the FILTER button is outside the toolbar ?
Can anyone help?
Just change the value of tools:openDrawer to end (i.e tools:openDrawer="end"), also add android:layout_gravity="end" in <android.support.design.widget.NavigationView>. Here's the solution.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="end">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
//Add this piece of code
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(drawer.isDrawerOpen(Gravity.RIGHT)){
drawer.closeDrawer(Gravity.RIGHT);
}else{
drawer.openDrawer(Gravity.RIGHT);
}
}
});
}
Check out this -http://updateunlimited.blogspot.in/2015/12/double-sided-nav-drawers.html
it will take less time
also check how it open from right -https://stackoverflow.com/a/19358114/4741746 and https://stackoverflow.com/a/32155976/4741746 and https://stackoverflow.com/a/17156831/4741746
Best of luck
i finished my project .but it only runs on lollipop and marshmallow.it does not runs in kitkat and older versions due to action bar and toolbar prblm.if adjust the theme ,some times it shows me two action bars on top.i m new to android.anybody help me to finish tis completely.its my first project given to me.thank you ...i m running out of time...i m posting my one sample activity...
`<activity android:name=".anims.AnimHome"
android:theme="#style/AppTheme.NoActionBar" />'
my toolbar theme is
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?android:attr/actionBarSize"
app:popupTheme="#style/AppTheme"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
'public class AnimHome extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private ProgressDialog loadDialog;
private JSONArray _myResponse;
public ActionBar ab;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.anim_home);
inilizeProgressDialog();
drawerLayout();
}
private void drawerLayout() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
try {
setSupportActionBar(toolbar);
} catch (Exception e) {
e.printStackTrace();
}
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
if (drawer != null) {
drawer.addDrawerListener(toggle);
}
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null) {
navigationView.setNavigationItemSelectedListener(this);
}
}
}'
I would rewrite the app using API level 8. Level 8 goes on 95% of android devices. Also you can check your manifest and try to set your "miniSdk to 8" "targetSdk to 18" and "maxSdk to 24".
You want to search your manifest for something that looks like this
<uses-sdk android:minSdkVersion="integer"
android:targetSdkVersion="integer"
android:maxSdkVersion="integer" />
I am using the DrawerLayout with the v7 Toolbar, and I want to show the hamburger icon in the main activity, and the back icon in the children activities.
I am not able to do that, the hamburger icon is always shown, also in the children activities.
I already searched on so without success (if I lost some usefull questions I apologize).
This is the Android manifest:
<activity android:name=".activities.MainActivity"></activity>
<activity
android:name=".activities.BuyActivity"
android:windowSoftInputMode="adjustResize"
android:parentActivityName=".activities.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
This is the activity code (the BaseActivity is the superclass for the parent and children activities):
public class BaseActivity extends AppCompatActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buy);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
}
This is the part of the layout of the toolbar:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:background="?attr/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/txtTitle"
android:textColor="#android:color/white"
android:text="#string/title_buy"
android:textAppearance="#android:style/TextAppearance.Large" />
<ImageView
android:layout_width="#dimen/toolbar_image"
android:layout_height="#dimen/toolbar_image"
android:src="#drawable/done"
android:background="#drawable/bg_border_white_l"
android:layout_marginRight="#dimen/toolbar_margin_right"
android:layout_marginEnd="#dimen/toolbar_margin_right"
android:contentDescription="#string/app_name"
android:layout_gravity="end"
android:id="#+id/imgDone" />
</android.support.v7.widget.Toolbar>
I tried:
checked to import the correct android.support.v7.app.ActionBarDrawerToggle
I don't know what I am doing wrong.
In child activities you should not add ActionBarDrawerToggle, as this is what sets a hamburger icon. Move the ActionBarDrawerToggle to the main activity instead.
Please, explain to me... I have Navigation Drawer in my Activity and it syncs with Toolbar (like ActionBar). Activity has few fragments and in different fragments I need to use different AppBar modes (parallax in one, simple in another). So, I think that I should set CoordinatorLayout in each frament with AppBar and content.
But how I can replace last toolbar on new to save synchronization with Drawer? Or it's wrong way and I need make it some else?
Not sure if my approach is good, but I tried to add this public method to my activity:
public void setToolbar(Toolbar toolbar) {
if(toolbar != null) {
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
} else {
drawer.setDrawerListener(null);
}
}
and I added this in all fragments:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((MainActivity)getActivity()).setToolbar(toolbar);
}
#Override
public void onDestroyView() {
((MainActivity)getActivity()).setToolbar(null);
super.onDestroyView();
}
It's working fine, but I'm not sure if it may cause a memory leak or any other performance issue. Maybe someone can help with it?
You can access main DrawerLayout from each Fragment just like the following code:
AppCompatActivity actionBar = (AppCompatActivity) getActivity();
actionBar.setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) actionBar.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
getActivity(), drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
If you want to use appbar(toolbar) that you specified in navigation drawer in different fragments with, for example different options menu items, you could make a public method in Main Activity where you specified your navigation drawer logic.
public void setToolbar(Toolbar toolbar, String title){
AppCompatActivity actionBar = this;
actionBar.setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout)actionBar.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toogle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
drawer.addDrawerListener(toogle);
toogle.setDrawerIndicatorEnabled(true);
toogle.syncState();
if(toolbar != null)
toolbar.setTitle(title);
}
Now you can use this method in your fragments to access the main toolbar and override it with your custom title, options menu...
You can do this by creating a new toolbar variable in your fragment and then inflate it in onCreateView() method like this
toolbarFragment = (Toolbar)getActivity().findViewById(R.id.toolbar);
R.id.toolbar is the id of a toolbar that you specified in your layout file and it is the same id that you used in your main activity for the main toolbar.
Now you can call the method setToolbar(Toolbar toolbar, String title) in fragment like this
((MainActivity)getActivity()).setToolbar(toolbarFragment, "Some title");
If you want to use options menu for this fragment you have to call
setHasOptionsMenu(true);
in fragments onCreate() or onCreateView() methods. After that you can override method onCreateOptionsMenu() like this
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.custom_menu1, menu);
}
You can repeat this procedure for other fragments in your navigation drawer as well. Although it worked for me, I don't know if this violates activities or fragments lifecycle or causes memory leeks.
I have the same problem. I wanted to add CollapsingToolbar only in the main fragment. By removing the toolbar from Activity, I lost the hamburger button and the connection to drawerLayout. To solve this problem, I didn't delete the Toolbar in activity and made it transparent. And for each fragment, I created my own custom toolbar. In the end, I have a hamburger button linked to the Drawer and a well-functioning CollapsingToolbar. I know it's a crutch. But I couldn't find another way
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="#+id/include"
layout="#layout/content_main"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
To make the AppBar completely invisible, I added
AppBarLayout appBarLayout = findViewById(R.id.appbar);
appBarLayout.setOutlineProvider(null);
This works for Android with sdk version 21.
If you are using DrawerLayout and NavigationView for your navigation drawer, best solution according to me would be to use individual DrawerLayout for each of the fragment layouts and use the AppBarLayout in the body of the DrawerLayout differently for each of the fragments.