I need to do a custom tab indicator for my tab layout. It will be linked to a ViewPager with a TabLayoutMediator. The layout that I need is this:
And I am currently getting this:
Anyone knows why? You can see my XML code below.
Layout where TabLayout is:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:background="#color/whiteCandy"
android:fitsSystemWindows="true">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/onBoardingViewPager"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_0"
android:layout_marginStart="#dimen/tablet_default_margin"
android:layout_marginTop="#dimen/dimen_40"
android:layout_marginEnd="#dimen/tablet_default_margin"
android:layout_marginBottom="#dimen/dimen_75"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabDots"
android:layout_width="wrap_content"
android:layout_height="#dimen/dimen_6"
android:layout_marginStart="#dimen/dimen_30"
android:layout_marginBottom="#dimen/dimen_75"
android:background="#android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#id/onBoardingViewPager"
app:tabBackground="#drawable/tab_selector"
app:tabIndicatorHeight="#dimen/dimen_0"
app:tabPaddingEnd="#dimen/dimen_6" />
</androidx.constraintlayout.widget.ConstraintLayout>
Tab Selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/selected_dot" android:state_selected="true" />
<item android:drawable="#drawable/default_dot" />
</selector>
Selected state drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="#dimen/dimen_3"/>
<solid android:color="#FFFF0000"/>
<size android:height="#dimen/dimen_6" android:width="#dimen/dimen_20"/>
</shape>
Unselected state drawable:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="#dimen/dimen_0"
android:shape="ring"
android:thickness="#dimen/dimen_6"
android:useLevel="false">
<solid android:color="#80FF0000" />
</shape>
</item>
</layer-list>
for unselected:
<shape android:shape="oval">
<solid android:color="#80FF0000" />
<size
android:width="4dp"
android:height="4dp" />
</shape>
Related
I want to set following xml shape as my linear layout background:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke
android:width="2dp"
android:color="#D50000">
</stroke>
<solid
android:color="#android:color/transparent">
</solid>
</shape>
And I also want to show the press effect by these lines of code:
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:background="?android:selectableItemBackground"
But as you know, it is impossible to have two background for a view. So, What is the solution?
Try this:
<LinearLayout
android:layout_margin="16dp"
app:layout_constraintTop_toTopOf="parent"
android:background="#drawable/ll_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:onClick="doSomething"
android:padding="8dp"
android:weightSum="3">
<TextView
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Greeting" />
<TextView
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
Then in drawable/ folder add:
button_normal.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke
android:width="2dp"
android:color="#D50000">
</stroke>
</shape>
button_pressed.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid
android:color="#D50000">
</solid>
<stroke android:color="#D50000" android:width="2dp"/>
</shape>
Then create ll_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/button_pressed"/>
<item android:drawable="#drawable/button_normal"/>
</selector>
Finally for ripple create drawable-v21 folder and add ll_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#D50000">
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
<stroke
android:color="#D50000"
android:width="1dp" />
</shape>
</item>
</ripple>
The first three files (button_normal.xml, button_pressed.xml & ll_background.xml) will be for api < 21 and the 4th (ll_background.xml) ripple will be on all other devices including api 21 and above.
I want to show a tabindicator as in the image below.
I am using viewpager. I already tried TabLayout with viewpager, in which we can only adjust tab indicator color and height. How can I implement this.
when seleted 'tab_selected.xml'
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="ring"
android:useLevel="false"
android:thickness="4dp"
android:innerRadius="0dp">
<solid android:color="#000"/>
</shape>
</item>
</selector>
when not selected 'tab_unselected'
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="ring"
android:useLevel="false"
android:thickness="4dp"
android:innerRadius="0dp">
<solid android:color="#3b000000"/>
</shape>
</item>
</selector>
now when state_presses is true or not 'tab'
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/tab_selected"
android:state_selected="true"/>
<item android:drawable="#drawable/tab_unseleted"/>
</selector>
now in tablayout
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tablayout"
android:layout_alignParentBottom="true"
app:tabIndicatorHeight="0dp"
app:tabGravity="center"
app:tabBackground="#drawable/tab"/>
Keep it simple and just use one XML file.
tab_indicator_circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:useLevel="false">
<size
android:width="4dp"
android:height="4dp" />
<solid android:color="#color/colorAccent" />
</shape>
Usage:
<com.google.android.material.tabs.TabLayout
android:id="#+id/myTabLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:tabIndicator="#drawable/tab_indicator_circle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabIndicatorHeight="10dp"
app:tabGravity="center" />
Note that I'm using TabLayout from
implementation "com.google.android.material:material:1.1.0-alpha10"
Here's how I achieved it
tab_indicator.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="8dp"
android:height="8dp"
android:bottom="16dp"
android:end="8dp"
android:gravity="center"
android:start="8dp"
android:top="8dp">
<shape android:shape="rectangle">
<size android:width="8dp" android:height="8dp" />
<corners android:radius="4dp" />
<solid android:color="?attr/colorAccent" />
</shape>
</item>
</layer-list>
Important thing is to have fixed width and height.
Usage:
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorHeight="8dp"
app:tabIndicator="#drawable/tab_indicator" />
i have implemented viewpager for image slider with tablayouts as indicator but it seems that i can't make any padding between the dots ,this the layout for pager
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="220dp"
android:layout_below="#id/PlacesPageBanner">
<android.support.v4.view.ViewPager
android:id="#+id/placesPager"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_margin="10dp" />
<android.support.design.widget.TabLayout
android:id="#+id/tabDots"
android:layout_width="match_parent"
android:layout_height="7dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
app:tabBackground="#drawable/tab_selector"
app:tabIndicatorHeight="0dp"
app:tabMaxWidth="7dp" />
</RelativeLayout>
code for layout containing the dots(tab_selector)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/tab_indicator_selected"
android:state_selected="true"/>
<item android:drawable="#drawable/tab_indicator_default"/>
I think the issue is in your #drawable/tab_indicator_selected and #drawable/tab_indicator_default. Providing the xml code for those would be helpful to find your issue.
Here's how I did it:
Tab indicator selected
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="8dp"
android:useLevel="false">
<solid android:color="#color/colorAccent"/>
</shape>
</item>
</layer-list>
Tab indicator default
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="5dp"
android:useLevel="false">
<solid android:color="#android:color/darker_gray"/>
</shape>
</item>
I try to create half circle background, in development IDE preview it works, but when I launch in emulator it doesn't work.
Here is my shape code :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:height="50dp">
<shape>
<solid android:color="#color/colorAccentDark" />
</shape>
</item>
<item android:top="-500dp" android:bottom="0dp" android:left="-100dp" android:right="-100dp">
<shape>
<corners android:radius="500dp" />
<solid android:color="#color/colorAccentDark" />
</shape>
</item>
</layer-list>
And here is my layout code :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_profile"
android:layout_weight="1">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profile_avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/ic_default_avatar"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"/>
<TextView
android:id="#+id/profile_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#id/profile_avatar"
android:layout_marginTop="20dp"
android:textColor="#color/neutralWhite"
android:textStyle="bold"
android:textSize="18sp"
android:text="Avatar Ang"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4.04">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello Android!"/>
</RelativeLayout>
</LinearLayout>
Maybe any other tweak to handle that?
Thank you
you can try this :
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#900021df"/>
<size
android:width="10dp"
android:height="5dp"/>
<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="20dp"/>
</shape>
it gives this shape:
curve_toolbar_bg.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:bottom="0dp"
android:left="-100dp"
android:right="-100dp"
android:top="-80dp">
<shape android:shape="oval">
<solid android:color="#color/colorPrimary" />
</shape>
</item>
</layer-list>
activity_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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="?android:attr/actionBarSize"
android:background="#drawable/rounded_corner"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
</android.support.v7.widget.Toolbar>
</android.support.constraint.ConstraintLayout>
You cannot create a semicircle from xml. but you could achieve what you are looking for using a circle with appropriate margin & padding.
You can use a circle shape .xml file.
Create a fixed sized circle like this:
Example:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false" >
<solid android:color="#006AC5" />
<size
android:height="50dp"
android:width="50dp" />
</shape>
Try this. Remove the gradient part then it will look like same as you want.
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#00B0EA" />
</shape>
</item>
<item
android:bottom="400dp"
android:left="-100dp"
android:right="-100dp"
android:top="-200dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<gradient
android:angle="90"
android:endColor="#65FFFFFF"
android:startColor="#65FFFFFF" />
</shape>
</item>
<item
android:bottom="402dp"
android:left="-100dp"
android:right="-100dp"
android:top="-280dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FFFFFF" />
</shape>
</item>
Background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
</shape>
</item>
<item
android:bottom="410dp"
android:left="-100dp"
android:right="-100dp"
android:top="-300dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#7181A1" />
</shape>
</item>
</layer-list>
Output like
You can try to use ShapeOfView.
<io.github.florent37.shapeofview.shapes.ArcView
android:layout_width="match_parent"
android:layout_height="300dp"
android:elevation="4dp"
app:shape_arc_height="20dp"
app:shape_arc_position="bottom">
<!-- YOUR CONTENT -->
</io.github.florent37.shapeofview.shapes.ArcView>
Image result
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"