Changing CardView shadow color - android

This question was asked on SO many times, but still I didn't find a good solution for this problem.
Why do I need this to do? Well because project me and my team develops has iOS style.
What did I try?
9.pathch shadow generator but 9.pathes are essentially pngs and it gives me no flexibility and if I'll use this approach I should edit margins everywhere.
Carbon library it supports custom shadows and they get drawn outside of view borders, but there is issue regarding rounded rectangles, when library doesn't draw shadow for rounded corners.
using old CardView implementation and overriding its shadow color, but it gets drawn inside of card bounds, so it isn't option.
So is there a way to change shadow color of CardView with minimum edits of all layout files and with drawing shadow outside of the view like original CardView does?

Consider this thread in twitter, where Nick Butcher talks about how to implement the feature:
See outlineAmbientShadowColor, outlineSpotShadowColor, spotShadowAlpha and ambientShadowAlpha attributes for details. Unfortunately, that's possible from API 28 onwards.
For lower APIs Nick has shared a gist. Here's the result:
Running on API 21
This technique isn't directly connected to CardView, it can be applied to any View.

You Can Implement this without having a cardview, and can also have all the properties of cardview
You have to Do:
Copy the two classes
Wrap your required view with the Custom View as in the example, you don't have to do much changes in your layout or anywhere else!
The below class will create a custom view, this will be wrapping your layout/View to be displayed in cardview with custom shadow color
Create a class:
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.LinearLayout;
import com.qzion.nfscrew.R;
public class RoundLinerLayoutNormal extends LinearLayout {
public RoundLinerLayoutNormal(Context context) {
super(context);
initBackground();
}
public RoundLinerLayoutNormal(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
initBackground();
}
public RoundLinerLayoutNormal(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initBackground();
}
private void initBackground() {
setBackground(ViewUtils.generateBackgroundWithShadow(this,R.color.white,
R.dimen.radius_corner,R.color.colorPrimaryDark,R.dimen.elevation, Gravity.BOTTOM));
}
}
Also create the class for the Shadow Settings, ViewUtils.java
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.v4.content.ContextCompat;
import android.view.Gravity;
import android.view.View;
import static android.support.v4.view.ViewCompat.LAYER_TYPE_SOFTWARE;
public class ViewUtils {
public static Drawable generateBackgroundWithShadow(View view, #ColorRes int backgroundColor,
#DimenRes int cornerRadius,
#ColorRes int shadowColor,
#DimenRes int elevation,
int shadowGravity) {
float cornerRadiusValue = view.getContext().getResources().getDimension(cornerRadius);
int elevationValue = (int) view.getContext().getResources().getDimension(elevation);
int shadowColorValue = ContextCompat.getColor(view.getContext(),shadowColor);
int backgroundColorValue = ContextCompat.getColor(view.getContext(),backgroundColor);
float[] outerRadius = {cornerRadiusValue, cornerRadiusValue, cornerRadiusValue,
cornerRadiusValue, cornerRadiusValue, cornerRadiusValue, cornerRadiusValue,
cornerRadiusValue};
Paint backgroundPaint = new Paint();
backgroundPaint.setStyle(Paint.Style.FILL);
backgroundPaint.setShadowLayer(cornerRadiusValue, 0, 0, 0);
Rect shapeDrawablePadding = new Rect();
shapeDrawablePadding.left = elevationValue;
shapeDrawablePadding.right = elevationValue;
int DY;
switch (shadowGravity) {
case Gravity.CENTER:
shapeDrawablePadding.top = elevationValue;
shapeDrawablePadding.bottom = elevationValue;
DY = 0;
break;
case Gravity.TOP:
shapeDrawablePadding.top = elevationValue*2;
shapeDrawablePadding.bottom = elevationValue;
DY = -1*elevationValue/3;
break;
default:
case Gravity.BOTTOM:
shapeDrawablePadding.top = elevationValue;
shapeDrawablePadding.bottom = elevationValue*2;
DY = elevationValue/3;
break;
}
ShapeDrawable shapeDrawable = new ShapeDrawable();
shapeDrawable.setPadding(shapeDrawablePadding);
shapeDrawable.getPaint().setColor(backgroundColorValue);
shapeDrawable.getPaint().setShadowLayer(cornerRadiusValue/3, 0, DY, shadowColorValue);
view.setLayerType(LAYER_TYPE_SOFTWARE, shapeDrawable.getPaint());
shapeDrawable.setShape(new RoundRectShape(outerRadius, null, null));
LayerDrawable drawable = new LayerDrawable(new Drawable[]{shapeDrawable});
drawable.setLayerInset(0, elevationValue, elevationValue*2, elevationValue, elevationValue*2);
return drawable;
}
}
and finally your XML, where you have the views required to have shadow.
<com.qzion.nfscrew.utils.RoundLinerLayoutNormal
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This view will have shadow"/>
</com.qzion.nfscrew.utils.RoundLinerLayoutNormal>

Well I think of an easy solution without using a Java or Some Libraries. You should make a Drawable shape and put it in the drawable folder and then adjust the gradient to be like a shadow.
For example, in my solution I have added two colors:
<color name="yellow_middle">#ffee58</color>
<color name="yellow_end">#7ae7de83</color>
Then I made a file and put it in drawable folder drawable\card_view_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="10dp"
android:height="10dp" />
<corners android:radius="6dp" />
<stroke
android:width="2dp"
android:color="#color/yellow_end" />
<gradient
android:angle="-90"
android:centerColor="#color/yellow_middle"
android:endColor="#color/yellow_end"
android:startColor="#fff" />
</shape>
Then from there you need to wrap a your view(that would have been inside CardView) in a container like LinearLayout then apply as the background to the container that you want to be seen like a cardview. To solve it well add some padding (Thats your shadow) to the Container itself. For instance check mine:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context="com.xenolion.ritetrends.MainActivity">
<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:background="#drawable/card_view_shape"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="3dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:gravity="center"
android:text="I love StackOverflow"
android:textColor="#000"
android:textSize="18sp" />
</LinearLayout>
</FrameLayout>
Then the results looks like this:
Adjusting the bottom padding it will look like this:
COMMENT
Since I am not of an artist but if you play with it you may make the whole thing look exactly like CardView check some hints:
Putting multiple gradients in the shape
Adjust the end colors of gradients to appear more greyish
The end colours must also be a little transparent
Adjust your View's padding to appear like a shadow and coloured but greyish
The main View's background also matters to bring the reality
From there redesign the shape to look even more realistic like a CardView.

display shadow >= 28 or >= P for above Sdk level 28
use below code in your CardView
with xml
android:outlineAmbientShadowColor="<yourCoolor>"
android:outlineSpotShadowColor="<yourCoolor>"
with java and kt file
mCardView.setOutlineAmbientShadowColor(ContextCompat.getColor(getContext(), R.color.color_new_yellow));
mCardView.setOutlineSpotShadowColor(ContextCompat.getColor(getContext(), R.color.color_new_yellow));
display like this

Use Fake Shadow.
Well, it is not possible to change the color of the shadow of cardview before API 28 but we can add a custom shadow behind a layout. You need to use a drawable background (shadow.xml) in the parent layout which is looking like a shadow.
shadow.xml -
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#05FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#10FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#15FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#20FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#25FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
</layer-list>
Now use the following code -
<FrameLayout
android:layout_width="match_parent"
android:background="#drawable/shadow"
android:layout_height="200dp">
<CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="15dp"
app:cardElevation="0dp">
<!-- your code here -->
</CardView>
</FrameLayout>
You can replace FF46A9 in shadow.xml to change the color of shadow.
Also android:backgroundTint="#color/colorShadow" works but you have to adjust colors alpha in shadow.xml.
Adjust the <corners android:radius="15dp"/> as app:cardCornerRadius="15dp".

This trick is difficult to achieve in most cases , due Official Android Framework do not have any way to change the cardview shadow color.
In this case you refers to ilumination light on the cardview . This library is optimized for this this trick.
Library Link:https://github.com/meetsl/SCardView-master
I hope can help you!
Good Luck

enter image description hereI know I'm late but I want to share the solution as I searched hard for this issue and solved the issue The solution is, You have to use "ComplexView" to create your custom shadow,
dependency: implementation 'com.github.BluRe-CN:ComplexView:v1.1'
XML:
<com.blure.complexview.ComplexView
android:id="#+id/shadow_card_1"
android:layout_width="#dimen/_65sdp"
android:layout_height="#dimen/_65sdp"
android:layout_centerInParent="true"
app:radius="#dimen/_30sdp"
app:shadow="true"
app:shadowAlpha="250"
app:shadowSpread="2"/>
//this will create the circular shadow for my need you can reduce the radius
Custom View
val shadow = ComplexView(context)
val radii = floatArrayOf(100f, 100f, 100f, 100f, 100f, 100f, 100f, 100f)//customise according to your requirement
val opacity = 150//customise according to your requirement
shadow.shadow =Shadow(
2,
opacity,
"#96B9BB",
GradientDrawable.RECTANGLE,
radii,
Shadow.Position.CENTER
)
val param: RelativeLayout.LayoutParams =
RelativeLayout.LayoutParams(
context.resources.getDimension(R.dimen._160sdp).toInt(),
context.resources.getDimension(R.dimen._160sdp).toInt()
)
shadow.layoutParams = param
shadow.addView(yourCustomView)
here is the result:
also
thanks :)

Already late for the answer.
Some trick can work perfectly for me
And XML file like
<?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:gravity="center"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="#+id/cardview"
android:layout_width="#dimen/_150sdp"
android:layout_height="#dimen/_150sdp"
android:layout_marginLeft="#dimen/_10sdp"
android:layout_marginRight="#dimen/_10sdp"
app:cardBackgroundColor="#color/white"
app:cardCornerRadius="#dimen/_5sdp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="#dimen/_50sdp"
android:orientation="vertical">
</LinearLayout>
<View
android:id="#+id/view_color"
android:layout_width="match_parent"
android:layout_height="#dimen/_2sdp"
android:layout_gravity="bottom"
android:background="#color/app_green" />
</androidx.cardview.widget.CardView>
</LinearLayout>
Enjoy coding

Simple way to change card 's shadow color is to set android:outlineSpotShadowColor="#color/#CCCCCC" inside your CardView
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="15dp"
android:outlineAmbientShadowColor="#color/#CCCCCC"
android:outlineSpotShadowColor="#color/#CCCCCC" />

Related

Programatically change background of Drawable, maintaining the corner radius

interview_timeline_row.xml
<LinearLayout
android:id="#+id/interviewTimelineIconLayout"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_marginTop="20dp"
android:background="#drawable/timeline_row_icon_layout_bg"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/interviewTimelineRowIcon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:adjustViewBounds="false"
android:cropToPadding="false"
android:padding="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
timeline_row_icon_layout_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="#dimen/_50sdp" />
<stroke android:width="1dp" android:color="#color/white" />
<solid android:color="#color/ic_rescheduled"/> //need to add this programatically
</shape>
InterviewTimeline.java
iconBg = row.findViewById(R.id.interviewTimelineIconLayout);
iconBg.setBackgroundColor(getResources().getColor(R.color.ic_rescheduled)); //this is the wrong way to go about it
I want to use the timeline_row_icon_layout_bg.xml in various places in my app, and it should have a different background color each time. If I use the iconBg.setBackgroundColor() method, then it ignores the radius and I have a square background color.
Since you are just using the shape to create a layout with rounded corners and a border, the first option is to wrap your LinearLayout inside a CardView and then apply to the card the corner radius, the stroke and the background color.
Otherwise you could use the MaterialShapeDrawable included in the Material Components Library to draw custom shapes.
Just remove from the LinearLayout the android:background:
<LinearLayout
android:id="#+id/interviewTimelineIconLayout"
android:layout_width=".."
android:layout_height="..
..>
<!-- ..... -->
</LinearLayout>
Then in your code you can apply a ShapeAppearanceModel. Something like:
float radius = getResources().getDimension(R.dimen.corner_radius);
LinearLayout linearLayout= findViewById(R.id.interviewTimelineIconLayout);
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
.toBuilder()
.setAllCorners(CornerFamily.ROUNDED,radius)
.build();
MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
//Fill the LinearLayout with your color
shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,R.color.yourColor));
//Stroke color and width
shapeDrawable.setStrokeWidth(2.0f);
shapeDrawable.setStrokeColor(...);
ViewCompat.setBackground(linearLayout,shapeDrawable);
In this way you easily change and set the color background and the stroke.
Copy your "timeline_row_icon_layout_bg.xml" file and rename it "timeline_row_icon_layout_bg_new.xml"
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="#dimen/_50sdp" />
<stroke android:width="1dp" android:color="#color/white" />
<solid android:color="#color/put_the_color_you_need" />
</shape>
And you can set background to layout:
iconBg.setBackgroundResource(R.drawable.timeline_row_icon_layout_bg_new);
set the background of LinearLayout programmatically.
val bgDrawable = resources.getDrawable(R.drawable.timeline_row_icon_layout_bg, null).apply{
colorFilter = PorterDuffColorFilter(
ResourcesCompat.getColor(resources, R.color.ic_rescheduled, null),
PorterDuff.Mode.SRC_IN
)
}
iconBg.background = bgDrawable
move the shape drawable timeline_row_icon_layout_bg to the drawable resource folder.

Android draw/add graphical border around a view [duplicate]

Is it possible to draw a border around an Android TextView?
You can set a shape drawable (a rectangle) as background for the view.
<TextView android:text="Some text" android:background="#drawable/back"/>
And rectangle drawable back.xml (put into res/drawable folder):
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#android:color/white" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>
You can use #android:color/transparent for the solid color to have a transparent background.
You can also use padding to separate the text from the border.
for more information see: http://developer.android.com/guide/topics/resources/drawable-resource.html
Let me summarize a few different (non-programmatic) methods.
Using a shape drawable
Save the following as an XML file in your drawable folder (for example, my_border.xml):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- View background color -->
<solid
android:color="#color/background_color" >
</solid>
<!-- View border color and width -->
<stroke
android:width="1dp"
android:color="#color/border_color" >
</stroke>
<!-- The radius makes the corners rounded -->
<corners
android:radius="2dp" >
</corners>
</shape>
Then just set it as the background to your TextView:
<TextView
android:id="#+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/my_border" />
More help:
Shape Drawable (Android docs)
Android Developer Tips & Tricks: XML Drawables (Part I)
Using a 9-patch
A 9-patch is a stretchable background image. If you make an image with a border then it will give your TextView a border. All you need to do is make the image and then set it to the background in your TextView.
<TextView
android:id="#+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/my_ninepatch_image" />
Here are some links that will show how to make a 9-patch image:
Draw 9-patch
Simple Nine-patch Generator
A simple guide to 9-patch for Android UI
Creating & Using 9-patch images in Android
What if I just want the top border?
Using a layer-list
You can use a layer list to stack two rectangles on top of each other. By making the second rectangle just a little smaller than the first rectangle, you can make a border effect. The first (lower) rectangle is the border color and the second rectangle is the background color.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Lower rectangle (border color) -->
<item>
<shape android:shape="rectangle">
<solid android:color="#color/border_color" />
</shape>
</item>
<!-- Upper rectangle (background color) -->
<item android:top="2dp">
<shape android:shape="rectangle">
<solid android:color="#color/background_color" />
</shape>
</item>
</layer-list>
Setting android:top="2dp" offsets the top (makes it smaller) by 2dp. This allows the first (lower) rectangle to show through, giving a border effect. You can apply this to the TextView background the same way that the shape drawable was done above.
Here are some more links about layer lists:
Understanding Android's <layer-list>
How to make bottom border in drawable shape XML selector?
Create borders on a android view in drawable xml, on 3 sides?
Using a 9-patch
You can just make a 9-patch image with a single border. Everything else is the same as discussed above.
Using a View
This is kind of a trick but it works well if you need to add a seperator between two views or a border to a single TextView.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textview1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- This adds a border between the TextViews -->
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#android:color/black" />
<TextView
android:id="#+id/textview2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Here are some more links:
How to draw a line in Android
How to put a horizontal divisor line between edit text's in a activity
How to add a horizontal 1px line above image view in a relative layout?
The simple way is to add a view for your TextView. Example for the bottom border line:
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:text="#string/title"
android:id="#+id/title_label"
android:gravity="center_vertical"/>
<View
android:layout_width="fill_parent"
android:layout_height="0.2dp"
android:id="#+id/separator"
android:visibility="visible"
android:background="#android:color/darker_gray"/>
</LinearLayout>
For the other direction borders, please adjust the location of the separator view.
I have solved this issue by extending the textview and drawing a border manually.
I even added so you can select if a border is dotted or dashed.
public class BorderedTextView extends TextView {
private Paint paint = new Paint();
public static final int BORDER_TOP = 0x00000001;
public static final int BORDER_RIGHT = 0x00000002;
public static final int BORDER_BOTTOM = 0x00000004;
public static final int BORDER_LEFT = 0x00000008;
private Border[] borders;
public BorderedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public BorderedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BorderedTextView(Context context) {
super(context);
init();
}
private void init(){
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(4);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(borders == null) return;
for(Border border : borders){
paint.setColor(border.getColor());
paint.setStrokeWidth(border.getWidth());
if(border.getStyle() == BORDER_TOP){
canvas.drawLine(0, 0, getWidth(), 0, paint);
} else
if(border.getStyle() == BORDER_RIGHT){
canvas.drawLine(getWidth(), 0, getWidth(), getHeight(), paint);
} else
if(border.getStyle() == BORDER_BOTTOM){
canvas.drawLine(0, getHeight(), getWidth(), getHeight(), paint);
} else
if(border.getStyle() == BORDER_LEFT){
canvas.drawLine(0, 0, 0, getHeight(), paint);
}
}
}
public Border[] getBorders() {
return borders;
}
public void setBorders(Border[] borders) {
this.borders = borders;
}
}
And the border class:
public class Border {
private int orientation;
private int width;
private int color = Color.BLACK;
private int style;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getStyle() {
return style;
}
public void setStyle(int style) {
this.style = style;
}
public int getOrientation() {
return orientation;
}
public void setOrientation(int orientation) {
this.orientation = orientation;
}
public Border(int Style) {
this.style = Style;
}
}
Hope this helps someone :)
Simplest solution I've found (and which actually works):
<TextView
...
android:background="#android:drawable/editbox_background" />
You can set the border by two methods. One is by drawable and the second is programmatic.
Using Drawable
<shape>
<solid android:color="#color/txt_white"/>
<stroke android:width="1dip" android:color="#color/border_gray"/>
<corners android:bottomLeftRadius="10dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="10dp"
android:topRightRadius="0dp"/>
<padding android:bottom="0dip"
android:left="0dip"
android:right="0dip"
android:top="0dip"/>
</shape>
Programmatic
public static GradientDrawable backgroundWithoutBorder(int color) {
GradientDrawable gdDefault = new GradientDrawable();
gdDefault.setColor(color);
gdDefault.setCornerRadii(new float[] { radius, radius, 0, 0, 0, 0,
radius, radius });
return gdDefault;
}
I was just looking at a similar answer-- it's able to be done with a Stroke and the following override:
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
Paint strokePaint = new Paint();
strokePaint.setARGB(255, 0, 0, 0);
strokePaint.setTextAlign(Paint.Align.CENTER);
strokePaint.setTextSize(16);
strokePaint.setTypeface(Typeface.DEFAULT_BOLD);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(2);
Paint textPaint = new Paint();
textPaint.setARGB(255, 255, 255, 255);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTextSize(16);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
canvas.drawText("Some Text", 100, 100, strokePaint);
canvas.drawText("Some Text", 100, 100, textPaint);
super.draw(canvas, mapView, shadow);
}
With the Material Components Library you can use the MaterialShapeDrawable.
<TextView
android:id="#+id/textview"
.../>
Then you can programmatically apply a MaterialShapeDrawable:
TextView textView = findViewById(R.id.textview);
MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable();
shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,android.R.color.transparent));
shapeDrawable.setStroke(1.0f, ContextCompat.getColor(this,R.color....));
ViewCompat.setBackground(textView,shapeDrawable);
You can add something like this in your code:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>
I found a better way to put a border around a TextView.
Use a nine-patch image for the background. It's pretty simple, the SDK comes with a tool to make the 9-patch image, and it involves absolutely no coding.
The link is http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch.
Check the link below to make rounded corners
http://androidcookbook.com/Recipe.seam?recipeId=2318
The drawable folder, under res, in an Android project is not restricted to bitmaps (PNG or JPG files), but it can also hold shapes defined in XML files.
These shapes can then be reused in the project. A shape can be used to put a border around a layout. This example shows a rectangular border with curved corners. A new file called customborder.xml is created in the drawable folder (in Eclipse use the File menu and select New then File, with the drawable folder selected type in the file name and click Finish).
The XML defining the border shape is entered:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:radius="20dp"/>
<padding android:left="10dp" android:right="10dp" android:top="10dp" android:bottom="10dp"/>
<solid android:color="#CCCCCC"/>
</shape>
The attribute android:shape is set to rectangle (shape files also support oval, line, and ring). Rectangle is the default value, so this attribute could be left out if it is a rectangle being defined. See the Android documentation on shapes at http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape for detailed information on a shape file.
The element corners sets the rectangle corners to be rounded. It is possible to set a different radius on each corner (see the Android reference).
The padding attributes are used to move the contents of the View to which the shape is applied, to prevent the contents overlapping the
border.
The border color here is set to a light gray (CCCCCC hexadecimal RGB value).
Shapes also support gradients, but that is not being used here. Again, see the Android resources to see how a gradient is defined. The shape is applied to the laypout using android:background="#drawable/customborder".
Within the layout other views can be added as normal. In this example, a single TextView has been added, and the text is white (FFFFFF hexadecimal RGB). The background is set to blue, plus some transparency to reduce the brightness (A00000FF hexadecimal alpha RGB value). Finally the layout is offset from the screen edge by placing it into another layout with a small amount of padding. The full layout file is thus:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/customborder">
<TextView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Text View"
android:textSize="20dp"
android:textColor="#FFFFFF"
android:gravity="center_horizontal"
android:background="#A00000FF" />
</LinearLayout>
</LinearLayout>
I have a way to do it very simply, and I'd like to share it.
When I want to square mi TextViews, I just put them in a LinearLayout. I set the background color of my LinearLayout, and I add a margin to my TextView. The result is exactly as if you square the TextView.
You can set a shape drawable (a rectangle with corners) as background for the view.
<TextView android:background="#drawable/frame"/>
And rectangle drawable frame.xml (put into res/drawable folder):
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#android:color/white" />
<stroke android:width="1dip"
android:color="#3d4caf"/>
<corners android:radius="50dp"/>
</shape>
You can create custom background for your text view.
Steps
Go to your project.
Go to resources and right click to drawable.
Click on New -> Drawable Resource File
Give name to you file
Paste following code in the file
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1dp"
android:color="#color/colorBlack" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<corners android:radius="6dp" />
<solid android:color="#ffffffff" />
</shape>
For your text view where you want to use it as backgroud,
android:background="#drawable/your_fileName"
Changing Konstantin Burov answer because not work in my case:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
<stroke android:width="2dip" android:color="#4fa5d5"/>
<corners android:radius="7dp"/>
</shape>
</item>
</selector>
compileSdkVersion 26 (Android 8.0),
minSdkVersion 21 (Android 5.0),
targetSdkVersion 26,
implementation 'com.android.support:appcompat-v7:26.1.0',
gradle:4.1
Here is my 'simple' helper class which returns an ImageView with the border. Just drop this in your utils folder, and call it like this:
ImageView selectionBorder = BorderDrawer.generateBorderImageView(context, borderWidth, borderHeight, thickness, Color.Blue);
Here is the code.
/**
* Because creating a border is Rocket Science in Android.
*/
public class BorderDrawer
{
public static ImageView generateBorderImageView(Context context, int borderWidth, int borderHeight, int borderThickness, int color)
{
ImageView mask = new ImageView(context);
// Create the square to serve as the mask
Bitmap squareMask = Bitmap.createBitmap(borderWidth - (borderThickness*2), borderHeight - (borderThickness*2), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(squareMask);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
canvas.drawRect(0.0f, 0.0f, (float)borderWidth, (float)borderHeight, paint);
// Create the darkness bitmap
Bitmap solidColor = Bitmap.createBitmap(borderWidth, borderHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(solidColor);
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
canvas.drawRect(0.0f, 0.0f, borderWidth, borderHeight, paint);
// Create the masked version of the darknessView
Bitmap borderBitmap = Bitmap.createBitmap(borderWidth, borderHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(borderBitmap);
Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawBitmap(solidColor, 0, 0, null);
canvas.drawBitmap(squareMask, borderThickness, borderThickness, clearPaint);
clearPaint.setXfermode(null);
ImageView borderView = new ImageView(context);
borderView.setImageBitmap(borderBitmap);
return borderView;
}
}
There are a lot of ways to add a border to a textView. The simplest one is by creating a custom drawable and setting it as android:background="#drawable/textview_bg" for your textView.
The textview_bg.xml will go under Drawables and can be something like this.
You can have a solid or a gradient background (or nothing if not required), corners to add a corner radius and stroke to add border.
textview_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="#dimen/dp_10"/>
<gradient
android:angle="225"
android:endColor="#FFFFFF"
android:startColor="#E0E0E0" />
<stroke
android:width="2dp"
android:color="#000000"/>
</shape>
This may help you.
<RelativeLayout
android:id="#+id/textbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#android:color/darker_gray" >
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_margin="3dp"
android:background="#android:color/white"
android:gravity="center"
android:text="#string/app_name"
android:textSize="20dp" />
</RelativeLayout
Create a border view with the background color as the color of the border and size of your text view. set border view padding as the width of the border. Set text view background color as the color you want for the text view. Now add your text view inside the border view.
Try this:
<shape>
<solid android:color="#color/txt_white"/>
<stroke android:width="1dip" android:color="#color/border_black"/>
</shape>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#android:color/black" />
this code enough you can place wherever you want
setBackground on your xml textview,
add rounded_textview.xml file into your drawable directory.
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#android:color/white" />
<stroke android:width="2dip" android:color="#4f5g52"/>
</shape>
set drawable file in textView background.
Actually, it is very simple. If you want a simple black rectangle behind the Textview, just add android:background="#android:color/black" within the TextView tags. Like this:
<TextView
android:textSize="15pt" android:textColor="#ffa7ff04"
android:layout_alignBottom="#+id/webView1"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="#android:color/black"/>

How to add 1dp border (to an image) so that it works on all screens?

I'm looking for the simplest, reliable way to add a thin (1dp) border to an element—in this case ImageView— on API level 14+.
To my understanding, layer lists are the way to do this kind of stuff.
So, what I have:
<ImageView
android:id="#+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp"
android:background="#drawable/image_border"
/>
In Java, the ImageView is set to display this 200x200 px image (Wikimedia Commons).
And in res/drawable/image_border.xml:
<!-- Adds thin (1dp) border, and nothing else. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" >
<stroke android:width="1dp" android:color="#FF000000" />
<solid android:color="#android:color/transparent"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<padding android:top="1dp" />
<padding android:bottom="1dp" />
<padding android:left="1dp" />
<padding android:right="1dp" />
</shape>
</item>
</layer-list>
What it looks like on a test device (Galaxy Note, Android 4.1.2):
Left and bottom borders are missing.
What am I doing wrong? Is my layer list approach incorrect (or could it be simplified)? Or can this be achieved using something else than layer lists?
You can set background color for your ImageView and set padding to 1dp:
<ImageView
android:id="#+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp"
android:background="#F000"
android:padding="1dp"
/>
It will look like you want.
While this solution is simple and works great in general, it has one shortcoming in the case of images that are fetched over network (in a background thread). While the image is still loading, a big black square is shown, which is not necessarily what you want.
A colleague of mine pointed out that in such cases you could do this instead: add a FrameLayout "behind" the image for the border, and set the ImageView background to white (for example), like so:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:padding="1dp">
<ImageView
android:id="#+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp"
android:background="#android:color/white" />
</FrameLayout>
In our case, the in-progress look is much better this way:
Addendum: custom "bordered image" component
Actually, besides the 1dp border, we also wanted to animate showing the image (alpha 0 -> 1) after it had been loaded over network; something like:
imageView.setAlpha(0f);
imageView.animate().alpha(1f).setDuration(500).start();
For the animation to look good (in our app at least), the background should be white instead of black.
To support both the border and animation, I'd have to add another FrameLayout (with white background), between the image and the outer (border) FrameLayout. But the XML gets quite verbose, so we created a custom reusable component for this in Java: "BorderedImage".
package fi.company.product.ui.helpers;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.ImageView;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
/**
* Custom ImageView (technically custom FrameLayout) with black 1dp border,
* white background and support for alpha animation (white -> image)
*
* #author Jonik, https://stackoverflow.com/a/19818328/56285
*/
public class BorderedImage extends FrameLayout {
private ImageView imageView;
public BorderedImage(Context context) {
super(context);
init(context);
}
public BorderedImage(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public BorderedImage(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
// Outer FrameLayout for the black border
setBackgroundColor(getResources().getColor(android.R.color.black));
int padding1dp = (int) getResources().getDisplayMetrics().density
setPadding(padding1dp, padding1dp, padding1dp, padding1dp);
// Another FrameLayout for the white background
FrameLayout middleLayout = new FrameLayout(context);
middleLayout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
middleLayout.setBackgroundColor(getResources().getColor(android.R.color.white));
addView(middleLayout);
// The actual ImageView
imageView = new ImageView(context);
imageView.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
middleLayout.addView(imageView);
}
public ImageView getImageView() {
return imageView;
}
}
Of course, it would easy to further customise this helper: for example, pass border & background colours as constructor parameters.
Now, it's simple to use BorderedImage in XML:
<fi.company.product.ui.helpers.BorderedImage
android:id="#+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="1dp" >
<ImageView
android:id="#+id/overlay_main_character"
android:layout_height="72dp"
android:layout_width="72dp"
android:background="#drawable/image_border"
/>

How to make a round button?

I'm trying to make a round button, but I don't know how can I do it. I can make button with rounded corners, but how can I can round circle. It's not the same. Please, tell me, is it possible on Android? Thank you.
Create an xml file named roundedbutton.xml in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#eeffffff" />
<corners android:bottomRightRadius="8dp"
android:bottomLeftRadius="8dp"
android:topRightRadius="8dp"
android:topLeftRadius="8dp"/>
</shape>
Finally set that as background to your Button as android:background = "#drawable/roundedbutton"
If you want to make it completely rounded, alter the radius and settle for something that is ok for you.
If using Android Studio you can just use:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FFFFFF"/>
</shape>
this works fine for me, hope this helps someone.
Create a drawable/button_states.xml file containing:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<corners android:radius="1000dp" />
<solid android:color="#41ba7a" />
<stroke
android:width="2dip"
android:color="#03ae3c" />
<padding
android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp" />
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="1000dp" />
<solid android:color="#3AA76D" />
<stroke
android:width="2dip"
android:color="#03ae3c" />
<padding
android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp" />
</shape>
</item>
</selector>
Use it in button tag in any layout file
<Button
android:layout_width="220dp"
android:layout_height="220dp"
android:background="#drawable/button_states"
android:text="#string/btn_scan_qr"
android:id="#+id/btn_scan_qr"
android:textSize="15dp"
/>
Markushi's android circlebutton:
(This library is deprecated and no new development is taking place. Consider using a FAB instead.)
If you want a FAB looking circular button and you are using the official Material Component library you can easily do it like this:
<com.google.android.material.button.MaterialButton
style="#style/Widget.MaterialComponents.ExtendedFloatingActionButton"
app:cornerRadius="28dp"
android:layout_width="56dp"
android:layout_height="56dp"
android:text="1" />
Result:
If you change the size of the button, just be careful to use half of the button size as app:cornerRadius.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#ffffff"
/>
</shape>
Set that on your XML drawable resources, and simple use and image button with an round image, using your drawable as background.
<corners android:bottomRightRadius="180dip"
android:bottomLeftRadius="180dip"
android:topRightRadius="180dip"
android:topLeftRadius="180dip"/>
<solid android:color="#6E6E6E"/> <!-- this one is ths color of the Rounded Button -->
and add this to the button code
android:layout_width="50dp"
android:layout_height="50dp"
Used the shape as oval. This makes the button oval
<item>
<shape android:shape="oval" >
<stroke
android:height="1.0dip"
android:width="1.0dip"
android:color="#ffee82ee" />
<solid android:color="#ffee82ee" />
<corners
android:bottomLeftRadius="12.0dip"
android:bottomRightRadius="12.0dip"
android:radius="12.0dip"
android:topLeftRadius="12.0dip"
android:topRightRadius="12.0dip" />
</shape>
</item>
You can use a MaterialButton:
<com.google.android.material.button.MaterialButton
android:layout_width="48dp"
android:layout_height="48dp"
android:insetTop="0dp"
android:insetBottom="0dp"
android:text="A"
app:shapeAppearanceOverlay="#style/ShapeAppearanceOverlay.App.Rounded"
/>
and apply a circular ShapeAppearanceOverlay with:
<style name="ShapeAppearanceOverlay.App.rounded" parent="">
<item name="cornerSize">50%</item>
</style>
Round button in Android
You can make a ImageButton with circular background image.
use ImageButton instead of Button....
and make Round image with transparent background
For a round button create a shape:
<?xml version="1.0" encoding="utf-8"?>
<stroke
android:width="8dp"
android:color="#FFFFFF" />
<solid android:color="#ffee82ee" />
<corners
android:bottomLeftRadius="45dp"
android:bottomRightRadius="45dp"
android:topLeftRadius="45dp"
android:topRightRadius="45dp" />
use it as a background of your button link
Update 2021:
Just use the MaterialButton
<com.google.android.material.button.MaterialButton
app:cornerRadius="30dp"
android:layout_width="60dp"
android:layout_height="60dp"
android:text="test" />
width equal height
cornerRadius is half of the width or height
Yes it's possible, look for 9-patch on google. Good articles :
http://radleymarx.com/blog/simple-guide-to-9-patch/
http://ogrelab.ikratko.com/custom-color-buttons-for-android/
You can use google's FloatingActionButton
XMl:
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/ic_dialog_email" />
Java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton bold = (FloatingActionButton) findViewById(R.id.fab);
bold.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do Stuff
}
});
}
Gradle:
compile 'com.android.support:design:23.4.0'
I simply use a FloatingActionButton with elevation = 0dp to remove the shadow:
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_send"
app:elevation="0dp" />
I like this solution
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="18dp"
app:cardElevation="0dp"
>
<ImageButton
android:layout_width="35dp"
android:layout_height="35dp"
android:background="#null"
android:scaleType="centerCrop"
android:src="#drawable/social_facebook"
/>
</androidx.cardview.widget.CardView>
It is
android.R.drawable.expander_ic_minimized
look into built in android drawables:
http://androiddrawableexplorer.appspot.com/
Use the Image Buttons and make the background as the image you want.
Create the images from the android asset studio link -
" https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html#foreground.type=image&foreground.space.trim=0&foreground.space.pad=0.25&foreColor=rgba(94%2C%20126%2C%20142%2C%200)&backColor=rgb(96%2C%20125%2C%20139)&crop=1&backgroundShape=circle&effects=none&name=ic_home "
and download it, extraxt it , inside that look for mipmap-hdpi folder.
copy the image from the mipmap-hdpi folder and paste it in the drwable folder of your android project.
Now set the background as that image.
I went through all the answers. But none of them is beginner friendly. So here I have given a very detailed answers fully explained with pictures.
Open Android Studio. Go to Project Window and scroll to drawable folder under res folder
Right click, select New --> drawable resource folder
In the window that appears, name the file rounded_corners and click on OK
A new file rounded_corners.xml gets created
Open the file. You are presented with the following code -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://android.com/apk/res/android">
</selector>
Replace it with the following code -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="8dp" />
<solid android:color="#66b3ff" />
</shape>
Here the design view can be seen on the right side
Adjust the value in android:radius to make the button more or less rounded.
Then go to activity_main.xml
Put the following code -->
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:padding="10dp">
<Button
android:id="#+id/_1"
android:text="1"
android:textSize="25dp"
android:textColor="#ffffff"
android:background="#drawable/rounded_corners"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
</RelativeLayout>
Here I have placed the Button inside a RelativeLayout. You can use any Layout you want.
For reference purpose MainActivity.java code is as follows -->
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
I have a Pixel 4 API 30 avd installed.
After running the code in the avd the display is as follows -->
Fully rounded circle shape.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#F0F0F0" />
<corners
android:radius="90dp"/>
</shape>
Happy Coding!
In case someone needs a floating action button, but doesn't want to depend on the entire material library, here's a minimal implementation that looks exactly the same, has ripple animation, the shadow, and show()/hide() methods with animation.
Widget code:
class CircularImageButton #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) : AppCompatImageButton(context, attrs) {
init {
background = null
outlineProvider = pillOutlineProvider
clipToOutline = true
}
fun show() {
if (visibility != VISIBLE) {
visibility = VISIBLE
startAnimation(showAnimation)
}
}
fun hide() {
if (visibility != INVISIBLE) {
visibility = INVISIBLE
startAnimation(hideAnimation)
}
}
override fun setBackgroundColor(color: Int) {
if (backgroundPaint.color != color) {
backgroundPaint.color = color
invalidate()
}
}
private val backgroundPaint = Paint().apply { style = Paint.Style.FILL }
override fun onDraw(canvas: Canvas?) {
canvas?.drawPaint(backgroundPaint)
super.onDraw(canvas)
}
}
val pillOutlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(0, 0, view.width, view.height, view.height.f / 2)
}
}
private val animationDuration = applicationContext
.resources.getInteger(android.R.integer.config_shortAnimTime).toLong()
val showAnimation = ScaleAnimation(
0f, 1f, 0f, 1f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f)
.apply { duration = animationDuration }
val hideAnimation = ScaleAnimation(
1f, .5f, 1f, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f)
.apply { duration = animationDuration }
And the xml, where 40dp is the “mini” version of the FAB.
<CircularImageButton
android:id="#+id/fab"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="#drawable/ic_your_drawable"
android:scaleType="center"
android:layout_margin="12dp"
android:elevation="3dp"
android:outlineAmbientShadowColor="#7000"
android:outlineSpotShadowColor="#7000"
android:foreground="?attr/selectableItemBackgroundBorderless" />
With jetpack compose, you can customize your button without requiring any 3-party lib or boilerplate code.
Button(
onClick = { /* do something when button clicked*/ },
modifier = Modifier
.width(64.dp)
.height(64.dp),
shape = CircleShape
) {
Icon(Icons.Default.Star, "")
}

How to create a drawable that's square on the outside and has rounded corners inside?

I'm trying to create rounded corners on a MapView, and since there doesn't seem to be any way to do it by default, I'm basically overlaying a layout with a background over my map view, like so:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" >
<RelativeLayout
android:id="#+id/map_holder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#drawable/panel_rounded_corner_transparent" />
</RelativeLayout>
My rounded corner drawable is defined like this:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/bg_rounded_corner_transparent" />
</selector>
and the drawable inside is defined as:
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid
android:color="#color/transparent" />
<stroke
android:width="1dp"
android:color="#color/darkgray" />
<corners
android:radius="5dp" />
</shape>
</item>
</layer-list>
However, the problem is that since the map ends up rectangular and the border is rounded, the corners of the map peek out from behind the corners of my makeshift border. How do I set a background color for only the outside of my border, while keeping the inside of the panel transparent?
To clarify, here are some screenshots.
This screenshot shows the map as originally "bounded" by the overlaid border:
This screenshot replaces the map with a red background, for greater clarity in seeing what the problem is:
As you can see, the red (and by extension, the map) bleeds outside the border.
I can add a 1dp padding to the map, but that doesn't entirely solve the issue as you can see here:
Since the corners are rounded, part of the map still leaks out. It's a lot better than the first option, but not perfect--there are 1 pixel dots at the corners.
As this screenshot shows, a padding of more than 1dp is not a solution since it creates another problem entirely:
Try extending the MapView like the following:
private class MyMapView extends MapView {
public MyMapView(Context context, String apiKey) {
super(context, apiKey);
}
#Override
public void draw(Canvas canvas) {
Path path = new Path();
RectF r = new RectF(0, 0, this.getWidth(), this.getHeight());
path.addRoundRect(r, 12, 12, Path.Direction.CW);
canvas.clipPath(path);
super.draw(canvas);
}
}
You might need to adjust the radius for path.addRoundRect()
Have you tried using the styleable elements? Take a look at this:
http://developer.android.com/reference/android/R.styleable.html#DrawableCorners_bottomLeftRadius
Hope this helps, this should solve your problem :)
hi there i play around for a few hours with this and here is my solution for a ImageView with transparent frame (oval) inside and solid color outside. I know it is a oval shape but it also works with rect.
Implement a FrameLayout with two children inside. So the shape will overlapping the ImageView:
<FrameLayout
android:id="#+id/testLinearLayout"
android:layout_width="300dp"
android:layout_height="300dp">
<ImageView
android:id="#+id/mainContentImage"
android:layout_width="300dp"
android:layout_height="300dp"/>
<LinearLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#drawable/shape_circle">
</LinearLayout>
</FrameLayout>
here is the shape_circle.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/shape_circle_rect"/>
<item android:drawable="#drawable/shape_circle_oval"/>
</layer-list>
shape_circle_rect.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<padding
android:left="-70dp"
android:top="-70dp"
android:right="-70dp"
android:bottom="-70dp"/>
</shape>
shape_circle_oval.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<stroke android:color="#ffffff" android:width="70dp"/>
</shape>
its not exactly what you searching for but it could help.
hope this is woking........read abount styles and other part of developers
may help you
http://developer.android.com/reference/android/R.style.html

Categories

Resources