How would I create a tab indicator in NavigationDrawer? - android

How do I create a navigation draw tab indicator like this? Does the NavigationDrawer class have an indicator like TabLayout?

You can define a custom drawable with a left border and set it as the background of the selected item. Follow the steps given below,
Step 1: Define a drawable with left border(selected_item.xml) in drawables
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#000000" />
</shape>
</item>
<item android:left="2dp">
<shape android:shape="rectangle">
<solid android:color="#FF0000" />
</shape>
</item>
</layer-list>
Step 2: Define a selector(navi_selector.xml) in drawables
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/selected_item"/>
<item android:state_pressed="true" android:drawable="#000000"/>
</selector>
Step 3: set the navi_selector for app:itemBackground
<android.support.design.widget.NavigationView
app:itemTextColor="#android:color/white"
android:fitsSystemWindows="true"
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/activity_main_drawer"
android:background="#000000"
app:itemBackground="#drawable/navi_selector"/>

Related

Navigation Drawer item divider with selected background color

I have a navigation drawer in my android app. Here's the code:
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:fitsSystemWindows="true"
android:background="#color/white"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_menu"
app:itemTextColor="#color/drawer_item"
app:itemIconTint="#color/drawer_item"
app:itemBackground="#drawable/nav_divider"/>
I've used one the answer to this post to add dividers between the items. Here's the nav_divider drawable that I'm using as itemBackground in my NavigationView:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="#dimen/activity_horizontal_margin">
<shape android:shape="rectangle">
<solid android:color="#color/light_gray"/>
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/white"/>
</shape>
</item>
</layer-list>
Now, the question is how do I change the background color of the selected item. I know how to do that without the divider, but with the divider, it's more complicated.
UPDATE:
Here's what I've tried:
I created another drawable called nav_divider_selected which is exactly like the nav_divider above except with different colors.
Then, I created a drawer_item_background drawable like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/nav_divider_selected" android:state_selected="true"/>
<item android:drawable="#drawable/nav_divider"/>
</selector>
And, replaced the itemBackground of the NavigationView with this new selector (app:itemBackground="#drawable/drawer_item_background"). But, it didn't work. The items all look black, for some reason.
I got it. It was a simple issue. I was just using the wrong state. So, here's the solution. I created two different layer lists (to add the divider to the navigation items):
nav_divider:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="#dimen/activity_horizontal_margin">
<shape android:shape="rectangle">
<solid android:color="#color/light_gray"/>
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/white"/>
</shape>
</item>
</layer-list>
nav_divider_selected:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="#dimen/activity_horizontal_margin">
<shape android:shape="rectangle">
<solid android:color="#color/light_gray"/>
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/light_blue"/>
</shape>
</item>
</layer-list>
Then, created a drawer_item_background drawable like this (state_checked should be used not state_selected):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/nav_divider_selected" android:state_checked="true"/>
<item android:drawable="#drawable/nav_divider"/>
</selector>
And, then I used this drawable as itemBackground in my NavigationView:
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:fitsSystemWindows="true"
android:background="#color/white"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_menu"
app:itemTextColor="#color/drawer_item"
app:itemIconTint="#color/drawer_item"
app:itemBackground="#drawable/drawer_item_background"/>
Also if in-case you do not want to use a selector to achieve that you can do so like this
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_share"
android:icon="#drawable/ic_menu_share"
android:title="#string/menu_share" />
</group>
By wrapping the element under <group android:checkableBehavior="single"> we get a selected background.
Try the below item_background.xml in
app:itemBackground="#drawable/item_background" for NavigationView
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/rgb_red" android:state_checked="true" />
<item android:drawable="#color/rgb_red" android:state_activated="true" />
<item>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/rgb_white" />
<item android:start="-2dp"
android:top="-2dp"
android:end="-2dp">
<shape>
<solid android:color="#android:color/transparent" />
<stroke android:width="1dp" android:color="#color/rgb_pale_gray"/>
</shape>
</item>
</layer-list>
</item>
</selector>
hope it will help you

android ripple effect crashes in pre-lollipop even when I added drawable-21

Ripple effect works fine but crashes below lollipop, So I added drawable-v21/animation_ripple but result is the same. What to do, Here is my code:-
XML file:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/animation_ripple"
android:text="Click Me"
android:textColor="#ccc"/>
drawable/animation_ripple
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#4d6670"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#4d6670" />
</shape>
</item>
<item >
<shape android:shape="rectangle">
<solid android:color="#62bae0" />
</shape>
</item>
</ripple>
drawable-v21/animation_ripple
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#4d6670"
>
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#4d6670" />
</shape>
</item>
<item >
<shape android:shape="rectangle">
<solid android:color="#62bae0" />
</shape>
</item>
</selector>
in drawable-v21 add your rippledrawable and in drawable add the selector drawable , as <ripple> </ripple> tags are used for api >=21
It should be the other way around:
drawable-v21 should contain <ripple ... tags and drawable the regular <selector ... tags.
Everything under the drawable-v21 folder will be used from Lollipop on, not the other way around

Set color to unselected tab indicator in tab layout

I am using tablayout provided by google and everything is working fine except the color of the unselected tab indicator. I am unable to set the unselected tab indicator color.
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
style="#style/MyCustomTabLayout"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout>
**1.app:**
tabBackground="#drawable/tablayout_selector"
**2.tablayout_selector.xml**
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#color/shl_common_default_color" />
</shape>
</item>
<item>
<inset android:insetBottom="1.5dp">
<shape android:shape="rectangle">
<solid android:color="#color/white" />
</shape>
</inset>
</item>
</layer-list>
or
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#color/white" />
</shape>
</item>
<item android:gravity="bottom">
<shape android:shape="rectangle">
<solid android:color="#color/shl_common_default_color" />
<size android:height="1.5dp" />
</shape>
</item>
</layer-list>
try this changing the color as you wish:
Create this file in drawable folder
tab_indicator_color.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- UNSELECTED TAB STATE -->
<item android:state_selected="false" android:state_pressed="false">
<layer-list>
<!-- Bottom indicator color for the UNSELECTED tab state -->
<item android:top="-5dp" android:left="-5dp" android:right="-5dp">
<shape android:shape="rectangle">
<stroke android:color="#65acee" android:width="2dp"/>
</shape>
</item>
</layer-list>
</item>
</selector>
and after set your .xml file in app:tabBackground like this:
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
style="#style/MyCustomTabLayout"
app:tabBackground="#drawable/tab_indicator_color" />
ic_tab_indicator_default.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" />
</item>
<item android:gravity="bottom">
<shape android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="#color/steel_blue" />
</shape>
</item>
</layer-list>
ic_tab_indicator_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" />
</item>
<item android:gravity="bottom">
<shape android:shape="rectangle">
<size android:height="3dp" />
<solid android:color="#color/congress_blue" />
</shape>
</item>
</layer-list>
selector_tab_indicator.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_tab_indicator_selected" android:state_selected="true" />
<item android:drawable="#drawable/ic_tab_indicator_default" />
</selector>
TabLayout
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicator="#android:color/transparent"
app:tabBackground="#drawable/selector_tab_indicator">
For people using the new com.google.android.material.tabs.TabLayout if you apply the solution given as the correct answer in this post would get corners on all four sides of the tab
To fix that use the following "hack"
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- UNSELECTED TAB STATE -->
<item android:state_selected="false" android:state_pressed="false">
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Bottom indicator color for the UNSELECTED tab state -->
<item android:top="-10dp" android:left="-1000dp" android:right="-1000dp">
<shape android:shape="rectangle" >
<stroke android:color="#4cffffff" android:width="1dp"/>
</shape>
</item>
</layer-list>
</item>
</selector>
If your TabLayout don't need title, but need indicator for unselected color.
You can do like
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="10dp"
app:tabBackground="#drawable/tab_normal"
app:tabIndicator="#drawable/tab_indicator"
app:tabIndicatorColor="#null"
app:tabIndicatorHeight="10dp" />
The workaround here is
Using both tabBackground and tabIndicator
Indicator height equals to TabLayout height
tab_normal.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#aaaaaa" />
<corners android:radius="5dp" />
</shape>
tab_indicator.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ff0000" />
<corners android:radius="5dp" />
</shape>
If you need a padding between indicator, you can use layer-list drawable with some padding (instead of using shape)
If you just only need a color for tab indicator, no need to define shape drawable, can use
app:tabBackground="#color/gray"
app:tabIndicatorColor="#color/red"

Stroke not getting applied along with selector in Android

I have a layout.xml like the following
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/green"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginBottom="2dp" >
<ImageButton
android:id="#+id/leftArrowImageButton"
android:background="#drawable/left_arrow_selector"
android:layout_width="120dp"
android:layout_height="50dp"
android:gravity="left"
android:src="#drawable/left_arrow">
</ImageButton>
</LinearLayout>
I have left_arrow_selector.xml like the following
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/white" android:state_selected="true"/>
<item android:drawable="#color/white" android:state_pressed="true"/>
<item android:drawable="#color/green">
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="2dp" android:color="#color/grey" />
</shape>
</item>
</selector>
Everything else is working fine but the stroke is not getting applied.
Please advice on this.
EDIT - Added Image...
The Image is there which i want to keep it same but i want to add stroke to the view. Please see how i added a grey stroke if i removed the selector.
I'd do like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/arrow_left_white" android:state_selected="true"/>
<item android:drawable="#drawable/arrow_left_white" android:state_pressed="true"/>
<item android:drawable="#drawable/arrow_left_green" />
</selector>
and add:
/res/drawable/arrow_left_white.xml (just to preserve the name in the selector)
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#color/grey" />
<solid android:color="#color/azure">
</shape>
and
/res/drawable/arrow_left_green.xml (also just to preserve the name in the selector)
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#color/black" />
<solid android:color="#color/brown">
</shape>
So, setting the selector as your background and the image as your src, you'll have a stateful ImageButton that turns (with the colors I choosed) from beaing a yellow left triangle on an azure background and having a grey border to the same yellow triangle on a brown backgrounf with a black border.
stroke for the border
solid for the fill
Reference: http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape
You can add some spice by rounding the corners and/or using gradients.
The problem is here:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="2dp" android:color="#color/black" />
</shape>
try this instead:
<shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#color/black" />
</shape>
That happens when you copy&paste too much ^^

Include resource files in other resources

Use case:
If you have multiple buttons to design and you want to have different images in them and a background gradient.
what I have now
ImageButton with background the following:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" >
<layer-list>
<item>
<shape android:shape="rectangle">
<gradient
android:type="linear"
android:startColor="#color/green_yellow"
android:endColor="#color/green_mantis" />
</shape>
</item>
<item>
<bitmap
android:antialias="true"
android:gravity="center"
android:src="#drawable/more_button_check_rates_img"/>
</item>
</layer-list>
</item>
</selector>
This is working, but now i want another one with a other bitmap.
Question
Can i create three files (1 shape and two buttons) and then include the shape into the two buttons.
something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" >
<layer-list>
<include shape="background"> <!-- this line -->
<item>
<bitmap
android:antialias="true"
android:gravity="center"
android:src="#drawable/more_button_check_rates_img"/>
</item>
</layer-list>
</item>
</selector>
yes you have to create multiple xml for multiple background button and just set that xml on those button.:)

Categories

Resources