Good Morning, I am a newbie programmer, and I use Navigation Drawer Android Studio Activity to start. Everything is ok when I compile, but when I use the app and click on the different options, nothing happens (I mean that the layout doesn't change and remain on the activity_main.xml). I look for other questions but (I think) no one has had my problem.
MainActivity:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Ma giusto a provare", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
switch(item.getItemId()) {
case R.id.nav_home:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit();
break;
case R.id.nav_gallery:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit();
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</android.support.constraint.ConstraintLayout>
activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_home"
android:icon="#drawable/ic_menu_camera"
android:title="#string/menu_home" />
<item
android:id="#+id/nav_gallery"
android:icon="#drawable/ic_menu_gallery"
android:title="#string/menu_Cultura" />
<item
android:id="#+id/nav_slideshow"
android:icon="#drawable/ic_menu_slideshow"
android:title="#string/menu_organizer" />
<item
android:id="#+id/nav_tools"
android:icon="#drawable/ic_menu_manage"
android:title="#string/menu_tools" />
</group>
<item android:title="Communicate">
<menu>
<item
android:id="#+id/nav_share"
android:icon="#drawable/ic_menu_share"
android:title="#string/menu_share" />
<item
android:id="#+id/nav_send"
android:icon="#drawable/ic_menu_send"
android:title="#string/menu_send" />
</menu>
</item>
</menu>
fragment_cultura.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cultura generale!"
tools:layout_editor_absoluteX="171dp"
tools:layout_editor_absoluteY="320dp" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="VVVVai!"
tools:layout_editor_absoluteX="161dp"
tools:layout_editor_absoluteY="403dp" />
</android.support.constraint.ConstraintLayout>
CulturaClass.java
public class CulturaClass extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_cultura,container,false);
}
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="start">
<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="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="hello" />
</android.support.v4.widget.DrawerLayout>
Instead of R.id.fragment_container provide name for FrameLayout in activity_main.xml and pass that name while replacing fragment i.e.
case R.id.nav_home:
ft.replace(R.id.<name_of_framelayout>, new CulturaClass()).commit();
break;
case R.id.nav_gallery:
ft.replace(R.id.<name_of_framelayout>, new CulturaClass()).commit();
break;
This might work for you
Because you are replacing fragment with same class:
case R.id.nav_home:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit(); //Same Class
break;
case R.id.nav_gallery:
ft.replace(R.id.fragment_container
, new CulturaClass()).commit(); //Same Class
break;
You can do this thing simple and easy way using common function or method and You never do mistake.
You have two option to use this One is using JAVA and second, is KOTLIN
The first Method I write below check this:
If you are using java, use like this method
First, create one function i.e name setFragment and pass the parameter Fragment class and second is a title (a Title is an optional if you use or not)
Declare the globally variable
private Fragment fragment = null;
//create function for replace fragment
private void setFragment(Fragment fragmentName, String title) {
fragment = fragmentName;
if (fragment != null) {
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.framelayout, fragment, fragment.getTag()).commit();
}
setTitle("Dashboard");
// Close the navigation drawer
drawerLayout.closeDrawers();
}
If you are using KOTLIN:
First, create one function i.e name openFragment and pass the parameter Fragment class and second is a title (a Title is an optional if you use or not)
Declare the globally variable
private var fragment: Fragment? = null
//create function for replace fragment
fun openFragment(fragmentClass: Fragment, titleName: String) {
//pass the current fragment class name which you replace
fragment = fragmentClass
//check first fragment is null or not
if (fragment != null) {
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.framelayout, fragment!!, fragment!!.tag).commit()
}
title = titleName // replace the titlename
//check the drawerLayout close or not
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START)
}
}
I'm using android SearchView to have a search button in my action bar. I followed this tutorial from Google Developers on YouTube, and added a few tweaks based on my own needs. However, whenever I exit the search field that comes up when clicking the button, the search button disappears!
Here is my onCreateOptionsMenu and onOptionsItemSelected functions
onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
onOptionsItemSelected:
#Override
public boolean onOptionsItemSelected(final MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
case R.id.action_settings:
// TODO: settings activity
break;
case R.id.action_logout:
FirebaseAuth.getInstance().signOut();
break;
case R.id.action_search:
// Initialize everything here, because it produces a NullPointerException if initialized in onCreateOptionsMenu
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE);
ComponentName componentName = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
break;
}
return super.onOptionsItemSelected(item);
}
And here's my menu_main.xml layout file
<menu 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"
tools:context="com.magnus.inline.MainActivity">
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
<item
android:id="#+id/action_logout"
android:orderInCategory="200"
android:title="#string/action_logout"
app:showAsAction="never" />
And searchable.xml layout file
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="Search"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</searchable>
Images
EDIT:
I noticed that the only time the search button disappears is when I've pressed the options button while in "search mode"(see the last image in link). I have a feeling that when the options menu is displayed, the "action_search" is somehow converted to a options menu item, instead of an action bar item (?). For anyone asking, whenever I try to call MenuItemCompat.getActionView() of a searchview MenuItem in the onCreateOptionsMenu function, my app just crashes and says that it tries to perform it on a null object reference.
Here's my activity_main.xml layout file
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.magnus.inline.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/main_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AlertDialog.AppCompat.Light"
android:background="#color/colorPrimaryDark" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Instead of
app:showAsAction="ifRoom|collapseActionView"
Change to
app:showAsAction="always|collapseActionView
I have a navigation menu set up but whenever I select an item from it the onNavigationItemSelected does not get called.
MapsActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
initializeMap();
googleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
navigationMenu = (NavigationView) findViewById(R.id.navigation_menu);
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toast = Toast.makeText(this, "test", Toast.LENGTH_LONG);
navigationMenu.setNavigationItemSelectedListener(this);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
toast.show();
Log.v("NAV", "Navigation item selected");
Log.v("ITEM", item.getItemId() + "");
switch (item.getItemId()){
case R.id.nav_restaurant: {
//do stuff
}
case R.id.nav_pharmacy: {
//do stuff
}
case R.id.nav_bank: {
//do stuff
}
}
return false;
}
activity_maps.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout">
<android.support.design.widget.NavigationView
android:layout_width="200dp"
android:layout_height="match_parent"
app:menu="#menu/navigation_menu"
android:id="#+id/navigation_menu"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header">
</android.support.design.widget.NavigationView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Main Layout"
android:layout_gravity="center"
android:textAlignment="center"
android:textSize="30dp"/>
</LinearLayout>
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.damia.placefinder.activities.MapsActivity" />
The navigation menu opens and closes perfectly fine, and even closes once I select an item, but neither the two logs or the toast appears, showing that the onNavigationItemSelected was never called.
I suspect it has something to do with everything (the maps and nagivation drawer) being in the same activity but I'm not sure.
Because your NavigationView was covered by your LinearLayout and fragment. Please put the sequence of your views in activity_maps.xml in this way:
<DrawerLayout >
<LinearLayout />
<fragment />
<NavigationView /> <!-- on the top of views -->
</DrawerLayout>
And DO NOT FORGET return true; in your listener.
I want use ToolBar instead of ActionBar, but don't show me menu in toolbar!!! i want set menu such as Refresh or Setting buttons in ActionBar.
Toolbar.xml code :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
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:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:navigationContentDescription="#string/abc_action_bar_up_description"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="Main Page"
android:gravity="center"/>
MainPage.java code:
public class MainPage extends AppCompatActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle("Main Page");
}
toolbar.setSubtitle("Test Subtitle");
toolbar.inflateMenu(R.menu.main_menu);
}
}
main_menu.xml code :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/menu_main_setting"
android:icon="#drawable/ic_settings"
android:orderInCategory="100"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
<item
android:id="#+id/menu_main_setting2"
android:icon="#drawable/ic_settings"
android:orderInCategory="200"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
</menu>
How to fix this problem and show menu in Toolbar ? thanks all dears <3
just override onCreateOptionsMenu like this in your MainPage.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
Don't use setSupportActionBar(toolbar)
I don't know why but this works for me.
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
toolbar.setSubtitle("Test Subtitle");
toolbar.inflateMenu(R.menu.main_menu);
For menu item click do this:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.item1) {
// do something
} else if (item.getItemId() == R.id.filter) {
// do something
} else {
// do something
}
return false;
}
});
Will update the why part of this answer when I find a proper explanation.
Here is a fuller answer as a reference to future visitors. I usually use a support toolbar but it works just as well either way.
1. Make a menu xml
This is going to be in res/menu/main_menu.
Right click the res folder and choose New > Android Resource File.
Type main_menu for the File name.
Choose Menu for the Resource type.
Paste in the following content as a starter.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_add"
android:icon="#drawable/ic_add"
app:showAsAction="ifRoom"
android:title="Add">
</item>
<item
android:id="#+id/action_settings"
app:showAsAction="never"
android:title="Settings">
</item>
</menu>
You can right click res and choose New image asset to create the ic_add icon.
2. Inflate the menu
In your activity add the following method.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
3. Handle menu clicks
Also in your Activity, add the following method:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_add:
addSomething();
return true;
case R.id.action_settings:
startSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Further reading
Android Menu Documentation
You need to override this code in your Activity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu, this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main2, menu);
return true;
}
and set your toolbar like this:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
You can still use the answer provided using Toolbar.inflateMenu even while using setSupportActionBar(toolbar).
I had a scenario where I had to move toolbar setup functionality into a separate class outside of activity which didn't by-itself know of the event onCreateOptionsMenu.
So, to implement this, all I had to do was wait for Toolbar to be drawn before calling inflateMenu by doing the following:
toolbar.post {
toolbar.inflateMenu(R.menu.my_menu)
}
Might not be considered very clean but still gets the job done.
First way:
In activitymain.xml
<androidx.appcompat.widget.Toolbar
android:id="#+id/maintoolbar"
android:layout_width="match_parent"
android:layout_height="56dp"/>
In MainActivity.java
import androidx.appcompat.widget.Toolbar;
private Toolbar toolbar;
Inside onCreate method-
toolbar=findViewById(R.id.maintoolbar);
setSupportActionBar(toolbar);
Inside your MainActivity class-
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.<your menu xml file name here>,menu);
return super.onCreateOptionsMenu(menu);
}
Second way :
//Remove setSupportActionBar(toolbar) and onCreateOptionmenu.
toolbar=findViewById(R.id.maintoolbar);
toolbar.inflateMenu(R.menu.<your menu xml file name here>);
Also you need this, to implement some action to every options of menu.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_help:
Toast.makeText(this, "This is teh option help", Toast.LENGTH_LONG).show();
break;
default:
break;
}
return true;
}
Without ActionBar but with Toolbar
If you want to use a Toolbar instead of the ActionBar, to setSupportActionBar is contradiction in principle as #RohitSingh answered above.
You need neither to use setSupportActionBar nor to override onCreateOptionsMenu and onOptionsItemSelected which are used for the ActionBar.
NoActionBar theme
Place a Toolbar in the layout xml
Prepare a menu xml
Toolbar#inflateMenu (alternatively you can also set a menu in the layout xml)
Toolbar#setOnMenuItemClickListener
Below is an example.
1. NoActionBar theme
(MaterialCompolent.DayNight theme is used in this sample)
<style name="Theme.AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
2. Place a Toolbar in the layout
(MaterialToobar is used in this sample)
<androidx.constraintlayout.widget.ConstraintLayout
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="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
3. Prepare a menu xml
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/item1"
android:title="#string/item1"
app:showAsAction="ifRoom" />
<item
android:id="#+id/item2"
android:title="#string/item2"
app:showAsAction="ifRoom" />
</menu>
4. Toolbar#inflateMenu
binding.toolbar.inflateMenu(R.menu.main); // binding is a ViewBinding
5. Toolbar#setOnMenuItemClickListener
Recent Android recommend to avoid to use switch to differentiate ids. Using a normal if ~ else if ~ else block is desirable. In addition to that, we can use lambda in Java 8.
binding.toolbar.setOnMenuItemClickListener(menuItem -> {
int itemId = menuItem.getItemId();
if (itemId == R.id.item1) {
// do something for item1
return true;
} else if (itemId == R.id.item2) {
// do something for item2
return true;
} else {
// if you do nothing, returning false should be appropriate.
return false;
}
});
Although I agree with this answer, as it has fewer lines of code and that it works:
How to set menu to Toolbar in Android
My suggestion would be to always start any project using the Android Studio Wizard. In that code you will find some styles:-
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
and usage is:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
Due to no action bar theme declared in styles.xml, that is applied to the Main Activityin the AndroidManifest.xml, there are no exceptions, so you have to check it there.
<activity android:name=".MainActivity" android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
The Toolbar is not an independent entity, it is always a child
view in AppBarLayout that again is the child of
CoordinatorLayout.
The code for creating a menu is the standard code since day one,
that is repeated again and again in all the answers, particularly
the marked one, but nobody realized what is the difference.
BOTH:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
AND:
How to set menu to Toolbar in Android
WILL WORK.
Happy Coding :-)
In XML add one line inside
<com.google.android.material.appbar.MaterialToolbar app:menu="#menu/main_menu"/>
In java file
Remove three line setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setTitle("Main Page"); }
add one line toolbar.setTitle("Main Page")
In your activity override this method.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
This will inflate your menu below:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/menu_main_setting"
android:icon="#drawable/ic_settings"
android:orderInCategory="100"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
<item
android:id="#+id/menu_main_setting2"
android:icon="#drawable/ic_settings"
android:orderInCategory="200"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
</menu>
In my case, I'm using an AppBarLayout with a CollapsingToolbarLayout and the menu was always
being scrolled out of the screen, I solved my problem by switching android:actionLayout in menu's XML to
the toolbar's id. I hope it can help people in the same situation!
activity_main.xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fab="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=".activities.MainScreenActivity"
android:screenOrientation="portrait">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="300dp"
app:elevation="0dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="48dp"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:elevation="0dp"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
main_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/logoutMenu"
android:orderInCategory="100"
android:title="#string/log_out"
app:showAsAction="never"
android:actionLayout="#id/toolbar"/>
<item
android:id="#+id/sortMenu"
android:orderInCategory="100"
android:title="#string/sort"
app:showAsAction="never"/> </menu>
You can achieve this by two methods
Using XML
Using java
Using XML
Add this attribute to toolbar XML
app:menu = "menu_name"
Using java
By overriding onCreateOptionMenu(Menu menu)
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.demo_menu,menu);
return super.onCreateOptionsMenu(menu);
}
}
for more details or implementating click on the menu go through this article
https://bedevelopers.tech/android-toolbar-implementation-using-android-studio/
You don't actually need to touch the fragment/activity class at all to get a menu inside a toolbar. You can use Rohit Singh's method inside onViewCreated method
import androidx.appcompat.widget.Toolbar
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val toolbar = view.findViewById<Toolbar>(R.id.inbox_toolbar)
toolbar.inflateMenu(R.menu.inbox_menu)
}
or
simply define a app:menu element inside the toolbar,
<androidx.appcompat.widget.Toolbar ...
app:menu= "#menu/myMenu" ?>
Simple fix to this was setting showAsAction to always in menu.xml in res/menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/add_alarm"
android:icon="#drawable/ic_action_name"
android:orderInCategory="100"
android:title="Add"
app:showAsAction="always"
android:visible="true"/>
</menu>
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar;
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_drawer,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_drawer){
drawerLayout.openDrawer(GravityCompat.END);
if (drawerLayout.isDrawerOpen(GravityCompat.END)) {
drawerLayout.closeDrawer(GravityCompat.END);
} else {
drawerLayout.openDrawer(GravityCompat.END);
}
}
return super.onOptionsItemSelected(item);
}
res/layout/drawer_menu
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_drawer"
android:title="#string/app_name"
android:icon="#drawable/ic_menu_black_24dp"
app:showAsAction="always"/>
</menu>
toolbar.xml
<com.google.android.material.appbar.AppBarLayout
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:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:titleTextColor="#android:color/white"
app:titleTextAppearance="#style/TextAppearance.Widget.Event.Toolbar.Title">
<TextView
android:id="#+id/toolbar_title"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/app_name"
android:textColor="#android:color/white"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title" />
</androidx.appcompat.widget.Toolbar>
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.my_toolbar);
*// here is where you set it to show on the toolbar*
setSupportActionBar(toolbar);
}
Well, you need to set support action bar setSupportActionBar(); and pass your variable, like so: setSupportActionBar(toolbar);
I'm currently creating and defining a navigation drawer. I want now a header view, like their on the google apps, above the item rows. I only found examples with RecyclerViews, and i dont want to use it. I have all finished with a ListView and all other stuff. Maybe someone can help me :) Thanks in advance
You can create NavigationView using android design support library without having pain to create listview or RecyclerView, its all created by android.
To add it to your project you need to add the android design support library to your project, add below line in build.gradle
compile 'com.android.support:design:22.2.0
Check out android design support features here
First create a header(header.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="190dp"
android:background="#drawable/background_material"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="nyname"
</RelativeLayout>
Next create a menu resource file, the items in the menu will be the items displayed in the drawer(drawer.xml)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/first1"
android:checked="false"
android:icon="#drawable/icon1"
android:title="#string/string1" />
<item
android:id="#+id/second2"
android:checked="false"
android:icon="#drawable/icon2"
android:title="#string/string2" />
</menu>
Next create a DrawerLayout file, within the drawerlayout you can see I have included a Toolbar and a 'FrameLayout`. When the item in the drawerlayout is clicked you can replace fragment.
Also within it is the NavigationView with these parameters:
app:headerLayout="#layout/header"
app:menu="#menu/drawer"
android:layout_gravity="start"
app:headerLayout is the header.xml that we created in step 1.
app:menu is the menu resource item i.e drawer.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<include
android:id="#+id/toolbar"
layout="#layout/tool_bar"
/>
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="#layout/header"
app:menu="#menu/drawer"
/>
</android.support.v4.widget.DrawerLayout>
Next in your MainActivity extend AppcompatActivity,
public class MainActivity extends AppCompatActivity {
............................................
Intialise NavigationView and call setNavigationItemSelectedListener to get click events,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not make it in checked state
if(menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()){
//Replacing the main content with ContentFragment
case R.id.first1:
SomeFragment fragment = new SomeFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment);
fragmentTransaction.commit();
return true;
...................
Step by step procedure to create navigationview go here
How it would look: