I have a drawer layout that needs to have two navigation views in it, because there's a couple of options that need to be aligned on top and another on the bottom, with a divider separating them.
I've managed to make it work, but now I have two different problems with my setup.
1) The first one, I can't change the selected items text color (the background color works as intented via a drawer selector, but for some reason, the selected item's text color is always colorPrimary)
2) The second one is trickier, since there's two navigation views, it can happen that there's a selected row on the first and on the second one, even though they all work loading fragments in the same container. Is there a way to manage that, when an item for the first navigation view is selected, the second navigation view's selected item gets deselected?
This is the drawer's layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- 1º Layout de la activity -->
<include layout="#layout/activity_main"/>
<!-- 2º Layout del drawer -->
<android.support.design.widget.NavigationView
android:id="#+id/container_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemBackground="#drawable/drawer_list_selector"
android:nestedScrollingEnabled="true"
android:scrollIndicators="none">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="#dimen/divider_height"
android:background="#color/colorAccent"
android:layout_above="#+id/navigation_view"
android:id="#+id/top_separator"/>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_above="#+id/bottom_separator"
app:itemBackground="#drawable/drawer_list_selector"
app:menu="#menu/menu_navigation" />
<View
android:layout_width="match_parent"
android:layout_height="#dimen/divider_height"
android:background="#color/colorAccent"
android:layout_above="#+id/navigation_bottom"
android:id="#+id/bottom_separator"/>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:menu="#menu/menu_navigation_bottom"
app:itemBackground="#drawable/drawer_list_selector"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
This is the top navigation view's layout:
<?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">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_tus_ofertas"
android:title="#string/tus_ofertas"
android:icon="#drawable/ic_offer" />
<item
android:id="#+id/nav_movimiento_puntos"
android:title="#string/movimiento_puntos"
android:icon="#drawable/ic_points"/>
<item
android:id="#+id/nav_asociaciones"
android:title="#string/asociaciones"
android:icon="#drawable/ic_flag"/>
</group>
</menu>
Bottom navigation view's layout:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_terminos"
android:title="#string/terminos"
android:icon="#drawable/ic_document" />
<item
android:id="#+id/nav_contacto"
android:title="#string/contacto"
android:icon="#drawable/ic_email"/>
<item
android:id="#+id/nav_valorar"
android:title="#string/valorar"
android:icon="#drawable/ic_rate_review"/>
<item
android:id="#+id/nav_exit"
android:title="#string/exit"
android:icon="#drawable/ic_shutdown"/>
</group>
</menu>
Selected item's background selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/colorAccent" />
<item android:state_activated="true" android:drawable="#color/colorAccent" />
<item android:state_selected="true" android:drawable="#color/colorAccent" />
<item android:state_checked="true" android:drawable="#color/colorAccent" />
<item android:state_pressed="false" android:drawable="#android:color/transparent" />
<item android:state_activated="false" android:drawable="#android:color/transparent" />
<item android:state_selected="false" android:drawable="#android:color/transparent" />
<item android:state_checked="false" android:drawable="#android:color/transparent" />
</selector>
The activity that calls the drawer and handles the events:
public class MainActivity extends AppCompatActivity {
#Bind(R.id.toolbar) Toolbar toolbar;
#Bind(R.id.tabs) TabLayout tabs;
#Bind(R.id.drawer_layout) DrawerLayout drawerLayout;
#Bind(R.id.container_navigation) NavigationView containerNavigator;
#Bind(R.id.navigation_view) NavigationView navigationView;
#Bind(R.id.navigation_bottom) NavigationView navigationBottom;
#Bind(R.id.vsFooter) ViewStubCompat stub;
ImageView userPicture;
TextView userMail;
ViewPager viewPager;
Menu menu;
ActionBar actionBar;
ViewPagerFragment viewPagerFragment;
Usuario currentUser;
public Usuario getCurrentUser() {
return currentUser;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer);
ButterKnife.bind(this);
currentUser = UserApiManager.getInstance(getApplicationContext()).getCurrentUser();
viewPagerFragment = ViewPagerFragment.newInstance();
setupToolbar();
setupNavigationDrawer();
ApiManager.getInstance(getApplicationContext()).setupFooter(stub, currentUser.getIdLocalidad(), this);
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,viewPagerFragment).commit();
}
public void setupViewPager(ViewPager viewPager) {
tabs.setupWithViewPager(viewPager);
}
private void setupToolbar() {
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
if (actionBar!=null){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_black);
actionBar.setTitle(getString(R.string.app_title));
}
}
private void setupNavigationDrawer() {
View headerView = navigationView.inflateHeaderView(R.layout.navigation_header);
userPicture = (ImageView) headerView.findViewById(R.id.user_picture);
userMail = (TextView) headerView.findViewById(R.id.user_mail);
userMail.setText(currentUser.getEmail());
Picasso.with(this).load(currentUser.getImagenURL()).transform(new CircleTransformation()).into(userPicture);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_tus_ofertas:
showTabLayout();
actionBar.setTitle(getString(R.string.app_title));
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,viewPagerFragment).commit();
break;
case R.id.nav_movimiento_puntos:
hideTabLayout();
Bundle bundle = new Bundle();
bundle.putString("idcliente", currentUser.getId());
MovimientoPuntosFragment movimientoPuntosFragment = MovimientoPuntosFragment.newInstance();
movimientoPuntosFragment.setArguments(bundle);
actionBar.setTitle(getString(R.string.movimiento_puntos));
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, movimientoPuntosFragment).commit();
break;
case R.id.nav_asociaciones:
hideTabLayout();
actionBar.setTitle(getString(R.string.asociaciones));
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, AsociacionFragment.newInstance()).commit();
break;
}
drawerLayout.closeDrawers();
return true;
}
});
navigationBottom.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_terminos:
hideTabLayout();
actionBar.setTitle(getString(R.string.terminos));
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, LegalesFragment.newInstance()).commit();
break;
case R.id.nav_contacto:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + getString(R.string.contacto_email));
intent.setData(data);
startActivity(intent);
break;
case R.id.nav_valorar:
final String appPackageName = BuildConfig.APPLICATION_ID;
try {
Log.i("url", "market://details?id=" + appPackageName);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
break;
case R.id.nav_exit:
break;
}
drawerLayout.closeDrawers();
return true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_over, menu);
this.menu = menu;
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.action_user:
Intent intent = new Intent(this, PerfilUsuarioActivity.class);
startActivity(intent);
break;
}
return super.onOptionsItemSelected(item);
}
public void hideTabLayout(){
tabs.setVisibility(View.GONE);
}
public void showTabLayout(){
tabs.setVisibility(View.VISIBLE);
}
}
Any help would be appreciated!
Thanks in advance!
Solved!
The problem with the color I solved it with a selector, it didn't work before because I had a syntax error (selector tag inside the main selector tag).
This is the color selector's code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FFFFFFFF" android:state_checked="true" />
<item android:color="#E6000000" android:state_checked="false"/>
</selector>
The second problem I solved it by programmatically deselecting the other navigationview's items onNavigationItemSelected.
This is the function I call:
public void deselectItems(NavigationView view){
int size = view.getMenu().size();
for (int i = 0; i < size; i++) {
view.getMenu().getItem(i).setChecked(false);
}
}
I know there must be a better way to solve the second problem, but this one worked.
Related
I'm trying to change the text color of the selected item in the NavigationView. Using the information for the previous topic I set a selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/primaryColor" android:state_checked="true" />
<item android:color="#color/lightGrayColor" android:state_checked="false" />
</selector>
The primaryColor is blue. The NavigationView is as follows:
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/activity_nav_header"
app:menu="#menu/nev_menu"
app:itemIconTint="#drawable/menu_item_selector"
app:itemTextColor="#drawable/menu_item_selector" />
</androidx.drawerlayout.widget.DrawerLayout>
As you can see I set app:itemTextColor to menu_item_selector. But when I run the application, I see the selected item as grey. How does the NavigationView know which screen am I seeing right now? How do I fix it?
I'm using onNavigationItemSelected to switch between activities. Also I currently have only two windows - the dashboard and the logout. From the main screen I move to the dashboard (which contains the menu) and using the logout I go back to the main screen. Maybe the reason for it not working is because it does not know that the current screen is dashboard?
The dashboard java cotnains the following method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
toolBar = findViewById(R.id.toolbar);
setSupportActionBar(toolBar);
drawerLayout = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.nav_view);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolBar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View hView = navigationView.getHeaderView(0);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.dashboard:
// CURRENT ACTIVITY
break;
case R.id.messages:
startActivity(new Intent(this, MessagesActivity.class));
break;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
break;
case R.id.about:
startActivity(new Intent(this, AboutActivity.class));
break;
case R.id.logout:
startActivity(new Intent(this, MainActivity.class));
break;
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
For the initial look, you set a checked color to primaryColor, but overwrite it with lightGrayColor as you didn't specify the state that this color is available at; so you need to specify the state by android:state_checked="false"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/primaryColor" android:state_checked="true" />
<item android:color="#color/lightGrayColor" android:state_checked="false"/>
</selector>
You can also set the default selected item at the app start by trying any of:
navigationView.getMenu().getItem(0).setChecked(true);
navigationView.setCheckedItem(R.id.nav_item);
Update
This is how it works with me
Step 1: Use the same selector:
selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/primaryColor" android:state_checked="true" />
<item android:color="#color/lightGrayColor" android:state_checked="false" />
</selector>
Step 2: use the xml attribute app:itemTextColor within NavigationView widget
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header_layout"
app:itemTextColor="#drawable/selector"
app:menu="#menu/navigation_menu" />
Step 3:
The previous step attribute won't work automatically as for some reason when you hit an item from the NavigationView menu, it doesn't consider this as a button check. So you need to manually get the selected item checked and clear the previously selected item. Use below listener to do that
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
// remove all colors of the items to the `unchecked` state of the selector
removeColor(mNavigationView);
// check the selected item to change its color set by the `checked` state of the selector
item.setChecked(true);
switch (item.getItemId()) {
case R.id.dashboard:
// CURRENT ACTIVITY
break;
case R.id.messages:
startActivity(new Intent(this, MessagesActivity.class));
break;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
break;
case R.id.about:
startActivity(new Intent(this, AboutActivity.class));
break;
case R.id.logout:
startActivity(new Intent(this, MainActivity.class));
break;
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
private void removeColor(NavigationView view) {
for (int i = 0; i < view.getMenu().size(); i++) {
MenuItem item = view.getMenu().getItem(i);
item.setChecked(false);
}
}
Now the text color will change perfectly.
Step 4:
To change icon colors, use the app:iconTint attribute in the NavigationView menu items, and set to the same selector.
<?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/nav_account"
android:checked="true"
android:icon="#drawable/ic_person_black_24dp"
android:title="My Account"
app:iconTint="#drawable/selector" />
<item
android:id="#+id/nav_settings"
android:icon="#drawable/ic_settings_black_24dp"
android:title="Settings"
app:iconTint="#drawable/selector" />
<item
android:id="#+id/nav_logout"
android:icon="#drawable/logout"
android:title="Log Out"
app:iconTint="#drawable/selector" />
</menu>
Result:
I have created the default template with menu from android studio. This project is working now but sometimes a user can click on meny only on small area:
But sometimes all items in menu work fine(each of item has normal area for click listener), It happens randomly.
Maybu someone has this problem, i cant understand why it happens.
My code:
xml
<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/view_nav_header_main"
app:menu="#menu/activity_main_drawer" />
activity_main_drawer
<?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_overview"
android:icon="#drawable/icon_overview"
android:title="#string/overview" />
<item
android:id="#+id/nav_library"
android:icon="#drawable/icon_library"
android:title="#string/library_of_events" />
<item
android:id="#+id/nav_statistic"
android:icon="#drawable/icon_chart"
android:title="#string/view_your_stats" />
<item
android:id="#+id/nav_add_event"
android:icon="#drawable/icon_add_event"
android:title="#string/create_a_new_event" />
<item
android:id="#+id/nav_settings"
android:icon="#drawable/icon_settings"
android:title="#string/settings" />
<item
android:id="#+id/nav_export"
android:icon="#drawable/icon_table"
android:title="#string/data_export" />
<item
android:id="#+id/nav_help"
android:icon="#drawable/icon_help"
android:title="#string/help" />
</group>
</menu>
activity has default template code
public class MainActivity extends TimeActivity implements NavigationView.OnNavigationItemSelectedListener, DrawerLayout.DrawerListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.open, R.string.close);
drawer.addDrawerListener(toggle);
navigationView.setNavigationItemSelectedListener(this);
drawer.addDrawerListener(this);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Log.e(TAG, "onNavigationItemSelected " + String.valueOf(item.getItemId()));
switch (item.getItemId()) {
case R.id.nav_overview:
openOverview();
break;
case R.id.nav_library:
openEventsLibrary();
break;
case R.id.nav_statistic:
openStatistic();
break;
case R.id.nav_add_event:
openAddEvent();
break;
case R.id.nav_settings:
openSettings();
break;
case R.id.nav_export:
openDataExport();
break;
case R.id.nav_help:
VideoActivity.start(this, false);
//youTubePopUp.show(view);
break;
default:
openWelcome(0);
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onDrawerSlide(#NonNull View view, float v) {
}
#Override
public void onDrawerOpened(#NonNull View view) {
Utils.hideKeyboard(this);
}
#Override
public void onDrawerClosed(#NonNull View view) {
}
}
Currently, my options menu is aligned to the end of the screen. I want to give it a margin, something like android:layout_marginEnd = "20dp". How can I achieve this?
My options 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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/menu_items"
android:icon="#drawable/menu_icon"
app:showAsAction="always">
<menu>
<group android:id="#+id/item1">
<item
android:id="#+id/download"
android:icon="#drawable/download_icon"
android:title="Download"></item>
</group>
<group android:id="#+id/item2">
<item
android:id="#+id/invite"
android:icon="#drawable/invite_icon"
android:title="Invite"></item>
</group>
</menu>
</item>
</menu>
My Custom Toolbar:
<androidx.appcompat.widget.Toolbar
android:id="#+id/menu_toolbar"
app:popupTheme="#style/ThemeOverlay.MyTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_below="#id/greetText"> <!--assume it comes somewhere in the centre due to this-->
</androidx.appcompat.widget.Toolbar>
My Theme for menu items:
<style name="ThemeOverlay.MyTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#color/dimGray</item>
<item name="android:textSize">14sp</item>
<item name="android:layout_marginEnd">20dp</item> <!-- doesn't work-->
<item name="android:fontFamily">#font/quicksand_medium</item>
<item name="android:background">#drawable/options_menu_background</item>
</style>
Here is the image of my problem. It shows how the end of the menu and the screen are aligned. I want space/margin between these two.
This is an interesting problem. I tried with many things found on the internet, but nothing works. I tried setting the actionOverflowMenuStyle with dropDownHorizontalOffset attribute which does not work either. Finally, I ended up getting a PopupMenu which works just fine. Here is the implementation.
Get your initial menu shorter with a single item which will open up the popup menu as a submenu.
<?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_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Then create another menu, in your /res/menu/ folder, named popup_menu.xml like the following.
<?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_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Now in your MainActivity, just add the following functions to handle the click action of the menu button and the popup menu.
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = findViewById(R.id.menu_toolbar);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_items:
showPopupMenu();
return true;
default:
return false;
}
}
public void showPopupMenu() {
PopupMenu popup = new PopupMenu(this, findViewById(R.id.menu_items));
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.popup_menu);
popup.setGravity(Gravity.END);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popup);
argTypes = new Class[]{boolean.class};
menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true);
} catch (Exception e) {
e.printStackTrace();
}
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.invite:
Toast.makeText(this, "Invite", Toast.LENGTH_LONG).show();
return true;
case R.id.download:
Toast.makeText(this, "Download", Toast.LENGTH_LONG).show();
return true;
default:
return false;
}
}
}
I put the working code in this Github Branch. You might consider cloning from that branch and run the application to check if that suffices your expectation.
Hope that helps!
Android 5.0 Material Design it seems impossible.
You can get that kind of effect using Bottom Navigation Tab.
Try this code hope it helps you
For Bottom Navigation Tab you have to add this line into dependency
compile ‘com.android.support:design:25.0.0’
Here is MainActivity.Java
public class MainActivity extends AppCompatActivity {
private BottomBar mBottomBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Notice how you don't use the setContentView method here! Just
// pass your layout to bottom bar, it will be taken care of.
// Everything will be just like you're used to.
mBottomBar = BottomBar.bind(this, R.layout.activity_main,
savedInstanceState);
mBottomBar.setItems(
new BottomBarTab(R.drawable.ic_recents, "Recents"),
new BottomBarTab(R.drawable.ic_favorites, "Favorites"),
new BottomBarTab(R.drawable.ic_nearby, "Nearby"),
new BottomBarTab(R.drawable.ic_friends, "Friends")
);
mBottomBar.setOnItemSelectedListener(new OnTabSelectedListener() {
#Override
public void onItemSelected(final int position) {
// the user selected a new tab
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mBottomBar.onSaveInstanceState(outState);
}
}
Design.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<!-- Content Container -->
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/white"
app:itemTextColor="#color/white"
app:menu="#menu/bottom_navigation_main" />
</RelativeLayout>
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/action_favorites"
android:enabled="true"
android:icon="#drawable/ic_favorite_white_24dp"
android:title="#string/text_favorites"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_schedules"
android:enabled="true"
android:icon="#drawable/ic_access_time_white_24dp"
android:title="#string/text_schedules"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_music"
android:enabled="true"
android:icon="#drawable/ic_audiotrack_white_24dp"
android:title="#string/text_music"
app:showAsAction="ifRoom" />
</menu>
Enable/Disable click state
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/white" android:state_enabled="true" />
<item android:color="#color/colorPrimaryDark" android:state_enabled="false" />
</selector>
Handle click event using this
BottomNavigationView bottomNavigationView = (BottomNavigationView)
findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorites:
break;
case R.id.action_schedules:
break;
case R.id.action_music:
break;
}
return false;
}
});
Add view in layout
<View
android:layout_width="fill_parent"
android:layout_height="5dip"
android:background="#drawable/drop_shadow" >
</View>
add in your drawable folder drop_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#404040"
android:endColor="#F1F1F1"
android:angle="270"
>
</gradient>
</shape>
I've switched to the official Google Design Support Library. Now, I want to use a secondary menu with a divider like this:
But as Android is using the Menu Inflater I have no idea what to do now. I can add a second group, but then the items have the same size and there is no divider.
drawer.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/overview"
android:checked="true"
android:icon="#drawable/ic_action_dashboard"
android:title="#string/drawer_overview" />
<item
android:id="#+id/social_evening"
android:checked="false"
android:icon="#drawable/ic_action_brightness_3"
android:title="#string/drawer_social_evening" />
<item
android:id="#+id/scouting_games"
android:checked="false"
android:icon="#drawable/ic_action_landscape"
android:title="#string/drawer_scouting_games" />
<item
android:id="#+id/olympics"
android:checked="false"
android:icon="#drawable/ic_action_stars"
android:title="#string/drawer_olympics" />
<item
android:id="#+id/quizzes"
android:checked="false"
android:icon="#drawable/ic_action_school"
android:title="#string/drawer_quizzes" />
</group>
</menu>
MainActivity.java:
package net.sutomaji.freizeitspiele;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
/**
* Created by Tom Schneider on 18.06.15
*/
public class MainActivity extends AppCompatActivity {
//Defining Variables
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
#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);Q
//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 Which is our Inbox View;
case R.id.overview:
Toast.makeText(getApplicationContext(), "Overview Selected", Toast.LENGTH_SHORT).show();
ContentFragment fragment = new ContentFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment);
fragmentTransaction.commit();
return true;
// For rest of the options we just show a toast on click
case R.id.social_evening:
Toast.makeText(getApplicationContext(),"SE Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.scouting_games:
Toast.makeText(getApplicationContext(),"SG Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.olympics:
Toast.makeText(getApplicationContext(),"OL Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.quizzes:
Toast.makeText(getApplicationContext(),"QZ Selected",Toast.LENGTH_SHORT).show();
return true;
default:
Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
return true;
}
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer){
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessay or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
#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;
}
#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);
}
}
So, how can I create a menu like this, or how can I add dividers (with category headers) to my navigation drawer?
You can use the standard NavigationView defining a menu like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="#+id/group1" android:checkableBehavior="single" id>
//items of group1
</group>
<group android:id="#+id/group2" android:checkableBehavior="single" id>
//items of group2
</group>
It is important to give an unique id to each group.
Tutorial: Navigation View Design Support Library
Menu Items:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/navigation_item_attachment"
android:checked="true"
android:icon="#drawable/ic_attachment"
android:title="#string/nav_item_attachment" />
<item
android:id="#+id/navigation_item_images"
android:icon="#drawable/ic_image"
android:title="#string/nav_item_images" />
<item
android:id="#+id/navigation_item_location"
android:icon="#drawable/ic_place"
android:title="#string/nav_item_location" />
</group>
<item android:title="#string/nav_sub_menu">
<menu>
<item
android:icon="#drawable/ic_emoticon"
android:title="#string/nav_sub_menu_item01" />
<item
android:icon="#drawable/ic_emoticon"
android:title="#string/nav_sub_menu_item02" />
</menu>
</item>
</menu>
Here is what you exactly looking for:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/Home"
android:checked="false"
android:icon="#drawable/ic_home"
android:title="#string/homestr" />
<item
android:id="#+id/myacc"
android:checked="false"
android:icon="#drawable/ic_account"
android:title="#string/myaccstr" />
<item
android:id="#+id/popular"
android:checked="false"
android:icon="#drawable/ic_star"
android:title="#string/Popularstr" />
<item
android:id="#+id/newsit"
android:checked="false"
android:icon="#drawable/ic_news"
android:title="#string/newsstr" />
<item android:title="#string/gn">
<menu>
<item
android:id="#+id/settings"
android:checked="false"
android:icon="#drawable/ic_setting"
android:title="#string/action_settings" />
<item
android:id="#+id/help"
android:checked="false"
android:icon="#drawable/ic_help"
android:title="#string/helpstr" />
</menu>
</item>
</group>
</menu>
You can use any ViewGroup like a LinearLayout for your Drawer. It is not limited to a ListView and a FrameLayout. Because of this you can style your Drawer View like any other layout of an Activity for example. The only thing you should keep in mind is that the NavigationDrawer can have only two childs. The first is your layout for the Activity and the second is the Drawer. Feel free to style them as you like!
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- YOUR DRAWER -->
<LinearLayout
android:id="#+id/drawer_view"
android:layout_width="240dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="start">
<!-- Use any Views you like -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#ffffff"/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
for the divider
android:divider="#FFFFFF"
android:dividerHeight="1dp"