Как я могу сделать макет с закругленными углами? Я хочу применить закругленные углы к моему LinearLayout
.
Как сделать макет с закругленными углами..?
Ответ 1
1: Определите layout_bg.xml в 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: Добавить layout_bg.xml
в качестве фона для вашего макета
android:background="@drawable/layout_bg"
Ответ 2
Для API 21+ используйте "Просмотр клипов"
Обрезание обрезанного обводки было добавлено в класс View
в API 21. См. этот учебный документ или это reference для получения дополнительной информации.
Эта встроенная функция делает закругленные углы очень простыми в реализации. Он работает с любым видом или макетом и поддерживает правильное обрезание.
Здесь Что делать:
- Создайте закругленную фигуру и установите ее в качестве фонового изображения:
android:background="@drawable/round_outline"
- Согласно документации, все, что вам нужно сделать, это следующее:
android:clipToOutline="true"
К сожалению, кажется, что ошибка, и этот атрибут XML в настоящее время не распознается. К счастью, мы можем установить обрезку в Java:
- В вашей деятельности или фрагменте:
View.setClipToOutline(true)
Что это выглядит:
Специальное примечание о ImageViews
setClipToOutline()
работает только тогда, когда фон "Вид" установлен в форму, пригодную для рисования. Если эта фоновая форма существует, View рассматривает контур фона как границы для целей отсечения и теневого копирования.
Это означает, что если вы хотите обогнуть углы ImageView с setClipToOutline()
, ваше изображение должно начинаться с android:src
вместо android:background
(поскольку фон используется для закругленной формы). Если вы ДОЛЖНЫ использовать фон для установки изображения вместо src, вы можете использовать обходные пути вложенных представлений:
- Создайте внешний макет с его фоном, настроенным на вашу форму.
- Оберните этот макет вокруг вашего ImageView (без прокладки)
- ImageView (включая все остальное в макете) теперь будет привязан к закругленной форме внешнего макета.
Ответ 3
Вот копия 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)
Ответ 4
Используйте CardView в библиотеке поддержки android v7. Хотя он немного тяжелый, он решает все проблемы и достаточно прост. Не похоже на заданный метод рисования фона, он может успешно скреплять субвью.
<?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>
Ответ 5
Я сделал так:
Проверьте скриншот:
Создать Drawable файл с именем, custom_rectangle.xml
в вытяжке папке:
<?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>
Теперь примените фон Rectangle на View:
mView.setBackground(R.drawlable.custom_rectangle);
Готово
Ответ 6
Я думаю, что лучший способ сделать это - объединить 2 вещи:
создайте растровое изображение макета, как показано здесь.
сделать округлый рисунок из растрового изображения, как показано здесь
установите рисование на imageView.
Это будет обрабатывать случаи, которые не удалось решить другим решениям, например, наличие контента с углами.
Я думаю, что это также немного более дружественно к GPU, так как показывает один слой вместо 2.
Единственный лучший способ - создать полностью настраиваемое представление, но это требует много кода и может занять много времени. Я думаю, что то, что я предложил здесь, является лучшим из обоих миров.
Вот фрагмент того, как это можно сделать:
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 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>
Другая альтернатива, которая может быть проще для большинства применений: используйте 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>
И результат:
Обратите внимание, что по краям обводки возникает небольшая проблема с артефактами (при этом остаются некоторые пиксели содержимого), если вы ее используете. Вы можете заметить это, если увеличите масштаб. Я сообщил об этой проблеме здесь.
ОБНОВЛЕНИЕ: кажется, исправлено, но не на IDE. Об этом сообщает здесь.
Ответ 7
Попробуйте это...
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.add ваш фон представления
android:background="@drawable/custom_layout"
Ответ 8
Если вы хотите, чтобы ваш макет был округлым, лучше всего использовать 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", вы можете изменить радиус.
Ответ 9
Лучший способ сделать это:
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 и даст вам примерно следующее:
Если вы хотите сделать больше усилий более эффективным, используйте android.support.v7.widget.CardView
с его атрибутом cardCornerRadius
(и установите атрибут elevation
на 0dp
, чтобы избавиться от любой сопровождающей теневой тени с помощью cardView). Кроме того, это будет работать от уровня API до 15.
Ответ 10
Используйте CardView, чтобы получить закругленные края для любых макетов. Используйте card_view: cardCornerRadius = "5dp" для просмотра карт с закругленными краями.
<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>
Ответ 11
Функция для установки радиуса угла программно
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);
Ответ 12
<?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, просто добавьте одно значение, как штрих, поэтому граница может быть видимой, безразмерный размер изображения
Ответ 13
Самый лучший и простой способ - использовать card_background, который можно использовать в вашем макете. Это также следует руководству Google по разработке материалов. Просто включите это в вас LinearLayout:
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>
Ответ 14
Создайте свой XML в 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-->
а затем добавьте это в свой layout.xml
android:background="@drawable/layout_background"
Ответ 15
Я взял ответ @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>
Ответ 16
<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" />
Ответ 17
Intead of XML
android:background="@drawable/layout_shape"
использовать (в коде):
getDialog().getWindow().setBackgroundDrawableResource(R.drawable.layout_shape)