16 ответов:
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"
для API 21+ используйте Clip Views
закругленный контур вырезки был добавлен в
Viewкласс в API 21. Смотрите это обучение doc или это ссылка для получения дополнительной информации.эта встроенная функция делает закругленные углы очень легко реализовать. Он работает на любом виде или макете и поддерживает правильное обрезание.
вот что нужно сделать:
- создать округлую форму drawable и установите его в качестве фона вашего представления :
android:background="@drawable/round_outline"- согласно документации, то все, что вам нужно сделать, это:
android:clipToOutline="true"к сожалению, там, кажется ошибка и этот атрибут XML в настоящее время не распознается. К счастью, мы можем установить ограничение на Java:
- в вашей деятельности или фрагмент:
View.setClipToOutline(true)Как Это Выглядит Например:
Особое Замечание Об ImageViews
setClipToOutline()работает только тогда, когда фон Вида установлен на фигуру, которую можно нарисовать. Если эта фоновая форма существует, представление рассматривает контур фона как границы для обрезки и затенения.это означает, что если вы хотите закруглить углы на ImageView с
setClipToOutline(), ваш образ должен исходить отandroid:srcвместоandroid:background(так как фон есть используется для округлой формы). Если вы должны использовать фон для установки изображения вместо src, вы можете использовать это вложенные представления обходной путь:
- создайте внешний макет с фоном, установленным для вашей фигуры drawable
- оберните этот макет вокруг вашего ImageView (без заполнения)
- изображение (включая все остальное в макете) теперь будет обрезано до округлой формы внешнего макета.
вот копия XML-файла для создания drawable с белым фоном, черной рамкой и закругленными углами:
<?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-файла в каталоге 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);сделал
используйте CardView в библиотеке поддержки android v7. Хотя это немного тяжело, он решает все проблемы, и достаточно легко. Не так, как метод 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 вещи:
сделайте изображение макета, как показано здесь.
сделайте округлый чертеж из растрового изображения, как показано здесь
установите drawable на 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'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: нашел хорошую альтернативу, основанную на библиотека"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>и в итоге:
обратите внимание, что есть небольшая проблема артефактов по краям штрих (оставляет там несколько пикселей содержимого), если вы его используете. Вы можете заметить это, если увеличить масштаб. Я уже сообщал об этой проблеме здесь.
попробуйте это...
1.создать 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 также, и дать вам что-то вроде этого:
если вы готовы сделать немного больше усилий более лучший контроль, то используйте
android.support.v7.widget.CardViewСcardCornerRadiusатрибут (и набор до0dpчтобы избавиться от любой сопутствующей тени с помощью cardView). Кроме того, это будет работать от уровня API до 15.
используйте 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 в вашем макете. Это также соответствует рекомендациям Google по дизайну материалов. Просто включите это в свой LinearLayout:
android:background="@drawable/card_background"добавьте это в свой каталог drawable и назовите его 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);
Если вы хотите сделать свой макет округлым, лучше всего использовать 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", вы можете изменить радиус.
создайте свой xml в drawable, layout_background.xml
<solid android:color="@color/your_colour" /> <stroke android:width="2dp" android:color="@color/your_colour" /> <corners android:radius="10dp" /> </shape>
наконец-то в вашем макете.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" />
Я взял @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>




Comments