Подтвердить что ты не робот

Как сделать макет с закругленными углами..?

Как я могу сделать макет с закругленными углами? Я хочу применить закругленные углы к моему LinearLayout.

4b9b3361

Ответ 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)

Что это выглядит:

enter image description here

Специальное примечание о 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

Я сделал так:

Проверьте скриншот:

Relative layout Background

Создать 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 вещи:

  1. создайте растровое изображение макета, как показано здесь.

  2. сделать округлый рисунок из растрового изображения, как показано здесь

  3. установите рисование на 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>

И результат:

enter image description here

Обратите внимание, что по краям обводки возникает небольшая проблема с артефактами (при этом остаются некоторые пиксели содержимого), если вы ее используете. Вы можете заметить это, если увеличите масштаб. Я сообщил об этой проблеме здесь.

ОБНОВЛЕНИЕ: кажется, исправлено, но не на 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)