Jak zrobić układ z zaokrąglonymi narożnikami ..?

516

Jak mogę utworzyć układ z zaokrąglonymi narożnikami? Chcę zastosować do mnie zaokrąglone rogi LinearLayout.

Addy
źródło
utwórz kształt z rysunkiem z narożnikiem, a następnie ustaw jako tło ... gdzie jest problem?
stinepike,
wystarczy ustawić zaokrąglony obraz jako tło układu, aby nadać mu kształt, jak powiedziano w pierwszym komentarzu
SilentKiller
musisz po prostu przeszukać SO ... znajdziesz mnóstwo odpowiedzi ..
Pankaj Kumar
kąty są dla mnie zasłonięte
filthy_wizard

Odpowiedzi:

1029

1: Zdefiniuj layout_bg.xml w 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: Dodaj layout_bg.xmljako tło do swojego układu

android:background="@drawable/layout_bg"
Gaurav Arora
źródło
194
To nie działa jak już ustawiłeś, jest to tło, więc treść zastępuje zaokrąglone rogi, a jeśli masz zawartość, która rysuje na rogach, nie zobaczysz, że są zaokrąglane.
programista Androida
22
Niemal zawsze moje treści nigdy nie obejmują narożników. To działa idealnie.
David JY Tang
2
Jak uniknąć błędu Element shape doesn't have the required attribute android:layout_height?
Lorenz
2
Element shape doesn't have the required attribute android:layout_heightPrzyczyna błędu została pokazana, ponieważ layout_bg.xml nie znajdował się w folderze rozwijalnym.
Atul
8
@ nhouser9: w rzeczywistości jest to bardziej „Działa, ale ostrzegam, że Twój pierwszy plan / treść może rysować się w rogach”. Zatem w zależności od przypadku użycia może działać w 100%. Cieszę się, że odpowiedź nie ma tylu głosów negatywnych, ponieważ jest przydatna, i cieszę się, że komentarz ma sto głosów pozytywnych, ponieważ dzięki temu rozwiązaniu łatwo jest dostrzec ograniczenia. Najlepsze z obu światów.
Benoit Duffez
124

W przypadku interfejsu API 21+ użyj widoków klipu

Zaokrąglone obcinanie obrysu zostało dodane do Viewklasy w API 21. Zobacz ten dokument szkoleniowy lub to odniesienie, aby uzyskać więcej informacji.

Ta wbudowana funkcja sprawia, że ​​zaokrąglone rogi są bardzo łatwe do wdrożenia. Działa na dowolnym widoku lub układzie i obsługuje prawidłowe obcinanie.

Oto co należy zrobić:

  • Utwórz zaokrąglony kształt do rysowania i ustaw go jako tło widoku: android:background="@drawable/round_outline"
  • Zgodnie z dokumentacją wszystko, co musisz zrobić, to: android:clipToOutline="true"

Niestety wydaje się, że wystąpił błąd i ten atrybut XML obecnie nie jest rozpoznawany. Na szczęście możemy ustawić przycinanie w Javie:

  • W Twojej działalności lub fragmencie: View.setClipToOutline(true)

Jak to wygląda:

wprowadź opis zdjęcia tutaj

Specjalna uwaga na temat ImageViews

setClipToOutline()działa tylko wtedy, gdy tło Widoku jest ustawione na kształt, który można rysować. Jeśli ten kształt tła istnieje, widok traktuje kontur tła jako obramowanie do celów wycinania i cieniowania.

Oznacza to, że jeśli chcesz zaokrąglać rogi w ImageView za pomocą setClipToOutline(), twój obraz musi pochodzić android:srczamiast android:background(ponieważ tło jest używane dla zaokrąglonego kształtu). Jeśli MUSISZ użyć tła do ustawienia obrazu zamiast src, możesz użyć tego obejścia widoków zagnieżdżonych:

  • Utwórz układ zewnętrzny z ustawionym tłem do kształtu do rysowania
  • Zawiń ten układ wokół ImageView (bez wypełnienia)
  • ImageView (włączając wszystko inne w układzie) zostanie teraz przycięty do zaokrąglonego kształtu zewnętrznego układu.
głodny głód
źródło
9
Nie działa na API mniejszym niż 21. Nie mogę się doczekać, aż będę mógł obsługiwać tylko API 21.
startoftext
Korzystanie z „setClipToOutline” działa, ale usuwa również samą ramkę (rysunek, którego używasz jako tła). Czy jest jakiś sposób, aby tego uniknąć?
programista Androida
Czy czytałeś moją notatkę o używaniu src=@drawable...zamiast background=@drawable? Możesz to zrobić lub zagnieździć ImageView w widoku kontenera, który zawiera kontur kształtu.
hungryghost
9
Wszyscy komentują ten błąd - ma prawie trzy lata i nie wykazuje żadnych oznak, że zostanie naprawiony w tej dekadzie. Naciskajmy na to.
Josh Hansen
Jak nie można jeszcze naprawić tego błędu
P Fuster
74

Oto kopia pliku XML, aby utworzyć rysunek z białym tłem, czarną ramką i zaokrąglonymi narożnikami:

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

zapisz go jako plik xml w katalogu do rysowania, użyj go tak, jakbyś używał dowolnego tła do rysowania (ikony lub pliku zasobów), używając jego nazwy zasobu (R.drawable.your_xml_name)

kyogs
źródło
5
Uwielbiałem możliwość zaokrąglania określonych rogów
Mercury
1
Ta odpowiedź jest w zasadzie odpowiedzią jak wyżej. Jedyną prawdziwą zmianą jest tutaj definicja każdego promienia narożnika, a biorąc pod uwagę jego tę samą wartość dla każdego narożnika, <corners android:radius="7dp" />
zapisałbym
jest to dla mnie NAJLEPSZA odpowiedź, ponieważ obejmuje dostępność zaokrąglania określonych narożników ... dobra robota, działa w 100%
Mahmoud Ayman
Rogi ImageView nie są zaokrąglone (przycięte), jak to rozwiązać?
Primož Kralj
Nadal działa we wrześniu 2019 r. Fajnie.
Nikolas Rieble,
36

Użyj CardView w bibliotece wsparcia dla Androida v7. Choć jest trochę ciężki, rozwiązuje wszystkie problemy i jest dość łatwy. W przeciwieństwie do metody rysowania tła, może skutecznie przycinać widoki podrzędne.

<?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
źródło
2
Znacznie lepiej dla wszystkich, którzy mogą sobie na to pozwolić, niż cokolwiek innego. Zaskakuje mnie to, że taka podstawowa rzecz nie jest częścią standardowych widoków Androida, jest podstawowym elementem CSS dla prawie każdej przeglądarki internetowej
Ben Philipp
29

Zrobiłem w ten sposób:

Sprawdź zrzut ekranu:

Układ względny Tło

Utwórz plik do rysowania o nazwie custom_rectangle.xmlw folderze do rysowania :

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

Teraz zastosuj tło prostokąta w widoku :

mView.setBackground(R.drawlable.custom_rectangle);

Gotowy

Hiren Patel
źródło
14
To nie działa jak już ustawiłeś, jest to tło, więc treść zastępuje zaokrąglone rogi, a jeśli masz zawartość, która rysuje na rogach, nie zobaczysz, że są zaokrąglane.
programista Androida
25

Myślę, że lepszym sposobem na to jest połączenie dwóch rzeczy:

  1. zrób bitmapę układu, jak pokazano tutaj .

  2. Zrobić zaokrąglony rysunek z mapy bitowej, jak pokazano tutaj

  3. ustaw drawable na imageView.

Będzie to obsługiwać przypadki, których inne rozwiązania nie rozwiązały, na przykład zawartość o narożnikach.

Myślę, że jest też trochę bardziej przyjazny dla GPU, ponieważ pokazuje jedną warstwę zamiast 2.

Jedynym lepszym sposobem jest stworzenie całkowicie spersonalizowanego widoku, ale to dużo kodu i może zająć dużo czasu. Myślę, że to, co tu zasugerowałem, jest najlepsze z obu światów.

Oto fragment tego, jak można to zrobić:

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

}

EDYCJA: znalazłem fajną alternatywę, opartą na bibliotece „RoundKornersLayouts” . Mieć klasę, która będzie używana dla wszystkich klas układu, które chcesz rozszerzyć, aby ją zaokrąglić:

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

}

Następnie w każdej z niestandardowych klas układu dodaj kod podobny do tego:

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

}

Jeśli chcesz obsługiwać atrybuty, użyj tego, jak napisano w bibliotece:

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

Inna alternatywa, która może być łatwiejsza w przypadku większości zastosowań: użyj MaterialCardView. Pozwala dostosować zaokrąglone rogi, kolor i szerokość obrysu oraz wysokość.

Przykład:

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

A wynik:

wprowadź opis zdjęcia tutaj

Zauważ, że na krawędziach obrysu występuje niewielki problem z artefaktami (pozostawia tam kilka pikseli zawartości), jeśli go używasz. Możesz to zauważyć, jeśli powiększysz. Zgłosiłem tutaj ten problem .

EDYCJA: wydaje się być naprawiona, ale nie na IDE. Zgłoszone tutaj .

programista Androida
źródło
Dziękuję za zebranie tej niesamowitej odpowiedzi. To sprawiło, że zmierzałem we właściwym kierunku, ale mogłem skorzystać z pomocy w bardzo pokrewnym problemie tutaj stackoverflow.com/questions/25877515/...
Will Thomson
Daje to błąd, ponieważ w ImageView nie ma domyślnego konstruktora.
Anuj,
Należy zaakceptować odpowiedź. Zamiast płaskiej logiki poszedłeś w dół i znalazłeś niesamowite rozwiązanie. To także rozwiązuje problemy wymienione w komentarzach do innych odpowiedzi. Dzięki za twój wysiłek, a może uda Ci się wykupić w pełni funkcjonalną klasę i udostępnić ją za pośrednictwem github. Myślę, że może pomóc zbyt wielu ludziom.
Arda Kara
@Senhor Myślisz, że powinienem? Pomyślę o tym. Na razie możesz zobaczyć inne repozytoria, które utworzyłem tutaj: github.com/AndroidDeveloperLB?tab=repositories
programista Androida
Jako dużą część tego możesz spróbować. Btw autofittextview wygląda naprawdę fajnie.
Arda Kara
10

Spróbuj tego...

1. stwórz xml do rysowania (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. dodaj swoje tło widoku

android:background="@drawable/custom_layout"
Silambarasan Poonguti
źródło
Tak jak napisałem powyżej o podobnym rozwiązaniu: To nie działa. jak już ustawiłeś, jest to tło, więc treść zastępuje zaokrąglone rogi, a jeśli masz zawartość, która rysuje na rogach, nie zobaczysz, że są zaokrąglane.
programista Androida
9

Jeśli chcesz, aby Twój układ był zaokrąglony, najlepiej użyć CardView, ponieważ zapewnił wiele funkcji, aby projekt był piękny.

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

Za pomocą tego card_view: cardCornerRadius = "5dp" możesz zmienić promień.

Farruh Habibullaev
źródło
5

Najlepszym i najprostszym sposobem byłoby wykorzystanie card_background rozciągliwej w układzie. Jest to również zgodne z wytycznymi Google dotyczącymi projektowania materiałów. Po prostu dołącz to do siebie LinearLayout:

android:background="@drawable/card_background"

Dodaj to do katalogu, który można wyciągnąć i nazwij go 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
źródło
5

Użyj CardView, aby uzyskać zaokrąglone krawędzie dla dowolnych układów. Użyj card_view: cardCornerRadius = "5dp" dla widoku karty, aby uzyskać zaokrąglone krawędzie układu.

<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
źródło
CardView z biblioteki support.v7, możesz używać z API7 lub wyższej.
Nikita G.
5

Lepszym sposobem na to byłoby:

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>

To zadziała również poniżej API 21 i da ci coś takiego:

Wynik


Jeśli chcesz nieco więcej wysiłku, lepiej kontrolować, użyj android.support.v7.widget.CardViewtego cardCornerRadiusatrybutu (i ustaw elevationatrybut, 0dpaby pozbyć się towarzyszącego mu cienia za pomocą cardView). Będzie to również działać z poziomu interfejsu API już od 15.

Abdul Wasae
źródło
Jeśli treść pasuje do tła, zastąpi ją. Tak naprawdę nie pasuje do ustawionego kształtu.
programista Androida
Masz na myśli inny widok? Czy możesz zaktualizować kod, aby pokazać, co masz na myśli? Chodzi o to, że zaokrąglone rogi nie umieszczałyby czarnego obszaru. Wokół rogów powinien być przezroczysty kolor.
programista Androida
Och, rozumiem teraz twoje pytanie. Sądzę, że możesz sobie
poradzić
Ale wtedy zawartość nie zostanie przycięta do wybranego kształtu, ponieważ ustalone marginesy są prostokątne, a nie zgodnie z wybranym kształtem.
programista Androida
5

Funkcja programowego ustawiania promienia narożnika

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

Za pomocą

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

view.setBackground(gradientDrawable);
Phan Van Linh
źródło
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, po prostu wstaw padding taką samą wartość jak obrys, aby ramka była widoczna, bez względu na rozmiar obrazu

paezinc
źródło
3

Wziąłem odpowiedź @gauravsapiens z moimi komentarzami w środku, aby dać ci rozsądne zrozumienie, jakie parametry będą miały wpływ.

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

Jeśli chcesz tylko utworzyć kształt, który zaokrągli rogi, usuń wypełnienie, a obrys się spełni. Jeśli usuniesz bryłę, utworzysz zaokrąglone rogi na przezroczystym tle.

Dla lenistwa stworzyłem pod spodem kształt, który jest po prostu białym tłem z zaokrąglonymi rogami - ciesz się! :)

<?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
źródło
3

Stwórz swój plik xml w wersji do rysowania, 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-->

a następnie dodaj to do swojego layout.xml

 android:background="@drawable/layout_background"
Bapusaheb Shinde
źródło
2

Za pomocą Biblioteki komponentów materiałów możesz używać MaterialShapeDrawabledo rysowania niestandardowych kształtów .

Wystarczy umieścić LinearLayout w układzie xml:

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

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

</LinearLayout>

Następnie w kodzie możesz zastosować ShapeAppearanceModel. Coś jak:

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

wprowadź opis zdjęcia tutaj

Uwaga :: wymaga wersji 1.1.0 biblioteki komponentów materiałów.

Gabriele Mariotti
źródło
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
źródło