Dopóki nie spróbujesz rozszerzyć CardView
klasy Androida , nie możesz dostosować tego atrybutu z XML
.
Niemniej jednak istnieje sposób na osiągnięcie tego efektu.
Umieść jeden CardView
wewnątrz drugiego CardView
i zastosuj przezroczyste tło na zewnątrz CardView
i usuń jego promień narożnika ( "cornerRadios = 0dp"
). Twoja wewnętrzna CardView
bę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 CardView
zostanie 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:
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
.
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>
źródło
innerRadius
,shape
orazthicknessRatio
app:cardCornerRadius="40dp"
będzie działać.Możesz użyć standardu
MaterialCard
zawartego 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
shapeAppearanceOverlay
atrybutu, aby dostosować kształt (domyślny promień narożnika to4dp
)<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:
źródło
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Cut"
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.
źródło
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>
źródło
Napisałem bibliotekę do rysowania do niestandardowej pozycji okrągłego rogu, wygląda to tak:
Możesz pobrać tę bibliotekę tutaj:
https://github.com/mthli/Slice
źródło
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
źródło
możesz skorzystać z biblioteki: OptionRoundCardview
źródło
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.
źródło
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.
źródło
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
cardCornerRadius
dział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_view
jako przestrzeni nazw do używaniacardCornerRadius
wł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>
źródło
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 -
to działało dla mnie.
XML
Ukł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.
źródło
Jeśli ustawiasz tło karty programowo, użyj go,
cardView.setCardBackgroundColor()
a nie,cardView.setBackgroundColor()
i upewnij się, że używaszapp: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.
źródło