I'm making a weather app with material cards and its shadows.
I've found a way to center them using a Linear Layout, but it cuts off the shadows.
How can I prevent this? Is there a way to align them without using a linear layout or a frame layout?
Here's my layout code:
I used a FrameLayout as root, there's my LinearLayout containing both material cards, I just wanted them to be centred as a group, if you know another way to do this please tell me!
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="#+id/img_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/background"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:fontFamily="cursive"
android:layout_gravity="center_horizontal"
android:layout_marginTop="25dp"
android:textSize="50sp"
android:textColor="#FFF"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your location's weather in a touch!"
android:layout_gravity="center_horizontal"
android:layout_marginTop="90dp"
android:textSize="17.3sp"
android:textColor="#color/colorPrimaryText"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="270dp"
android:layout_height="140dp"
android:layout_gravity="center_horizontal"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="5dp">
<TextView
android:id="#+id/tv_temperature"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:padding="16dp"
android:text="30°C"
android:textColor="#color/colorPrimaryText"
android:textSize="50sp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cv_data"
android:layout_width="270dp"
android:layout_height="140dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="5dp">
<TextView
android:id="#+id/tv_conditions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:padding="16dp"
android:text="Scatted Clouds"
android:textColor="#color/colorPrimaryText"
android:textSize="30sp" />
</android.support.v7.widget.CardView>
</LinearLayout>
<ProgressBar
android:id="#+id/pb_loading"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_gravity="center"
android:elevation="20dp"/>
<TextView
android:id="#+id/tv_city_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"
android:padding="20dp"
android:fontFamily="sans-serif"
android:textColor="#FFF"
android:textSize="20sp"/>
It looks like your layout would be better as a ConstraintLayout instead of a FrameLayout, but we can still make what you have work.
The problem is that (on newer Android versions), the shadows for a CardView are actually drawn outside the view's bounds. Normally this is fine, but if the CardView is inside a parent, that parent can clip the shadows if the parent doesn't have enough room to show the shadows.
In your case, the "easy fix" is actually extremely easy. Change your LinearLayout's width to match_parent; this will give the cards room to draw their shadows.
Edit
What I said above will solve the shadows on the sides of each card, but won't solve the shadows above the top card or below the bottom card. Again, in the spirit of a quick fix, I'd suggest adding these attributes to your LinearLayout:
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:clipToPadding="false"
You need to change height and add change layout_gravity to gravity, like the code bellow:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical">
It probably will solve your problems =]
If you want to improve your code, I suggest you not to set fixed width and height, it cand bring you problems in some devices. You can also load xmlns:card_view only once, at your LinearLayout, that it's your very first tag
Related
The button at the bottom, Map/filter. It's from the expedia app. What kind of button is it? Can a FAB be overriden to have two button?
My best guess, as someone who has made an extremely similar widget myself, is that this is neither a FAB nor even a Button at all. It's probably just a floating ViewGroup with two clickable areas (maybe a LinearLayout holding two TextViews, for instance).
You create it by using a FrameLayout (or spiritual subclass like CoordinatorLayout) to host your main content view, and then your "button" view group on top of that. CardView is a great way to get rounded corners and elevation on all Android API levels:
<?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="match_parent">
<!-- insert your content here -->
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginBottom="32dp"
android:layout_gravity="center_horizontal|bottom"
app:cardCornerRadius="24dp"
app:cardElevation="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="48dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="12dp"
android:gravity="center"
android:drawableStart="#drawable/icon_map"
android:drawablePadding="6dp"
android:textColor="#00f"
android:textSize="18sp"
android:text="#string/label_map"
android:fontFamily="sans-serif-medium"/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:background="#ccc"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="12dp"
android:gravity="center"
android:drawableStart="#drawable/icon_filters"
android:drawablePadding="6dp"
android:textColor="#00f"
android:textSize="18sp"
android:text="#string/label_filters"
android:fontFamily="sans-serif-medium"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
I have read several answers on how to align a card view horizontally. I am trying to achieve the following:
Desired Result
This is so far the code I have written (I have followed around 20 answers from different posts, none which have helped me. The problem is the margin or space on the left and the right, I need that space, but the card view expands the whole width.
<RelativeLayout
android:id="#+id/relativeLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true">
<TextView
android:id="#+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignStart="#+id/mProjectCDCNumCardView"
android:layout_marginStart="7dp"
android:layout_marginTop="7dp"
android:text="DETAIL"
android:textColor="#000"
android:textSize="16sp" />
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/mProjectCDCNumCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="13dp"
card_view:cardCornerRadius="2dp"
card_view:contentPaddingLeft="50dp"
card_view:contentPaddingRight="#dimen/activity_horizontal_margin"
card_view:contentPaddingTop="20dp"
card_view:contentPaddingBottom="#dimen/activity_vertical_margin"
android:background="#drawable/cardview_normal"
android:layout_centerHorizontal="true"
android:layout_below="#+id/textView8">
<EditText
android:id="#+id/mProjectCDCNumEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#drawable/editborder"
android:hint="Project Number"
android:inputType="textPersonName"
android:padding="10dp" />
</android.support.v7.widget.CardView>
<TextView
android:id="#+id/mProjectAddressLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#drawable/editborder"
android:layout_below="#id/mProjectCDCNumCardView"
android:ems="16"
android:padding="10dp"
android:hint="Location"
android:textColor="#000"
android:textSize="18sp"
android:drawableRight="#drawable/left_arrow"/>
</RelativeLayout>
Thanks!
little late to the party here but I really like using ConstraintLayouts. It is super easy to center Views in them.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="200dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
... Content ...
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
This code will center CardView inside of the ConstraintLayout that has the same width as parent. The CardView has width of 200dp and thanks to the constraints it will be centered horizontaly in the Layout.
More info about ConstraintLayout.
You just add android:layout_marginStart and android:layout_marginEnd to your cardview.
The height attribute of your layout must be match_parent.
In your CardView component, add a LinearLayout component.
Add android:gravity="center_horizontal" property to your LinearLayout.
In your LinearLayout component add your EditText component.
<android.support.v7.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardUseCompatPadding="true"
app:cardElevation="4dp"
app:cardCornerRadius="3dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<EditText
android:id="#+id/mProjectCDCNumEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#drawable/editborder"
android:hint="Project Number"
android:inputType="textPersonName"
android:padding="10dp" />
</LinearLayout>
Why is my Linear Layout not taking up the whole space inside the CardView?
When I use the preview and expand the LinearLayout to match the CardViews width it sets the width to match_parent (which I tried manually) but then goes back to how it is now.
In other words: I want the red background to go all the way to the right and also the right TextView aligned to the right.
<LinearLayout 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:id="#+id/itemCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginBottom="3dp"
android:layout_marginTop="3dp"
android:background="#color/Mat"
android:padding="3dp"
app:cardElevation="4dp"
app:cardCornerRadius="1dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#color/Mat"
android:orientation="horizontal"
android:padding="3dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<TextView
android:id="#+id/textView2"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="#drawable/circle"
android:gravity="center"
android:text="DEU"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Frau Hardt"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/textView4" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="O03"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Edit: After removing the min-width and setting the width of the whole layout to match_parent it goes all the way to the right.
Now how do I get to center the TextView with the name horizontally and have the text view on the right align to the right of the whole layout?
I included a picture because it looks all nice right next to each other. I hope the code (especially since it's not a whole lot) doesn't have to be as text. If so I'll edit the question of course!
Thanks!
Make your middle TextView as this;
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
... />
It fills the remaining middle space.
You also should use match_parent instead of fill_parent since it is deprecated.
I have a TextView and a square ImageView that I would like to show in a horizontal linear layout. Each should take half of the parent view's width and the height should fit the content (i.e. the image). The text should be centered vertically.
Additional constraint is that the image should not grow beyond a given maxWidth (= maxHeight), and excess width should be made available to the TextView. Obviously, this conflicts with the 50/50 rule above. Is there a way to prioritize the constraints, i.e. allow the image to take half of the space unless it exceeds a given size?
These are layouts I tried:
The first one nicely stretches the left side to the available space. But the image takes more than half of the width as its layout_weight is not specified (as in image below).
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Some text."/>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="200dp"
android:adjustViewBounds="true"
android:src="#drawable/image" />
</LinearLayout>
When I add layout_weight to the ImageView it always takes half of the width and ignore the maxWidth (see image below).
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="200dp"
android:adjustViewBounds="true"
android:src="#drawable/image" />
Enclosing the ImageView in another LinearLayout enables the maxWidth again, but the enclosing LinearLayout still takes half of the available space (see image below).
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="200dp"
android:adjustViewBounds="true"
android:src="#drawable/image" />
</LinearLayout>
Another option I have found for similar scenarios is to use a RelativeLayout with an invisible view as a center divider, but that locks the division to 50/50 (or wherever the divider is placed).
Okay, gonna go on ahead and post the xml I created, it's pretty much simple, it does most of your conditions.. One thing I'm having trouble with is the part where each view takes half of the parent view's width. Hope this still helps you in some way.
sample_layout.xml
<?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="wrap_content"
android:layout_margin="2dp"
android:background="#android:color/darker_gray">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/img_sample"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="2dp"
android:layout_toLeftOf="#id/img_sample"
android:background="#color/colorPrimary"
android:gravity="center_vertical"
android:text="Some text." />
<ImageView
android:id="#id/img_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="2dp"
android:adjustViewBounds="true"
android:maxWidth="200dp"
android:src="#drawable/sample_img" />
</RelativeLayout>
Here is a sample screenshot:
If ever you figure out how to the the half of each thing, kindly comment it here, It'd be nice to know about it for possible future use. :)
PS: Have you considered doing the half of each thing programatically? Like checking the LayoutParams then dynamically setting weightSum and the layout_weights.
Sample Image retrieved from this link
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_weight="1"
android:adjustViewBounds="true"
android:background="#color/blue"
android:src="#drawable/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:layout_toStartOf="#id/imageView"
android:background="#color/colorPrimary"
android:padding="10dp"
android:text="Some text. " />
</RelativeLayout>
It won't be a perfect solution in term of performance. But you can achieve it by playing with FrameLayout and ImageView.
Here is the output:
Layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/textGray"
android:orientation="vertical">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/skyBlue">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/white">
<ImageView
android:id="#+id/imageView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="200dp"
android:src="#drawable/ic_settings"
android:visibility="invisible" />
<TextView
android:id="#+id/TextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:text="!" />
</FrameLayout>
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="200dp"
android:src="#drawable/ic_settings" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
In order to achieve desire behaviour, You would have to set same images to both imagesviews in this layout. one of them is invisble, It is just helping to make parent with same width and heights which would lead us to create TextView with same dimensions.
Note: If you want to change textView alignment, you can do it with layout_gravity or gravity.
I'm trying to define layout for listview item that looks like attached image (made in Photoshop). What layout(s) should I use?
i propose a LinearLayoutwith horizontal orientation first, and inside a RelativeLayoutto place other views from left / top to right / bottom using attributes : layout_alignParentTop, layout_alignParentBottom, layout_alignParentLeft, layout_alignParentRight etc ...
I would suggest using a RelativeLayout for this. Otherwise, you may up with too much nesting. I'm not going to write the layout but you should look through the RelativeLayout Docs and see all the possible properties you can give Views. You may possibly end up with child LinearLayouts also and that's ok. But I would use RelativeLayout for the parent.
If you are undecided a good thing to do is to draw it out really quick in xml how you think each might go and see with ViewGroup seems like the most efficient. Sometimes its hard to say until you get going on it by either writing the xml code or at least some pseudocode.
You only need to play now with paddings and margins.
<?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" >
<LinearLayout
android:id="#+id/gray_layout"
android:layout_width="40dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#888888"
android:layout_alignParentLeft="true"
android:gravity="center_vertical">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="AUG"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="18"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2011"/>
</LinearLayout>
<View
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#000088"
android:layout_toRightOf="#id/gray_layout"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="30dp"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/divider"
android:text="Title"
android:layout_marginBottom="5dp"
android:layout_alignBottom="#id/divider"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#id/divider"
android:text="18. aug 23:49"
android:layout_marginBottom="5dp"
android:layout_alignBottom="#id/divider"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/divider"
android:text="Short msg"
android:layout_marginTop="10dp"
android:layout_alignTop="#id/divider"/>
<ImageView
android:id="#+id/info_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="#ff0000"/>
<ImageView
android:id="#+id/arrow_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_above="#id/info_button"
android:layout_toLeftOf="#id/info_button"
android:background="#00ff00"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/arrow_button"
android:layout_toLeftOf="#id/info_button"
android:layout_alignLeft="#id/arrow_button"
android:gravity="center_horizontal"
android:text="30" />
</RelativeLayout>
You can nest multiple LinearLayouts with different orientation to achieve this.