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

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.


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>

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


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.


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>

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


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


1
I w ten sposób zmieniasz swoją aplikację na Androida w
— iOS


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.


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.


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

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.


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.