Cardview not showing shadow along bottom - android

I have the following xml for a cardview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:padding="2dp">
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="200dp"
android:layout_height="wrap_content"
card_view:cardCornerRadius="0dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">
<TextView
android:id="#+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Which results in these shadows which have no shading on the bottom at all
But I am trying to get something like this shadow, that more nicely surrounds the whole card.
I've tried changing the elevation to no avail, and searching on this issue seems to bring up nothing but people with no shadows at all issues which is not my case.
How can I get the shadows right?
Thanks.

You need to add this xml property in your card view
app:cardUseCompatPadding="true"

Adding clipChildren="false" to the parent LinearLayout should also work.

set elevation using card_view:cardElevation property

I was having the same problem until I remembered that if the parent is wrapping its content, then it will not wrap the shadow, so I gave the parent a bigger size than the child that way it will include the child and the shadow of the child
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="110dp"
android:layout_height="110dp">
<androidx.cardview.widget.CardView xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
android:layout_width="98dp"
android:layout_height="98dp"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:srcCompat="#drawable/manhattan" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

add these lines in your cardView
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"

Related

How to center an ImageView on the edge of a cardView?

I have a layout like this:
My xml for that layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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:fillViewport="true"
tools:context=".view.testviews.ProfileFragment"
android:background="#color/colorDarkGrey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginStart="20dp"
android:layout_marginTop="100dp"
android:layout_marginEnd="20dp"
app:cardCornerRadius="16dp">
<FrameLayout
android:layout_gravity="center_horizontal"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="-50dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profile_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:src="#drawable/user_image_placeholder"
app:civ_border_color="#FF000000"
app:civ_border_width="2dp">
</de.hdodenhof.circleimageview.CircleImageView>
</FrameLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
I'm trying to center the circleImageView on the edge of the cardView. But the top part of it is invisible. I looked up for similar questions, but they couldn't meet my requirements. How can I achieve this?
So I tried #PPartisan's solution, and it made it like this:
The code for that :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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:fillViewport="true"
tools:context=".view.testviews.ProfileFragment"
android:background="#color/colorDarkGrey">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="#+id/cardView2"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginStart="20dp"
android:layout_marginTop="150dp"
android:layout_marginEnd="20dp"
app:cardCornerRadius="16dp">
</androidx.cardview.widget.CardView>
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profile_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="90dp"
android:src="#drawable/user_image_placeholder"
app:civ_border_color="#FF000000"
app:civ_border_width="2dp"
>
</de.hdodenhof.circleimageview.CircleImageView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Don't make your ImageView a child of the CardView, as it will be clipped by its parent. Also, when considering XML, the drawing order is specified from top to bottom, which means that Views specified later in the XML will be drawn over any views that are specified earlier. This mean you should draw your CardView first, and then your CircleImageView. Your layout structure should therefore be:
<CardView.../>
<...CircleImageView.../>
I would also recommend you use CoordinatorLayout as it will be simpler to use features like guidelines to correctly align your various views.
Edit: Thankyou Adinia for pointing out in the comments that it is also necessary to set an elevation on the image to ensure it draws on top.
android:layout_gravity="center"
So your layout becomes:
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="80dp"
app:cardElevation="10dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/titelbild280x280"
/>
</android.support.v7.widget.CardView>

Add shadow to bottom of view

I've been having a lot of trouble with this layout.
Basically I have 2 linears, one that is slightly grey with that shadow on bottom and below another linear just white. My trouble here is adding that shadow to the end of the first linear. I tried "elevation" but that is now what i need since i want the shadow to be inside the linear kinda if the last 10dp are from a different color but I'm not getting it right.
This is my layout so far, i thought of putting a view inside the first linear but its not working that good.
Any ideas how to do this?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:layout_width="match_parent"
android:background="#f8f8f8"
android:layout_height="0dp">
<android.support.v7.widget.CardView
app:cardCornerRadius="10dp"
app:cardElevation="10dp"
android:layout_width="312dp"
android:layout_height="204dp"
app:cardBackgroundColor="#android:color/holo_red_light"/>
</LinearLayout>
<LinearLayout
android:background="#ffffff"
android:layout_weight="1"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="0dp">
</LinearLayout>
</LinearLayout>
Try using below line in the linearlayout under which your cardview is sitting.
android:elevation="8dp"
Let the cardElevation part in your cardView be as it is.
card_view:cardElevation="10dp"
card_view:cardPreventCornerOverlap="false"
Also just a suggestion :
If you're using android:layout_weight in both child linearLayout put android:weightSum="2" in your parent linearLayout as mentioned in answer given by #Ming Leung here
For more information on android:weightSum="2" you can refer to answers on this page
This page would help you for elevation in cardview
Hope that helps.
I was able to get it to work using a ConstraintLayout:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="312dp"
android:layout_height="204dp"
app:cardBackgroundColor="#android:color/holo_red_light"
app:cardCornerRadius="10dp"
app:cardElevation="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

RecyclerView content goes behind and not over TextView above

Consider this video from material design on drag & dropping items:
Material design reordering list
In the video you see a RecyclerView and above it a TextView with the text "Playlist". When the row is dragged up you see it going over the Playlist.
In my code the row goes behind the Textview. I've put RecyclerView's layout_height to match_parent. And I used a FrameLayout and placed the TextView below the RecyclerView. Why isn't it going over it?
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/general_margin"
android:text="#string/activity_bible_order_explanation"
android:layout_gravity="start|top" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:layout_marginTop="96dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
Use Constraint layout as a parent layout and add textview at the top by giving top constraints to the textview. then add
recyclerview's top constraint to the the bottom of textview and recyclerview bottom constraint to the bottom of parent then set height 0 it will work
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:padding="#dimen/general_margin"
android:text="#string/activity_bible_order_explanation"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/txtTitle"
android:background="#android:color/transparent"
android:layout_marginTop="96dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</androidx.constraintlayout.widget.ConstraintLayout>
Have you tried elevation? the problem might be that in the z axis the TextView is higher than the RecyclerView. try adding android:elevation="10dp" or higher... like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/general_margin"
android:text="#string/activity_bible_order_explanation"
android:layout_gravity="start|top" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="10dp" (if it doesn't work try maybe higher elevation, 20dp etc.)
android:background="#android:color/transparent"
android:layout_marginTop="96dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
Hope it works for you (: let me know!
What is the parent layout of this?
Because you set match_parent in recyclerview and list have many content that's why this issue facing.
Please give fix height or use relative layout and apply position above of text view in recyclerview
Problem with your layout code:
You're using a FrameLayout
Inside FrameLayout, you're also using top margin on your RecyclerView
android:layout_marginTop="96dp" <-- This causing the issue.
Solution:
You should LinearLayout instead of FrameLayout. And, also set LinearLayout's orientation as vertical.
android:orientation="vertical"
Also remove this line from your RecyclerView:-
android:layout_marginTop="96dp"
Solution Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Hello World"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
The issue is not that the dragged view is going behind the TextView but, rather, the dragged view is not being drawn outside the bounds of the RecyclerView. The effect is the same.
To allow the RecyclerView to draw outside of itself, set the following for the parent of the RecyclerView:
android:clipChildren="false"
For the RecyclerView set
android:clipToPadding="false"
That should solve the problem.
The RecyclerView is above the text view in your FrameLayout. Currently, it appears that the underlying TextView is above the RecyclerView as you have given the background for the RecyclerView as:
android:background="#android:color/transparent"
To make this work as normal, either remove this line or change the background of RecyclerView to any value other than transparent.
There is 1 more issue. You need to place the recycler view first. Try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<TextView
android:id="#+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Hello World"/>
</LinearLayout>

Constraint Layout does'nt constraint nested elements of other layouts

I'm trying to create a layout of a list which starts on the bottom of a button and it's 3/4 of screen's width.
Just like this:
First, I used nested Linear layouts a horizonal and a vertical one, but then I read here that Constraint layouts are more responsive and I was impressed and gave it a try.
So, I tried to replace the outer layout to a constraint layout but now, I can't constraint the list to start at the bottom of the button and it starts at top of the screen.
I tried to see what would happen if I replaced the whole linear layout with a button just to see that the attributes are correctly implemented and it worked, so I understood that the Constraint layout does'nt effect the sons of the Linear layout although it should be effecting the whole layout (as I see it).
my code is the following:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/settings_button"
app:layout_constraintTop_toBottomOf="#+id/settings_button">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
My current layout looks like this:
I really appriciate the helpers!
You need to change layout height of linear layout to 0dp, I will put here the layout for you. Also consider migrating to androidx :)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/settings_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/settings_button">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I think, that using match_parent as width or height of child and adding any constraint is wrong here.
Edited xml (change margins if you want):
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginTop="24dp"
android:backgroundTint="#FFFFFF"
android:src="#drawable/ic_menu_black_32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="#+id/list_linear_layout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="24dp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#+id/settings_button"
app:layout_constraintTop_toBottomOf="#+id/settings_button"
app:layout_constraintWidth_percent="0.75">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>

CardView goes on top of FrameLayout, but declared first

I have simple FrameLayout with support CardView as first item, and TextView as second, so TextView must be on top of inflated view. This works on pre-Lolipop but on 21+ card takes toppest place in layout, why that's so and how to fix this? Same thing with RelativeLayout.
Layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="20dp"
app:cardBackgroundColor="#ff0000"
app:cardUseCompatPadding="false"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="i am top view!"
android:gravity="center"
android:layout_gravity="center"
android:textSize="30sp"
android:textAllCaps="true"
android:textColor="#00ff00"
android:background="#0000ff"
/>
</FrameLayout>
In case someone gets here and the solution for setting elevation doesn't work for them (like in my case, where I needed to draw an image above the CardView and having a shadow on it was not acceptable), you can solve the issue by wrapping the CardView inside another FrameLayout. In the example provided, it would look something like this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- This is the added FrameLayout -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="20dp"
app:cardBackgroundColor="#ff0000"
app:cardUseCompatPadding="false"
/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="i am top view!"
android:gravity="center"
android:layout_gravity="center"
android:textSize="30sp"
android:textAllCaps="true"
android:textColor="#00ff00"
android:background="#0000ff"
/>
</FrameLayout>
I might be joining the discussion a bit late, but if you can afford giving up the CardView's elevation, you can just set the cardElevation property of the CardView in your XML layout to 0dp.
Like so:
app:cardElevation="0dp"
Just add your text view inside the card view, far as I know the z order is undefined inside a frame layout, but last laid out view should be drawn last.
This probably had to do with that card views in lollipop use elevation while they fall back on border drawing code pre lollipop.
This worked for me!
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Add this layout as parent of CardView -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="20dp"
app:cardBackgroundColor="#ff0000"
app:cardUseCompatPadding="false" />
</LinearLayout>
<!--Close parent layout-->
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#0000ff"
android:gravity="center"
android:text="i am top view!"
android:textAllCaps="true"
android:textColor="#00ff00"
android:textSize="30sp" />
</FrameLayout>

Categories

Resources