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.