Promień naroża CardView

98

Czy istnieje sposób, aby CardView miał tylko promień narożnika u góry?

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="10dp"
    >
gniotliwy
źródło

Odpowiedzi:

121

Dopóki nie spróbujesz rozszerzyć CardViewklasy Androida , nie możesz dostosować tego atrybutu z XML.

Niemniej jednak istnieje sposób na osiągnięcie tego efektu.

Umieść jeden CardViewwewnątrz drugiego CardViewi zastosuj przezroczyste tło na zewnątrz CardViewi usuń jego promień narożnika ( "cornerRadios = 0dp"). Twoja wewnętrzna CardViewbędzie miała na przykład wartość cornerRadius równą 3dp. Następnie zastosuj marginTop do wewnętrznej strony CardView, aby jej dolne granice zostały obcięte przez zewnętrzną CardView. W ten sposób promień dolnego narożnika twojego wnętrza CardViewzostanie ukryty.

Kod XML jest następujący:

 <android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view_outer"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_gravity="center"
    card_view:cardBackgroundColor="@android:color/transparent"
    card_view:cardCornerRadius="0dp"
    card_view:cardElevation="3dp" >

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view_inner"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:layout_marginTop="3dp"
        card_view:cardBackgroundColor="@color/green"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="0dp" >
    </android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>

A efekt wizualny jest następujący:

CardView z zaokrąglonymi rogami tylko na górze

Zawsze umieszczaj zawartość w swoim wnętrzu CardView. Twój zewnętrzny CardView służy jedynie do „ukrycia” dolnych zaokrąglonych rogów wewnętrznej strony CardView.

joao2fast4u
źródło
8
Zwróć uwagę, że cień jest nieprawidłowy (cienie w dolnym rogu są nadal zaokrąglone), a selektor pierwszego planu byłby bardziej zauważalnie nieprawidłowy.
ataulm
Myślę, że łatwiejszy sposób opisania @shreedhar bhat jest lepszy
Matei Suica
Powiedzmy, jaka jest domyślna wartość cardCornerRadius? czy to jest 4dp?
programista Androida
Nie jestem pewien, dlaczego wszyscy oznaczyli to jako odpowiedź. To nie jest dobra odpowiedź. Próbowałem tego, ale nie działa tak, jak powinno.
Visal Varghese
42
dependencies: compile 'com.android.support:cardview-v7:23.1.1'

<android.support.v7.widget.CardView
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:elevation="12dp"
    android:id="@+id/view2"
    app:cardCornerRadius="40dp"
    android:layout_centerHorizontal="true"
    android:innerRadius="0dp"
    android:shape="ring"
    android:thicknessRatio="1.9">
    <ImageView
        android:layout_height="80dp"
        android:layout_width="match_parent"
        android:id="@+id/imageView1"
        android:src="@drawable/Your_image"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true">
    </ImageView>
</android.support.v7.widget.CardView>
shreedhar bhat
źródło
9
Czy mógłbyś wyjaśnić, co robi ten blok kodu? I nie wydaje się znaleźć żadnych zasobów wyjaśniające o właściwości XML innerRadius, shapeorazthicknessRatio
atjua
2
Tylko app:cardCornerRadius="40dp"będzie działać.
Rumit Patel
33

Możesz użyć standardu MaterialCardzawartego w oficjalnej bibliotece komponentów materiałowych .

Użyj w swoim układzie:

<com.google.android.material.card.MaterialCardView
        style="@style/MyCardView"
        ...>

W swoim stylu użyj shapeAppearanceOverlayatrybutu, aby dostosować kształt (domyślny promień narożnika to 4dp)

  <style name="MyCardView" parent="@style/Widget.MaterialComponents.CardView">
    <item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.MaterialCardView.Cut</item>
  </style>


  <style name="ShapeAppearanceOverlay.MaterialCardView.Cut" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">8dp</item>
    <item name="cornerSizeTopLeft">8dp</item>
    <item name="cornerSizeBottomRight">0dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
  </style>

Możesz także użyć:

<com.google.android.material.card.MaterialCardView
     app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Cut"
     ...>

Oto wynik:

wprowadź opis obrazu tutaj

Gabriele Mariotti
źródło
to nie działa z TabLayout. Moje narożniki nie są zaokrąglone. Moim wymaganiem jest to, że tylko górne rogi zakładek powinny być zaokrąglone, podczas gdy dół powinien pozostać kwadratowy. czy możesz mi w tym pomóc?
Tara
2
Jeśli stosujesz to tylko do pojedynczego komponentu, możesz zastosować nakładkę wyglądu kształtu bezpośrednio w XML bez potrzeby stosowania niestandardowego stylu. app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Cut"
Affian
9

Oto przykład jak to osiągnąć, gdy karta znajduje się na samym dole ekranu. Jeśli ktoś ma taki problem, po prostu zrób coś takiego:

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="-5dp"
    card_view:cardCornerRadius="4dp">

    <SomeView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp">

    </SomeView>

</android.support.v7.widget.CardView>

Widok karty ma ujemny dolny margines. Widok wewnątrz widoku karty ma taki sam, ale dodatni dolny margines. W ten sposób zaokrąglone części są ukryte pod ekranem, ale wszystko wygląda dokładnie tak samo, ponieważ widok wewnętrzny ma margines licznika.

koras
źródło
6

Możesz użyć tego XML do rysowania i ustawić jako tło widoku karty:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffffff"/>

    <stroke android:width="1dp"
        android:color="#ff000000"
        />

    <padding android:left="1dp"
        android:top="1dp"
        android:right="1dp"
        android:bottom="1dp"
        />

    <corners 
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp"/>
</shape>
Surender Kumar
źródło
To nie zadziała z cardView, którego potrzebujesz, aby wziąć układ, tj. Liniowy lub Względny i ustaw na nim tło. wtedy to zadziała.
Surender Kumar
1
ale co z efektem cienia?
Ravi Rajput
W tym celu możesz użyć listy warstw. Sprawdź ten link .
Surender Kumar
@SurenderKumar aree bhaii bhaii bhaaiii: D: D
Abhishek
6

Napisałem bibliotekę do rysowania do niestandardowej pozycji okrągłego rogu, wygląda to tak:

example.png

Możesz pobrać tę bibliotekę tutaj:

https://github.com/mthli/Slice

mthli
źródło
2

Musisz zrobić 2 rzeczy:

1) Zadzwoń setPreventCornerOverlap(false)na swój CardView.

2) Umieść zaokrąglony widok obrazu w CardView

Jeśli chodzi o zaokrąglanie widoku obrazu, miałem ten sam problem, więc stworzyłem bibliotekę, w której możesz ustawić różne promienie w każdym rogu . W końcu uzyskałem wynik taki, jaki chciałem poniżej.

https://github.com/pungrue26/SelectableRoundedImageView

Zaokrąglony ImageView wewnątrz CardView

김준호
źródło
1
I w ten sposób zmieniasz swoją aplikację na Androida w
iOS
0

możesz skorzystać z biblioteki: OptionRoundCardview

wprowadź opis obrazu tutaj

qinmiao
źródło
To nie pokazuje zaokrąglonych rogów ... Używam API> 23
Ravi Rajput
dodać wystarczająco dużo miejsca na margines?
qinmiao
Nie, widoki dziecka są zgodne z rodzicem
Ravi Rajput
Margines już jest
Ravi Rajput
ta biblioteka nie działa z aplikacją do koloru tła: optRoundCardBackgroundColor = "@ color / gray" usuwa efekty promienia narożnika
Kishan Donga
0

Możesz umieścić swój ImageView wewnątrz CardView i dodać te właściwości do ImageView:

android:cropToPadding="true"
android:paddingBottom="15dp"

W ten sposób pozbędziesz się zaokrąglonego dolnego rogu, ale pamiętaj, że wiąże się to z ceną odcięcia małej części obrazu.

omzer
źródło
0

UWAGA: To tutaj jest obejściem, jeśli chcesz uzyskać zaokrąglone rogi tylko u dołu i regularne rogi u góry. To nie zadziała, jeśli chcesz mieć różne promienie dla wszystkich czterech rogów widoku karty. Będziesz musiał użyć do tego materialnego widoku kart lub skorzystać z biblioteki innej firmy.

Oto, co wydawało się działać dla mnie:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#F9F9F9">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@drawable/profile_bg"/>

    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:id="@+id/cvProfileHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="32dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="280dp"
            android:orientation="vertical"
            android:background="@drawable/profile_bg"
            android:id="@+id/llProfileHeader"
            android:gravity="center_horizontal">

            <!--Enter your code here-->

        </LinearLayout>
    
    </androidx.cardview.widget.CardView>

</RelativeLayout>

W sumie są dwa widoki kart. Drugi widok karty to ten, który będzie miał zaokrąglone rogi (jak zwykle ze wszystkich stron) i wszystkie inne podglądy pod nim. Pierwszy widok karty powyżej jest również na tym samym poziomie (elewacji) i ma to samo tło, ale jest tylko około połowy wysokości drugiego widoku karty i nie ma zaokrąglonych rogów (tylko zwykłe ostre rogi). W ten sposób udało mi się uzyskać częściowo zaokrąglone rogi na dole i normalne na górze. Ale dla wszystkich czterech stron może być konieczne skorzystanie z materialnego widoku kart.

Możesz zrobić to odwrotnie, aby uzyskać zaokrąglone rogi u góry i zwykłe u dołu, tj. Pozwolić, aby pierwszy widok karty miał zaokrąglone rogi, a drugi widok karty miał zwykłe rogi.

Maks
źródło
-1

Najłatwiejszy sposób na osiągnięcie tego w Android Studio wyjaśniono poniżej:

Krok 1:
Napisz poniższą linię w zależnościach w build.gradle:

compile 'com.android.support:cardview-v7:+'

Krok 2:
Skopiuj poniższy kod do pliku xml, aby zintegrować rozszerzenie CardView.

Aby cardCornerRadiusdziałało, pamiętaj o umieszczeniu poniższej linii w układzie nadrzędnym: xmlns:card_view="http://schemas.android.com/apk/res-auto"

I pamiętaj, aby używać card_viewjako przestrzeni nazw do używania cardCornerRadiuswłaściwości.

Na przykład : card_view:cardCornerRadius="4dp"

Kod XML:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view_outer"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_gravity="center"
    card_view:cardBackgroundColor="@android:color/transparent"
    card_view:cardCornerRadius="0dp"
    card_view:cardElevation="3dp" >

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view_inner"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:layout_marginTop="3dp"
        card_view:cardBackgroundColor="@color/green"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="0dp" >
    </android.support.v7.widget.CardView>

</android.support.v7.widget.CardView>
Mit
źródło
4
Chce tylko tego na szczycie.
Heisenberg
2
Chociaż nie jest to odpowiedź na to pytanie, bardzo mi pomogło znaleźć niesamowity problem z przestrzeniami nazw! :)
Fragment
1
To nie jest odpowiedź na konkretne pytanie, ale pomogło wielu użytkownikom.
Mit
-1

Prostym sposobem na osiągnięcie tego byłoby:

1. Utwórz niestandardowy zasób tła (taki jak kształt prostokąta) z zaokrąglonymi narożnikami.

2. ustaw to niestandardowe tło za pomocą polecenia -

cardView = view.findViewById(R.id.card_view2);
cardView.setBackgroundResource(R.drawable.card_view_bg);

to działało dla mnie.

XMLUkład zrobiłem z góry lewy i prawy dolny promień.

<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:topLeftRadius="18dp" android:bottomRightRadius="18dp" />
</shape>

W Twoim przypadku musisz zmienić tylko topLeftRadius oraz topRightRadius.

Jeśli masz układ, który zachodzi na rogi widoku karty i może mieć inny kolor, możesz potrzebować innego pliku zasobów tła dla układu i w pliku XML ustawić ten zasób tła do układu.

Wypróbowałem i przetestowałem powyższą metodę. Mam nadzieję, że to ci pomoże.

Ankit Deshmukh
źródło
-2

Jeśli ustawiasz tło karty programowo, użyj go, cardView.setCardBackgroundColor()a nie, cardView.setBackgroundColor()i upewnij się, że używasz app:cardPreventCornerOverlap="true"w cardView.xml. To naprawiło to dla mnie.

Przy okazji, powyższy kod (w cudzysłowach) jest w Kotlinie, a nie w Javie. Użyj odpowiednika Java, jeśli używasz języka Java.

Joseph Magara
źródło