I'm trying to understand the UI behavior when parent layout_width/layout_height is set to wrap_content while in son layout_width/layout_height is set to match_parent. I found a old question in stackoverflow combining wrap_content on parent and fill_parent on child
But the post writer tried to achieve that all his sons (buttons in his case) will be at the same height, the response refereed to this purpose and not to how this conflict is set.
For example in the following code i have written:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="25dp"
android:layout_margin="#dimen/cardview_compat_inset_shadow">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textStyle="bold" />
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
I ran this code and CardView width take occupied all the screen (it seems that layout_width (match_parent) in CardView overcome on layout_width (wrap_content) in RelativeLayout. While CardView height occupied only both TextViews and not all the screen ( it seems that layout_width (wrap_content) in RelativeLayout overcome on layout_width (match_parent) in CardView
I can't find any "rule" how the conflict should be set.
I hope someone can help me understanding the logic or facts on how this conflict is set?
Related
I have a simple view as follows;
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="60dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_red_dark"
android:gravity="center">
<TextView
android:Text="Some text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.cardview.widget.CardView>
Even though both LinearLayout's height and width is clearly set to match its parent, it matches the CardView's width but wraps its content heightwise.
Why does this happen?
I would like to comment but I have no "enough reputation", anyway.
Have you added the dependecy 'androidx.cardview:cardview:1.0.0' in gradle file? Your code works fine for me, but, I dont know if you added the dependecies.
Having
android:layout_height="match_parent"
in both CardView and LinearLayout meant that LinearLayout's height is the same as CardView's parent's height which was smaller than 60dp. Then setting
android:minHeight="60dp"
in CardView changes its height to 60dp while leaving LinearLayout's height the same. I replaced these two lines in CardView to
android:layout_height="60dp"
and problem is solved.
I still think this is unintuitive but it looks like this is what happens.
I am using Xamarin Android, and I have a list view with row views that have the following content in them:
All of these views are wrapped in a PercentRelativeLayout, because I want to keep the widths proportional. So the issue I'm running into is that since the two layouts on the left are left empty and filled at runtime (there is absolutely no way around this) their height is measured out to 0, which then sets the Rowview height to 0, and that then sets the controls layout off to the right to have a height of 0, which then stretches to the size of the largest control inside of it (ex:)
I have tried:
Using layout weights and a height of 0 to allow the layout itself to stretch to fill the parent
Using layout weights on the controls themselves within the layout
Scrapping a layout altogether, and simply wrapping the image buttons in the PercentRelativeLayout, and using layout positions to position them properly
Using percentage based layout widths and heights within the children to fill the height (this only seems to work for the width, but not height)
Adding dummy views as padding to push the controls layout into position
Adding percentage based margins to the layout itself, the children, the padding dummy views, and every combination of those
Not one single thing I have tried has had any effect, the only thing that affects the height of the linear layout is simply hard-coding the height.
My question then is how can I tell this layout to occupy the full height of the rowview once everything has been measured? (Please let me know if you have any other questions to help address this, I'm happy to oblige)
EDIT #1: Here is my xml for the rowview:
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="400dp"
android:layout_height="match_parent"
android:id="#+id/LeadRowHolder">
<!--Tag Holder-->
<RelativeLayout
android:layout_height="wrap_content"
app:layout_widthPercent="80%"
android:paddingTop="10dp"
android:orientation="horizontal"
android:id="#+id/LeadTagLayout">
</RelativeLayout>
<!--Details Holder-->
<LinearLayout
android:layout_height="match_parent"
app:layout_widthPercent="80%"
android:orientation="horizontal"
android:id="#+id/LeadDetailsLayout"
android:layout_below="#id/LeadTagLayout"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:paddingRight="10dp"
android:paddingLeft="10dp">
<android.webkit.WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/leadShortDescription"/>
</LinearLayout>
<!--Controls Holder-->
<LinearLayout
android:layout_height="wrap_content"
app:layout_widthPercent="20%"
android:orientation="horizontal"
android:id="#+id/LeadControlsLayout"
android:layout_toRightOf="#id/LeadTagLayout"
android:gravity="center_vertical|center_horizontal">
<ImageButton
android:layout_height="50dp"
android:layout_width="50dp"
android:id="#+id/MenuCall3x"
android:background="#drawable/MenuCall3x"/>
<ImageButton
android:layout_height="30dp"
android:layout_width="20dp"
android:id="#+id/MenuFwd3x"
android:background="#drawable/MenuFwd3x"/>
</LinearLayout>
</android.support.percent.PercentRelativeLayout>
I've played a bit with your code, and the result seems good.
<android.support.percent.PercentRelativeLayout
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="wrap_content"
android:padding="5dp"
android:id="#+id/LeadRowHolder">
<!--Tag Holder-->
<RelativeLayout
android:layout_height="wrap_content"
app:layout_widthPercent="80%"
android:orientation="horizontal"
android:id="#+id/LeadTagLayout">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="this is a test"/>
</RelativeLayout>
<!--Details Holder-->
<LinearLayout
android:layout_height="wrap_content"
app:layout_widthPercent="80%"
android:orientation="horizontal"
android:id="#+id/LeadDetailsLayout"
android:layout_marginTop="5dp"
android:layout_below="#id/LeadTagLayout">
<android.webkit.WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:id="#+id/leadShortDescription"/>
</LinearLayout>
<!--Controls Holder-->
<LinearLayout
android:layout_height="wrap_content"
app:layout_widthPercent="20%"
android:layout_centerVertical="true"
android:orientation="horizontal"
android:id="#+id/LeadControlsLayout"
android:layout_toRightOf="#id/LeadTagLayout"
android:gravity="center_vertical|center_horizontal">
<ImageButton
android:layout_height="50dp"
android:layout_width="50dp"
android:id="#+id/MenuCall3x"/>
<ImageButton
android:layout_height="30dp"
android:layout_width="20dp"
android:id="#+id/MenuFwd3x"/>
</LinearLayout>
</android.support.percent.PercentRelativeLayout>
Let me know if this works for you at runtime (i've removed some background drawable files which you didn't provided to test this XML).
I've added a TextView inside the RelativeLayout to test his height
I am trying to get a better understanding of android layouts. In the following example I solved my problem but only through trial and error. I would like to understand WHY it worked.
I am setting up a "header" line inside another layout. I want the first part to use as much of the width as possible and the second part to use only what it needs. So I set layout_1 to have a weight of 1, layout_2 to have a weight of 0. Originally, I had both with layout_width of match_parent. That caused layout_2 to take the entire width and made layout_1 disappear. I finally fixed it by setting width on layout_2 to wrap_content. I understand that it makes sense for layout_2 to have width wrap_content. But don't understand why layout_2 match_parent would take the entire width when it has weight of 0 and layout_1 also has width match_parent.
An example of the code follows.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout android:id="#+id/header_layout_1"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="center" >
<LinearLayout android:orientation="horizontal"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some text"/>
</LinearLayout>
<!-- changing width on header_layout_2 to match_parent takes over layout, wrap_content gives me what I want -->
<LinearLayout android:id="#+id/header_layout_2"
android:orientation="horizontal"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="0">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some more text"/>
</LinearLayout>
</LinearLayout>
<!--end of header-->
</LinearLayout>
You can find lots of sources and blogs on The Internet about LinearLayout and layout_weight.
There are some useful websites:
https://ugia.io/2012/01/19/android-linearlayout-distribution-explained-weight-and-sizes/
http://www.101apps.co.za/index.php/articles/using-android-s-layout-weight-attribute.html
https://blog.stylingandroid.com/layout-weights-part-1/
https://www.mkyong.com/android/android-linearlayout-example/
First time asking a question, so please be gentle. :)
I'm trying to create a nested layout of ImageViews inside a LinearLayout. The parent LinearLayout needs to match the root view's width but have it's height determined by the 2 ImageView components it holds.
The 2 ImageView components need to be equally weighted for width (i.e. 50%) within the LinearLayout parent and have retain their proportional height.
However, whilst the width of the ImageViews are calculating correctly and the height of the image itself is correct, the height of the parent LinearLayout is not.
Below is the XML code I am using, apologies but I do not currently have enough reputation points to post images, which could make this difficult.
XML Code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/grey"
android:orientation="vertical"
android:padding="10dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#drawable/container_dropshadow"
android:orientation="horizontal"
android:padding="5dp"
android:weightSum="2" >
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:padding="5dp"
android:src="#drawable/barcode" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:padding="5dp"
android:src="#drawable/barcode" />
</LinearLayout>
</LinearLayout>
This is what I am getting
Any help would be greatly appreciated, apologies for any failing in etiquette,
Danny
You should add the following line for each ImageView:
android:adjustViewBounds="true"
For more info about the xml attribute see here
As it seems the GridLayout will always push its children to layout corresponding to their needs. for instance the following declaration:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="3"
android:orientation="vertical"
android:rowCount="4"
android:useDefaultMargins="true" >
...
<ImageView
android:id="#+id/main_image"
android:layout_column="1"
android:layout_columnSpan="2"
android:layout_row="3"
android:scaleType="fitStart" />
</GridLayout>
The GridLayout declares fill_parent and as such I would expect it to not overflow. The GridLayout should take the size of the parent which in this case is the window (full height). However in hierarchy viewer the GridLayout is set as Wrap_content for both vertical and horizontal.
As such the ImageView (which is a large image) or any text view will be push to fit themself and as such overflow the container.
This can be seen within the hierarchy viewer where the container grid view fits the parent:
while the image view overflow
Reading the documentation, I understand there is a need to set gravity. As far as I can try, I used all kinds of gravity options and image scaling options without much effect. Removing the margins with useDefaultMargins="false" does change the layout overflow which leads the issue towards gridlayout.
My question follows:
Is this a bug or am I using the GridLayout incorrectly
How can I force the GridLayout's children to fit their container and to fill
remaining spaces
The trick in other layouts is to give the first element an android:layout_weight="1.0" and nothing to the other elements. Why it works I have no idea, but it does. Here's a simple XML that displayed an ImageView, a TextView and a Button. Without the layout_weight parameter assigned to the ImageView the text and button were shifted down.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white"
android:orientation="vertical"
android:keepScreenOn = "true" >
<ImageView
android:id="#+id/imageView_surprise"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:scaleType="centerInside"
android:contentDescription="#string/accessibility_imageView_surprise"
android:layout_weight="1.0" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom" >
<TextView
android:id="#+id/textView_message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="24sp"
android:gravity="center_horizontal" />
<Button
android:id="#+id/button_share"
style="#style/button_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>