角の丸いレイアウトを作成する方法丸みを帯びた角をLinearLayout
に適用したいです。
1:drawablesに layout_bg.xml を定義します。
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
<solid Android:color="#FFFFFF"/>
<stroke Android:width="3dp" Android:color="#B1BCBE" />
<corners Android:radius="10dp"/>
<padding Android:left="0dp" Android:top="0dp" Android:right="0dp" Android:bottom="0dp" />
</shape>
2:レイアウトの背景としてlayout_bg.xml
を追加する
Android:background="@drawable/layout_bg"
API 21以降の場合、クリップビューを使用
丸いアウトラインクリッピングは、API 21のView
クラスに追加されました。詳細については、this training doc またはthis reference を参照してください。
この内蔵機能により、角の丸い角を簡単に実装できます。あらゆるビューやレイアウトで機能し、適切なクリッピングをサポートします。
ここにすべきことは:
Android:background="@drawable/round_outline"
Android:clipToOutline="true"
残念ながら、 バグ のようであり、そしてこのXML属性は現在認識されていません。幸運にも、Javaでクリッピングを設定することができます。
View.setClipToOutline(true)
外観は次のとおりです。
ImageViewに関する特記事項
setClipToOutline()
は、ビューの背景がシェイプ描画可能に設定されている場合にのみ機能します。この背景形状が存在する場合、Viewは背景の輪郭をクリッピングおよびシャドウイングの目的で境界として扱います。
つまり、ImageViewの隅をsetClipToOutline()
で丸めたい場合は、画像はAndroid:src
ではなくAndroid:background
から来る必要があります(丸みを帯びた形状に背景が使用されるため)。 srcの代わりに背景を使用して画像を設定する必要がある場合は、このネストされたビューの回避策を使用できます。
これは、白い背景、黒い枠線、角の丸いドロウアブルを作成するためのXMLファイルのコピーです。
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
<solid Android:color="#ffffffff"/>
<stroke Android:width="3dp"
Android:color="#ff000000"
/>
<padding Android:left="1dp"
Android:top="1dp"
Android:right="1dp"
Android:bottom="1dp"
/>
<corners Android:bottomRightRadius="7dp" Android:bottomLeftRadius="7dp"
Android:topLeftRadius="7dp" Android:topRightRadius="7dp"/>
</shape>
描画可能なディレクトリにxmlファイルとして保存します。リソース名(R.drawable.your_xml_name)を使用して描画可能な背景(アイコンまたはリソースファイル)を使用するのと同じように使用します。
私はこのようにしました:
スクリーンショットをチェックする:
drawable フォルダーにcustom_rectangle.xml
という名前の drawable ファイルを作成します。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle" >
<solid Android:color="@Android:color/white" />
<corners Android:radius="10dip" />
<stroke
Android:width="1dp"
Android:color="@Android:color/white" />
</shape>
長方形の背景 on 表示 を適用します。
mView.setBackground(R.drawlable.custom_rectangle);
完了
Android v7サポートライブラリのCardViewを使用してください。それは少し重いですが、それはすべての問題を解決し、そして十分に簡単です。 set drawable backgroundメソッドとは異なり、サブビューを正常に切り取ることができます。
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:card_view="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
card_view:cardBackgroundColor="@Android:color/transparent"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="0dp"
card_view:contentPadding="0dp">
<YOUR_LINEARLAYOUT_HERE>
</Android.support.v7.widget.CardView>
私はそれを行うためのより良い方法は2つのことをマージすることだと思います:
これは、コーナーを持つコンテンツを持つなど、他のソリューションでは解決できなかったケースを処理します。
2ではなく単層で表示されるので、もう少しGPUにやさしいと思います。
唯一の良い方法は、完全にカスタマイズされたビューを作成することですが、それは多くのコードであり、時間がかかるかもしれません。私がここで提案したのは両方の長所の中で一番だと思います。
これがどのように行われることができるかの抜粋です:
RoundedCornersDrawable.Java
/**
* shows a bitmap as if it had rounded corners. based on :
* http://rahulswackyworld.blogspot.co.il/2013/04/Android-drawables-with-rounded_7.html
* easy alternative from support library: RoundedBitmapDrawableFactory.create( ...) ;
*/
public class RoundedCornersDrawable extends BitmapDrawable {
private final BitmapShader bitmapShader;
private final Paint p;
private final RectF rect;
private final float borderRadius;
public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float borderRadius) {
super(resources, bitmap);
bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
final Bitmap b = getBitmap();
p = getPaint();
p.setAntiAlias(true);
p.setShader(bitmapShader);
final int w = b.getWidth(), h = b.getHeight();
rect = new RectF(0, 0, w, h);
this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius;
}
@Override
public void draw(final Canvas canvas) {
canvas.drawRoundRect(rect, borderRadius, borderRadius, p);
}
}
CustomView.Java
public class CustomView extends ImageView {
private View mMainContainer;
private boolean mIsDirty=false;
// TODO for each change of views/content, set mIsDirty to true and call invalidate
@Override
protected void onDraw(final Canvas canvas) {
if (mIsDirty) {
mIsDirty = false;
drawContent();
return;
}
super.onDraw(canvas);
}
/**
* draws the view's content to a bitmap. code based on :
* http://nadavfima.com/Android-snippet-inflate-a-layout-draw-to-a-bitmap/
*/
public static Bitmap drawToBitmap(final View viewToDrawFrom, final int width, final int height) {
// Create a new bitmap and a new canvas using that bitmap
final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bmp);
viewToDrawFrom.setDrawingCacheEnabled(true);
// Supply measurements
viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
// Apply the measures so the layout would resize before drawing.
viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(), viewToDrawFrom.getMeasuredHeight());
// and now the bmp object will actually contain the requested layout
canvas.drawBitmap(viewToDrawFrom.getDrawingCache(), 0, 0, new Paint());
return bmp;
}
private void drawContent() {
if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0)
return;
final Bitmap bitmap = drawToBitmap(mMainContainer, getMeasuredWidth(), getMeasuredHeight());
final RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(), bitmap, 15);
setImageDrawable(drawable);
}
}
編集: "RoundKornersLayouts"ライブラリ に基づいて、ニースの代替を見つけました。丸めて、拡張したいすべてのレイアウトクラスに使用されるクラスを用意します。
//based on https://github.com/JcMinarro/RoundKornerLayouts
class CanvasRounder(cornerRadius: Float, cornerStrokeColor: Int = 0, cornerStrokeWidth: Float = 0F) {
private val path = Android.graphics.Path()
private lateinit var rectF: RectF
private var strokePaint: Paint?
var cornerRadius: Float = cornerRadius
set(value) {
field = value
resetPath()
}
init {
if (cornerStrokeWidth <= 0)
strokePaint = null
else {
strokePaint = Paint()
strokePaint!!.style = Paint.Style.STROKE
strokePaint!!.isAntiAlias = true
strokePaint!!.color = cornerStrokeColor
strokePaint!!.strokeWidth = cornerStrokeWidth
}
}
fun round(canvas: Canvas, drawFunction: (Canvas) -> Unit) {
val save = canvas.save()
canvas.clipPath(path)
drawFunction(canvas)
if (strokePaint != null)
canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, strokePaint)
canvas.restoreToCount(save)
}
fun updateSize(currentWidth: Int, currentHeight: Int) {
rectF = Android.graphics.RectF(0f, 0f, currentWidth.toFloat(), currentHeight.toFloat())
resetPath()
}
private fun resetPath() {
path.reset()
path.addRoundRect(rectF, cornerRadius, cornerRadius, Path.Direction.CW)
path.close()
}
}
次に、カスタマイズした各レイアウトクラスに、次のようなコードを追加します。
class RoundedConstraintLayout : ConstraintLayout {
private lateinit var canvasRounder: CanvasRounder
constructor(context: Context) : super(context) {
init(context, null, 0)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init(context, attrs, 0)
}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
init(context, attrs, defStyle)
}
private fun init(context: Context, attrs: AttributeSet?, defStyle: Int) {
val array = context.obtainStyledAttributes(attrs, R.styleable.RoundedCornersView, 0, 0)
val cornerRadius = array.getDimension(R.styleable.RoundedCornersView_corner_radius, 0f)
val cornerStrokeColor = array.getColor(R.styleable.RoundedCornersView_corner_stroke_color, 0)
val cornerStrokeWidth = array.getDimension(R.styleable.RoundedCornersView_corner_stroke_width, 0f)
array.recycle()
canvasRounder = CanvasRounder(cornerRadius,cornerStrokeColor,cornerStrokeWidth)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
setLayerType(FrameLayout.LAYER_TYPE_SOFTWARE, null)
}
}
override fun onSizeChanged(currentWidth: Int, currentHeight: Int, oldWidth: Int, oldheight: Int) {
super.onSizeChanged(currentWidth, currentHeight, oldWidth, oldheight)
canvasRounder.updateSize(currentWidth, currentHeight)
}
override fun draw(canvas: Canvas) = canvasRounder.round(canvas) { super.draw(canvas) }
override fun dispatchDraw(canvas: Canvas) = canvasRounder.round(canvas) { super.dispatchDraw(canvas) }
}
属性をサポートしたい場合は、ライブラリに書かれているようにこれを使用してください。
<resources>
<declare-styleable name="RoundedCornersView">
<attr name="corner_radius" format="dimension"/>
<attr name="corner_stroke_width" format="dimension"/>
<attr name="corner_stroke_color" format="color"/>
</declare-styleable>
</resources>
もう1つの方法は、ほとんどの用途では簡単かもしれません:MaterialCardViewを使用します。丸みのある角、線の色と幅、および高さをカスタマイズできます。
例:
<FrameLayout
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" Android:clipChildren="false" Android:clipToPadding="false"
tools:context=".MainActivity">
<com.google.Android.material.card.MaterialCardView
Android:layout_width="100dp" Android:layout_height="100dp" Android:layout_gravity="center"
app:cardCornerRadius="8dp" app:cardElevation="8dp" app:strokeColor="#f00" app:strokeWidth="2dp">
<ImageView
Android:layout_width="match_parent" Android:layout_height="match_parent" Android:background="#0f0"/>
</com.google.Android.material.card.MaterialCardView>
</FrameLayout>
そしてその結果:
あなたがそれを使用するなら、ストロークの端にわずかなアーティファクト問題があることに注意してください(そこにコンテンツのいくつかのピクセルを残す)。ズームインすると気付くでしょう。この問題について私は報告しました here 。
これを試して...
1.create - drawable xml (custom_layout.xml):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<solid Android:color="#FFFFFF" />
<stroke
Android:width="2dp"
Android:color="#FF785C" />
<corners Android:radius="10dp" />
</shape>
2.ビューの背景を追加します
Android:background="@drawable/custom_layout"
それを行うより良い方法は次のとおりです。
background_activity.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:gravity="fill">
<color Android:color="@color/black"/>
</item>
<item>
<shape Android:gravity="fill">
<solid Android:color="@color/white"/>
<corners Android:radius="10dip"/>
<padding Android:left="0dip" Android:top="0dip" Android:right="0dip" Android:bottom="0dip" />
</shape>
</item>
</layer-list>
これはAPI 21の下でも機能し、次のようになります。
もう少し努力して制御を改善したい場合は、cardCornerRadius
属性を付けてAndroid.support.v7.widget.CardView
を使用します(そしてcardViewで付随するドロップシャドウを削除するにはelevation
属性を0dp
に設定します)。また、これは15という低いAPIレベルでも機能します。
あなたがあなたのレイアウトを丸くしたいならば、それはデザインを美しくするためにCardViewを使うことが最善です、それは多くの機能を提供しました。
<Android.support.v7.widget.CardView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
card_view:cardCornerRadius="5dp">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight=".3"
Android:text="@string/quote_code"
Android:textColor="@color/white"
Android:textSize="@dimen/text_head_size" />
</LinearLayout>
</Android.support.v7.widget.CardView>
このcard_view:cardCornerRadius = "5dp"を使えば、半径を変更することができます。
レイアウトの丸みを帯びた縁にするには、CardViewを使用してください。 card_view:cardCornerRadius = "5dp" cardviewを使用して、丸みを帯びたレイアウトエッジを取得します。
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.v7.widget.CardView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
card_view:cardCornerRadius="5dp">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal"
Android:padding="15dp"
Android:weightSum="1">
<TextView
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight=".3"
Android:text="@string/quote_code"
Android:textColor="@color/white"
Android:textSize="@dimen/text_head_size" />
<TextView
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight=".7"
Android:text="@string/quote_details"
Android:textColor="@color/white"
Android:textSize="@dimen/text_head_size" />
</LinearLayout>
</Android.support.v7.widget.CardView>
</LinearLayout>
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
<solid Android:color="#FFFFFF"/>
<stroke Android:width="3dip" Android:color="#B1BCBE" />
<corners Android:radius="10dip"/>
<padding Android:left="3dip" Android:top="3dip" Android:right="3dip" Android:bottom="3dip" />
</shape>
@David、ストロークと同じ値をパディングするだけで、画像サイズに関係なく境界線を表示できます
最も簡単で簡単な方法は、レイアウトに card_background drawableを使用することです。これはグーグルの材料設計ガイドラインにも従う。あなたの中にこれを含めるだけです。
Android:background="@drawable/card_background"
これを描画可能ディレクトリに追加して、 card_background.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="#BDBDBD"/>
<corners Android:radius="5dp"/>
</shape>
</item>
<item
Android:left="0dp"
Android:right="0dp"
Android:top="0dp"
Android:bottom="2dp">
<shape Android:shape="rectangle">
<solid Android:color="#ffffff"/>
<corners Android:radius="5dp"/>
</shape>
</item>
</layer-list>
プログラムで角半径を設定するための関数
static void setCornerRadius(GradientDrawable drawable, float topLeft,
float topRight, float bottomRight, float bottomLeft) {
drawable.setCornerRadii(new float[] { topLeft, topLeft, topRight, topRight,
bottomRight, bottomRight, bottomLeft, bottomLeft });
}
static void setCornerRadius(GradientDrawable drawable, float radius) {
drawable.setCornerRadius(radius);
}
を使う
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.GREEN);
setCornerRadius(gradientDrawable, 20f);
//or setCornerRadius(gradientDrawable, 20f, 40f, 60f, 80f);
view.setBackground(gradientDrawable);
私は@gauravsapiens答えを私のコメントと一緒に取って、あなたにパラメータが何をもたらすのかについての合理的な不安を与えます。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
<!-- Background color -->
<solid Android:color="@color/white" />
<!-- Stroke around the background, width and color -->
<stroke Android:width="4dp" Android:color="@color/drop_shadow"/>
<!-- The corners of the shape -->
<corners Android:radius="4dp"/>
<!-- Padding for the background, e.g the Text inside a TextView will be
located differently -->
<padding Android:left="10dp" Android:right="10dp"
Android:bottom="10dp" Android:top="10dp" />
</shape>
角を丸める図形を作成するだけの場合は、パディングとストロークを削除してください。ソリッドも削除すると、事実上、透明な背景に丸みを帯びた角が作成されます。
怠け者のために、私はその下に丸みを帯びた角を持つ単色の白い背景である図形を作成しました - お楽しみください! :)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
<!-- Background color -->
<solid Android:color="@color/white" />
<!-- The corners of the shape -->
<corners Android:radius="4dp"/>
</shape>
Create your xml in drawable, layout_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<solid Android:color="@color/your_colour" />
<stroke
Android:width="2dp"
Android:color="@color/your_colour" />
<corners Android:radius="10dp" />
</shape>
<--width, color, radius should be as per your requirement-->
Finally in your layout.xml file write below line
Android:background="@drawable/layout_background"
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:padding="@dimen/_10sdp"
Android:shape="rectangle">
<solid Android:color="@color/header" />
<corners
Android:bottomLeftRadius="@dimen/_5sdp"
Android:bottomRightRadius="@dimen/_5sdp"
Android:topLeftRadius="@dimen/_5sdp"
Android:topRightRadius="@dimen/_5sdp" />