Wie erstelle ich ein Layout mit abgerundeten Ecken?

517

Wie kann ich ein Layout mit abgerundeten Ecken erstellen? Ich möchte abgerundete Ecken auf meine anwenden LinearLayout.

Addy
quelle
Erstellen Sie eine Form, die mit einer Ecke gezeichnet und dann als Hintergrund festgelegt werden kann. Wo liegt das Problem?
Stinepike
Sie müssen nur ein abgerundetes Bild als Hintergrund des Layouts
festlegen,
Sie müssen nur über SO suchen ... Sie werden eine Menge Antworten finden ..
Pankaj Kumar
Die Ecken sind für mich verdeckt
filthy_wizard

Antworten:

1030

1: Definieren Sie layout_bg.xml in 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: Fügen Sie layout_bg.xmlIhrem Layout einen Hintergrund hinzu

android:background="@drawable/layout_bg"
Gaurav Arora
quelle
194
Das funktioniert nicht. Wie Sie festgelegt haben, ist es der Hintergrund, sodass der Inhalt die abgerundeten Ecken überschreibt. Wenn Sie Inhalte haben, die an den Ecken gezeichnet werden, werden diese nicht abgerundet.
Android-Entwickler
22
Fast immer deckt mein Inhalt nie die Ecken ab. Das funktioniert perfekt.
David JY Tang
2
Wie vermeidest du den Fehler Element shape doesn't have the required attribute android:layout_height?
Lorenz
2
Element shape doesn't have the required attribute android:layout_heightDer Grund für den Fehler wurde angezeigt, weil sich layout_bg.xml nicht im Zeichenordner befand.
Atul
8
@ nhouser9: Eigentlich ist es eher wie "Es funktioniert, aber seien Sie gewarnt, dass Ihr Vordergrund / Inhalt in den Ecken zeichnen könnte". Je nach Anwendungsfall könnte es also zu 100% funktionieren. Ich bin froh, dass die Antwort nicht so viele Downvotes enthält, weil sie nützlich ist, und ich bin froh, dass der Kommentar hundert Upvotes enthält, weil es mit dieser Lösung leicht ist, die Einschränkung zu erkennen. Beste aus beiden Welten.
Benoit Duffez
124

Verwenden Sie für API 21+ Clip-Ansichten

Abgerundete Gliederungsausschnitte wurden der ViewKlasse in API 21 hinzugefügt . Siehe dieses Schulungsdokument oder diese Referenz Weitere Informationen finden .

Diese eingebaute Funktion macht abgerundete Ecken sehr einfach zu implementieren. Es funktioniert in jeder Ansicht oder jedem Layout und unterstützt das ordnungsgemäße Ausschneiden.

Folgendes ist zu tun:

  • Erstellen Sie eine abgerundete Form, die gezeichnet werden kann, und legen Sie sie als Hintergrund für Ihre Ansicht fest: android:background="@drawable/round_outline"
  • Laut Dokumentation müssen Sie dann nur noch Folgendes tun: android:clipToOutline="true"

Leider scheint es einen Fehler zu geben und dieses XML-Attribut wird derzeit nicht erkannt. Zum Glück können wir den Ausschnitt in Java einstellen:

  • In Ihrer Aktivität oder Ihrem Fragment: View.setClipToOutline(true)

Wie es aussieht:

Geben Sie hier die Bildbeschreibung ein

Besonderer Hinweis zu ImageViews

setClipToOutline()Funktioniert nur, wenn der Hintergrund der Ansicht auf eine Form eingestellt ist, die gezeichnet werden kann. Wenn diese Hintergrundform vorhanden ist, behandelt View den Umriss des Hintergrunds als Rahmen für Beschneidungs- und Schattenzwecke.

Dies bedeutet, dass, wenn Sie die Ecken in einer ImageView mit abrunden möchten setClipToOutline(), Ihr Bild von android:srcstatt stammen muss android:background(da der Hintergrund für die abgerundete Form verwendet wird). Wenn Sie den Hintergrund verwenden müssen, um Ihr Bild anstelle von src festzulegen, können Sie diese Problemumgehung für verschachtelte Ansichten verwenden:

  • Erstellen Sie ein äußeres Layout, dessen Hintergrund auf Ihre Form eingestellt ist
  • Wickeln Sie dieses Layout um Ihre ImageView (ohne Polsterung).
  • Die ImageView (einschließlich aller anderen Elemente im Layout) wird jetzt auf die abgerundete Form des äußeren Layouts zugeschnitten.
hungrighost
quelle
9
Funktioniert nicht mit API unter 21. Ich kann es kaum erwarten, bis ich nur API 21 unterstützen kann.
Startoftext
Die Verwendung von 'setClipToOutline' funktioniert, entfernt jedoch auch den Rahmen selbst (das Zeichenelement, das Sie für den Hintergrund verwenden). Gibt es eine Möglichkeit, dies zu vermeiden?
Android-Entwickler
Hast du meine Notiz über die Verwendung src=@drawable...anstelle von gelesen background=@drawable? Sie können dies entweder tun oder Ihre ImageView in einer Containeransicht verschachteln, die den Formumriss enthält.
Hungerghost
9
Jeder kommentiert diesen Fehler - er ist fast drei Jahre alt und zeigt keine Anzeichen dafür, dass er in diesem Jahrzehnt jederzeit behoben wird. Lassen Sie uns etwas Druck ausüben.
Josh Hansen
Wie kann dieser Fehler noch nicht behoben werden
P Fuster
74

Hier ist eine Kopie einer XML-Datei, um eine Zeichnungsdatei mit weißem Hintergrund, schwarzem Rand und abgerundeten Ecken zu erstellen:

 <?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>

Speichern Sie es als XML-Datei im Zeichenverzeichnis. Verwenden Sie es so, als würden Sie einen zeichnbaren Hintergrund (Symbol oder Ressourcendatei) unter Verwendung seines Ressourcennamens (R.drawable.your_xml_name) verwenden.

Kyogs
quelle
5
Liebte die Möglichkeit, bestimmte Ecken abzurunden
Mercury
1
Diese Antwort ist so ziemlich die Antwort wie oben. Die einzige wirkliche Änderung hier ist die Definition jedes Eckenradius, und da es für jede Ecke den gleichen Wert hat, hätte ich ihn stattdessen in eine Zeile geschrieben: <corners android:radius="7dp" />:)
ZooMagic
Dies ist die beste Antwort für mich, da sie die Verfügbarkeit des Abrundens bestimmter Ecken abdeckt ... gute Arbeit, funktioniert zu 100%
Mahmoud Ayman
Die Ecken des ImageView sind nicht abgerundet (abgeschnitten). Wie löse ich das?
Primož Kralj
Funktioniert noch im September 2019. Schön.
Nikolas Rieble
36

Verwenden Sie CardView in der Android v7-Unterstützungsbibliothek. Obwohl es ein bisschen schwer ist, löst es alle Probleme und ist einfach genug. Anders als bei der Set Drawable Background-Methode können Unteransichten erfolgreich abgeschnitten werden.

<?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>
Evan JIANG
quelle
2
Viel besser für alle, die es sich "leisten" können als alles andere. Es verwirrt mich, dass so eine grundlegende Sache nicht Teil der Standard-Android-Ansichten ist, da sie für fast jeden Webbrowser eine Grundvoraussetzung in CSS ist
Ben Philipp,
29

Ich habe so gemacht:

Screenshot überprüfen:

Relativer Layout-Hintergrund

Erstellen Sie eine zeichnbare Datei mit dem Namen custom_rectangle.xmlin einem zeichnbaren Ordner:

<?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>

Wenden Sie nun den Rechteckhintergrund auf Ansicht an :

mView.setBackground(R.drawlable.custom_rectangle);

Erledigt

Hiren Patel
quelle
14
Das funktioniert nicht. Wie Sie festgelegt haben, ist es der Hintergrund, sodass der Inhalt die abgerundeten Ecken überschreibt. Wenn Sie Inhalte haben, die an den Ecken gezeichnet werden, werden diese nicht abgerundet.
Android-Entwickler
25

Ich denke, ein besserer Weg, dies zu tun, besteht darin, zwei Dinge zusammenzuführen:

  1. Erstellen Sie eine Bitmap des Layouts, wie hier gezeigt .

  2. Machen Sie eine abgerundete Zeichnung aus der Bitmap, wie hier gezeigt

  3. Stellen Sie das Zeichen in einer Bildansicht ein.

Dies behandelt Fälle, die andere Lösungen nicht lösen konnten, z. B. Inhalte mit Ecken.

Ich denke, es ist auch ein bisschen GPU-freundlicher, da es eine einzelne Schicht anstelle von 2 zeigt.

Der einzig bessere Weg ist, eine vollständig angepasste Ansicht zu erstellen, aber das ist viel Code und kann viel Zeit in Anspruch nehmen. Ich denke, was ich hier vorgeschlagen habe, ist das Beste aus beiden Welten.

Hier ist ein Ausschnitt davon, wie es gemacht werden kann:

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);
    }

}

BEARBEITEN: habe eine nette Alternative gefunden, basierend auf der Bibliothek "RoundKornersLayouts" . Haben Sie eine Klasse, die für alle Layoutklassen verwendet wird, die Sie erweitern möchten, um gerundet zu werden:

//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()
    }

}

Fügen Sie dann in jeder Ihrer benutzerdefinierten Layoutklassen Code hinzu, der diesem ähnlich ist:

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) }

}

Wenn Sie Attribute unterstützen möchten, verwenden Sie diese wie in der Bibliothek beschrieben:

<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>

Eine weitere Alternative, die für die meisten Anwendungen möglicherweise einfacher ist: Verwenden Sie MaterialCardView. Es ermöglicht das Anpassen der abgerundeten Ecken, der Strichfarbe und -breite sowie der Höhe.

Beispiel:

<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>

Und das Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass an den Rändern des Strichs ein leichtes Artefaktproblem auftritt (einige Pixel des Inhalts bleiben dort), wenn Sie es verwenden. Sie können es bemerken , wenn Sie die Ansicht vergrößern. Ich habe über dieses Thema berichtet hier .

EDIT: scheint behoben zu sein, aber nicht in der IDE. Berichtet hier .

Android-Entwickler
quelle
Vielen Dank, dass Sie diese großartige Antwort zusammengestellt haben. Ich habe mich in die richtige Richtung bewegt, aber ich könnte Hilfe bei einem sehr verwandten Problem gebrauchen. Stackoverflow.com/questions/25877515/…
Will Thomson
Dies gibt einen Fehler aus, da in ImageView kein Standardkonstruktor verfügbar ist.
Anuj
Dies sollte als Antwort akzeptiert werden. Anstelle einer flachen Logik haben Sie eine fantastische Lösung gefunden. Auch dies löst Probleme, die Sie in Kommentaren zu anderen Antworten erwähnt haben. Vielen Dank für Ihre Mühe und vielleicht können Sie eine voll funktionsfähige Klasse korrigieren und über Github teilen. Ich denke, es könnte zu vielen Menschen helfen.
Arda Kara
@Senhor Du denkst ich sollte? Ich werde darüber nachdenken. Im Moment können Sie die anderen Repositories, die ich erstellt habe, hier sehen: github.com/AndroidDeveloperLB?tab=repositories
Android-Entwickler
Als großer Teil davon können Sie es versuchen. Btw autofittextview sieht wirklich cool aus.
Arda Kara
10

Versuche dies...

1.Erstellbare XML erstellen (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. Fügen Sie Ihren Ansichtshintergrund hinzu

android:background="@drawable/custom_layout"
Silambarasan Poonguti
quelle
Genau wie ich oben über eine ähnliche Lösung geschrieben habe: Das funktioniert nicht. Wie Sie festgelegt haben, ist es der Hintergrund, sodass der Inhalt die abgerundeten Ecken überschreibt. Wenn Sie Inhalte haben, die an den Ecken gezeichnet werden, werden diese nicht abgerundet.
Android-Entwickler
9

Wenn Sie Ihr Layout abrunden möchten, verwenden Sie am besten CardView. Es bietet viele Funktionen, um das Design schön zu machen.

<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>

Mit dieser card_view: cardCornerRadius = "5dp" können Sie den Radius ändern.

Farruh Habibullaev
quelle
5

Die beste und einfachste Methode wäre zu nutzen macht card_background ziehbar in Ihrem Layout. Dies folgt auch den Richtlinien für das Materialdesign von Google. Fügen Sie dies einfach in Ihr LinearLayout ein:

android:background="@drawable/card_background"

Fügen Sie dies Ihrem Zeichenverzeichnis hinzu und nennen Sie es 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>
Divyanshu Maithani
quelle
5

Verwenden Sie CardView, um abgerundete Kanten für Layouts zu erhalten. Verwenden Sie card_view: cardCornerRadius = "5dp" für cardview, um abgerundete Layoutkanten zu erhalten.

<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>
vishnuc156
quelle
CardView aus der support.v7-Bibliothek können Sie ab API7 oder höher verwenden.
Nikita G.
5

Ein besserer Weg wäre:

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>

Dies funktioniert auch unter API 21 und bietet Ihnen Folgendes:

Ergebnis


Wenn Sie bereit sind, etwas mehr Aufwand zu betreiben, um die Kontrolle zu verbessern , verwenden Sie android.support.v7.widget.CardViewdas cardCornerRadiusAttribut (und setzen Sie das elevationAttribut 0dp, um alle zugehörigen Schlagschatten mit cardView zu entfernen). Dies funktioniert auch ab API-Ebene ab 15.

Abdul Wasae
quelle
Wenn der Inhalt zum Hintergrund passt, wird er überschrieben. Es wird nicht wirklich an die von Ihnen festgelegte Form angepasst.
Android-Entwickler
Du meinst eine andere Ansicht? Können Sie bitte den Code aktualisieren, um zu zeigen, was Sie meinen? Die Idee ist, dass die abgerundeten Ecken keinen schwarzen Bereich setzen würden. Um die Ecken sollte eine transparente Farbe vorhanden sein.
Android-Entwickler
Oh, ich bekomme jetzt deine Frage. Ich denke, dafür können Sie mit einem kleinen festen Rand für Ihren Inhalt
auskommen
Dann wird der Inhalt jedoch nicht auf die von Ihnen gewählte Form zugeschnitten, da feste Ränder rechteckig sind und nicht der von Ihnen gewählten Form entsprechen.
Android-Entwickler
5

Funktion zum programmgesteuerten Einstellen des Eckenradius

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);
}

Verwenden von

GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.GREEN);
setCornerRadius(gradientDrawable, 20f);
//or setCornerRadius(gradientDrawable, 20f, 40f, 60f, 80f); 

view.setBackground(gradientDrawable);
Phan Van Linh
quelle
4
<?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, geben Sie einfach den gleichen Wert wie der Strich ein, damit der Rand sichtbar ist, unabhängig von der Bildgröße

paezinc
quelle
3

Ich habe die Antwort von @gauravsapiens mit meinen Kommentaren aufgenommen, um Ihnen eine vernünftige Vorstellung davon zu geben, wie sich die Parameter auswirken werden.

<?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>

Wenn Sie nur eine Form erstellen möchten, die die Ecken abrundet, können Sie die Polsterung und den Strich entfernen. Wenn Sie auch den Volumenkörper entfernen, haben Sie tatsächlich abgerundete Ecken auf einem transparenten Hintergrund erstellt.

Um faul zu sein, habe ich eine Form darunter geschaffen, die nur ein fester weißer Hintergrund mit abgerundeten Ecken ist - viel Spaß! :) :)

<?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>
ZooMagic
quelle
3

Erstellen Sie Ihre 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-->

und dann fügen Sie dies in Ihre layout.xml

 android:background="@drawable/layout_background"
Bapusaheb Shinde
quelle
2

Mit der Materialkomponenten - Bibliothek können Sie mit der MaterialShapeDrawableauf individuelle Formen zu zeichnen .

Fügen Sie einfach das LinearLayout in Ihr XML-Layout ein:

<LinearLayout
    android:id="@+id/linear_rounded"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    ..>

    <!-- content ..... -->

</LinearLayout>

Dann können Sie in Ihrem Code eine anwenden ShapeAppearanceModel. Etwas wie:

float radius = getResources().getDimension(R.dimen.default_corner_radius);

LinearLayout linearLayout= findViewById(R.id.linear_rounded);
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
    .toBuilder()
    .setAllCorners(CornerFamily.ROUNDED,radius)
    .build();

MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
//Fill the LinearLayout with your color
shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,R.color.secondaryLightColor));


ViewCompat.setBackground(linearLayout,shapeDrawable);

Geben Sie hier die Bildbeschreibung ein

Hinweis :: Es ist die Version 1.1.0 der Materialkomponentenbibliothek erforderlich .

Gabriele Mariotti
quelle
1
 <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" />

Keval Patel
quelle