Bagaimana saya dapat membuat layout dengan sudut membulat? Saya ingin menerapkan sudut membulat untuk saya LinearLayout
.
1: Tentukan layout_bg.xml di drawables:
<?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: Menambahkan layout_bg.xml
sebagai latar belakang untuk tata letak anda
android:background="@drawable/layout_bg"
Untuk API 21+, Menggunakan Klip Views
Bulat garis kliping ditambahkan ke View
kelas dalam API 21. Melihat ini pelatihan doc atau referensi untuk info lebih lanjut.
Ini built-in fitur membuat sudut bulat yang sangat mudah untuk menerapkan. Ia bekerja pada setiap tampilan atau tata letak yang tepat dan mendukung kliping.
Berikut's Apa yang Harus Dilakukan:
android:background="@drawable/round_outline"
android:clipToOutline="benar"
Sayangnya, tampaknya ada bug dan ini atribut XML saat ini tidak diakui. Untungnya, kita dapat mengatur kliping di Jawa:
Lihat.setClipToOutline(benar)
Apa Yang Tampak Seperti:
Catatan Khusus Tentang ImageViews
setClipToOutline()
hanya bekerja ketika Melihat's latar belakang diatur ke bentuk drawable. Jika latar belakang ini bentuk yang ada, Melihat memperlakukan latar belakang's garis sebagai batas untuk kliping dan membayangi tujuan.
Ini berarti bahwa jika anda ingin putaran sudut pada ImageView dengan setClipToOutline()
, anda gambar harus datang dari android:src
bukan android:background
(karena latar belakang ini digunakan untuk bentuk bulat). Jika anda HARUS menggunakan latar belakang untuk mengatur gambar anda bukan src, anda dapat menggunakan ini bersarang pandangan pemecahan masalah:
Berikut ini's salinan dari sebuah file XML untuk membuat drawable dengan latar belakang putih, hitam perbatasan dan rounded corners:
<?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>
simpan sebagai file xml di direktori drawable, Gunakan seperti yang akan anda gunakan setiap drawable latar belakang(icon atau file sumber daya) yang menggunakan nama sumber daya (R. drawable.your_xml_name)
Gunakan CardView di android v7 dukungan perpustakaan. Meskipun itu's sedikit berat, memecahkan semua masalah, dan cukup mudah. Tidak seperti set drawable latar belakang metode, bisa klip subviews berhasil.
<?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>
Saya telah melakukan cara ini:
Periksa Screenshot:
Buat drawable file diberi nama dengan custom_rectangle.xml
di 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="@android:color/white" />
<corners android:radius="10dip" />
<stroke
android:width="1dp"
android:color="@android:color/white" />
</shape>
Sekarang menerapkan Persegi panjang latar belakang di Melihat:
mView.setBackground(R.drawlable.custom_rectangle);
Selesai
Saya pikir cara yang lebih baik untuk melakukannya adalah untuk menggabungkan 2 hal:
membuat bitmap dari tata letak, seperti yang ditunjukkan di sini.
membuat rounded ditarik dari bitmap, seperti yang ditunjukkan di sini
mengatur drawable pada imageView.
Ini akan menangani kasus-kasus yang solusi lain telah gagal untuk memecahkan, seperti memiliki kandungan yang memiliki sudut.
Saya pikir itu's juga sedikit lebih banyak GPU-friendly, karena hal itu menunjukkan lapisan tunggal bukan 2 .
Satu-satunya cara yang lebih baik adalah untuk membuat yang benar-benar disesuaikan, namun yang's banyak kode dan mungkin mengambil banyak waktu. Saya berpikir bahwa apa yang saya nyatakan di sini adalah yang terbaik dari kedua dunia.
Berikut ini's cuplikan dari bagaimana hal itu bisa dilakukan:
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);
}
}
EDIT: menemukan alternatif yang baik, berdasarkan "RoundKornersLayouts" perpustakaan. Memiliki kelas yang akan digunakan untuk semua kelas tata letak yang anda inginkan untuk memperpanjang, harus dibulatkan:
//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()
}
}
Kemudian, di masing-masing disesuaikan kelas tata letak, tambahkan kode yang mirip dengan yang satu ini:
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) }
}
Jika anda ingin mendukung atribut, gunakan ini seperti yang tertulis di perpustakaan:
<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>
Alternatif lain, yang mungkin lebih mudah bagi sebagian besar menggunakan: gunakan MaterialCardView . Hal ini memungkinkan menyesuaikan sudut membulat, warna stroke dan lebar, dan elevasi.
Contoh:
<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>
Dan hasilnya:
Perhatikan bahwa ada sedikit artefak masalah di tepi stroke (daun beberapa piksel pada konten yang ada), jika anda menggunakannya. Anda dapat melihat jika anda melakukan zoom in. I've melaporkan tentang masalah ini di sini.
EDIT: sepertinya harus diperbaiki, tapi tidak pada IDE. Dilaporkan di sini.
Coba ini...
1.buat 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.menambahkan view latar belakang
android:background="@drawable/custom_layout"
Jika anda ingin membuat tata letak anda bulat, itu adalah yang terbaik untuk menggunakan CardView, itu memberikan banyak fitur untuk membuat desain yang indah.
<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>
Dengan ini card_view:cardCornerRadius="5dp", anda dapat mengubah radius.
Fungsi untuk mengatur sudut radius pemrograman
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);
}
Menggunakan
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.GREEN);
setCornerRadius(gradientDrawable, 20f);
//or setCornerRadius(gradientDrawable, 20f, 40f, 60f, 80f);
view.setBackground(gradientDrawable);
Cara yang lebih baik untuk melakukannya akan sama:
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>
Ini akan bekerja di bawah API 21 juga, dan memberi anda sesuatu seperti ini:
Jika anda bersedia untuk membuat upaya yang lebih sedikit lebih banyak kontrol yang lebih baik, maka gunakan android.dukungan.v7.widget.CardView
dengan cardCornerRadius
atribut (dan set elevation
atribut 0dp
untuk menyingkirkan apapun yang menyertainya drop shadow dengan cardView). Juga, ini akan bekerja dari API tingkat rendah sebagai sebagai 15.
Gunakan CardView untuk mendapatkan tepi bulat untuk setiap layout. Menggunakan card_view:cardCornerRadius="5dp" untuk cardview untuk mendapatkan bulat letak tepi.
<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>
Yang terbaik dan paling sederhana metode akan membuat penggunaan card_background drawable dalam tata letak anda. Ini juga mengikuti Google's bahan rancangan pedoman. Hanya memasukkan ini dalam anda LinearLayout:
android:background="@drawable/card_background"
Tambahkan ini ke drawable direktori dan nama itu 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>
<?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, hanya menempatkan bantalan nilai yang sama seperti stroke, sehingga perbatasan dapat terlihat, regardeless ukuran gambar
I've diambil @gauravsapiens menjawab dengan komentar saya dalam untuk memberikan anda sebuah ketakutan wajar dari apa parameter yang akan berlaku.
<?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>
Jika anda're hanya mencari untuk membuat bentuk yang putaran sudut, menghapus padding dan stroke akan dilakukan. Jika anda menghapus padat serta anda akan, pada dasarnya, telah membuat sudut bulat pada latar belakang transparan.
Demi menjadi malas saya telah menciptakan sebuah bentuk di bawah, yang hanya padat latar belakang putih dengan sudut-sudut membulat - menikmati! :)
<?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>
Membuat xml anda di 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-->
dan kemudian, tambahkan ini di anda layout.xml
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" />