In RelativeLayout if layout_centerVertical or layout_centerInParent are true vertical margin (margin top ,margin bottom) does not work for me why?
<RelativeLayout>`
`
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="900dp"
android:background="#36648b"
android:src="#drawable/ic_star_black_24dp"
/>
</RelativeLayout>`
When you layout_centerInParent="true" your ImageView, it's being put exactly in center of parent view.
layout_marginTop="[##]dp" will affect your layout if an object is within 90px of the top of your view. Thus pushing the centered view down to keep at least 90px of space on top of it. So it isn't being ignored but it is not having the effect that you think it should have.
source: https://stackoverflow.com/a/7895380/5244435
In Xamarin.Forms 2.1, at least on Android, setting a control to height match_parent doesn't do anything.
Here is my setup:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="125px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/layoutComment">
<LinearLayout
android:id="#+id/layoutTest"
android:layout_width="20px"
android:layout_height="100px"
android:background="#android:color/holo_red_dark"
>
</LinearLayout>
<LinearLayout
android:layout_toRightOf="#id/layoutTest"
android:id="#+id/layoutLinesContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="50px"
android:minHeight="50px"
android:background="#android:color/holo_blue_dark"
>
That is basically:
- Relative Layout with height wrap_content
- Linear Layout A with fixed width and height
- Linear Layout B with a min height/width and match_parent for height
The reason I put a dummy LinearLayout A is to tell the parent that it should at least fit this height.
I expect LinearLayout B to have the same height as its parent or AT LEAST the height of LinearLayout A that came before it or the min height of the parent.
However, LinearLayout B gets height 50px instead which is its min height.
Here is a screenshot:
Red is A and blue is B. B should be the full height of the cell or at least the same as A or the min height of the parent, but instead it uses its min height 50px.
This problem only happens when I used a cell renderer, it doesn't happen if I use a cell without a custom renderer but with its view set to a custom view that has a custom renderer.
My renderer is not doing anything abnormal, it's simply inflating that layout file, setting the provided "convertView" to it then setting the different values.
What should I do? All I want is for LinearLayout B to have the same height as its parent...
I have a complex xml layout with part of it being:
...
<FrameLayout
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_weight="1" >
<ImageView
android:id="#+id/flexible_imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#drawable/gradient"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingTop="8dp" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</FrameLayout>
...
The height of the FrameLayout #+id/parent must be determined at runtime because it is displayed above many other views, and they must be shown in the layout. This way the FrameLayout fills the remaining space perfectly (using height="0dp" and weight="1" properties).
The ImageView #+id/flexible_imageview receives an image from the network, and it always shows with the correct aspect ratio. This part is already ok as well. This View is the largest and should determine the size of the FrameLayout #+id/parent.
The problem is that when the image is drawn, the width of the FrameLayout #+id/parent is not adjusted to wrap and be the ImageView #+id/flexible_imageview as it should be.
Any help is appreciated.
-- update --
I've updated the layout to clarify some of the missing parts, and to add the reasoning behind all of it.
What I want is to have an Image (ImageView #+id/flexible_imageview) with unknown dimensions to have, on top of it, a gradient and some text on top of the gradient. I can't set the FrameLayout #+id/parent dimensions to both wrap_content because there is more Views after this Image that must be shown. If there's not enough space in the layout, the Image (ImageView #+id/flexible_imageview) is reduced until it all fits in the layout, but it should maintain its aspect ratio, and the gradient/texts on top of it.
The #drawable/gradient is just:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="270"
android:endColor="#aa000000"
android:startColor="#00000000" />
</shape>
-- update 2 --
I added two images below to demonstrate what's happening, and what should happen:
Bug:
Correct:
If would help if you explained more about what you are trying to accomplish in your layout (not the layout itself but what should the user see on the screen and what are the other elements in the layout).
A FrameLayout with multiple children is usually a "code smell". Usually, FrameLayouts should have only one child element. So this makes me wonder whether there is something wrong with your design.
-- Edit --
If I understand correctly, you are trying the framelayout to wrap the content of the image but at the same time match the space left from the other layout views before/after the frame layout.
What is the parent view/layout of the frame layout?
I see a couple of problems with this design or your explanation:
You have framelayout width set to match parent, but you want to wrap the content of the image.
You want the imageView to be reduced but you are not taking into account the text views in the linear layout. You have them set to wrap content. So when the fame layout is small, you will not see all the textviews. (Unless you are resizing them as well somehow).
Sorry if this isn't helpful enough but it's difficult to understand what you are trying to accomplish with this layout. A sample use-case would help in providing you a better recommendation.
When a dimension (width / height) is MeasureSpec.EXACTLY adjustViewBounds will not effect it.
In your case, having android:width="match_parent" ensures that the image view is the size of the parent, regardless of adjustViewBounds.
It works to begin with because the height is wrap_content - the height is adjusted when the image is scaled to fill the width.
When you override the height to fit everything on the screen (this may not be a great idea to begin with), the width is still matching the parent and doesn't get adjusted. However, because the scale type is ScaleType.FIT_CENTER the image is scaled and positioned so that the entirety of it fits in the bounds of the ImageView (and centred.. hence the name).
If you turn on the debug option for drawing layout bounds, or look at your app using hierarchyviewer, you'll see that the image view is still matching the width of its parent.
There are a couple of ways you could do what you want.
Since you're already manually calculating the height, setting the width shouldn't be that hard.
Drawable drawable = imageView.getDrawable();
if (drawable != null && drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0) {
int height = // however you calculate it
int width = height / (getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth());
}
You might also get away with
<ImageView
android:id="#+id/flexible_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:minWidth="9999dp" />
Even if this works, you probably wouldn't be able to use it in a horizontal LinearLayout using weights any more (for example, if you wanted a landscape variant of the layout), or a number of other scenarios.
With the below layout (a portion of a larger layout), the container layout's visibility is set to "gone" until a button is clicked. On the button click, if the container_ll is not visible, it's set to visible, and a custom view is added to the reminderViews_ll container.
The views are being added, and the container_ll view is visible on button click. What follows is the width and height of various views after the button is clicked.
container_ll width 420, height 96.
lineDivider_view width 420, height 2 (as expected)
reminder_img width 36, height 36 (as expected, hdpi phone)
reminderViews_ll width 0, height 96 (argh)
<LinearLayout
android:id="#+id/container_ll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"
>
<View style="#style/lineDivider_view" />
<ImageView
android:id="#+id/reminder_img"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_horizontal"
/>
<!-- Stick the actual Reminder TVs + Del buttons in here dynamically -->
<LinearLayout
android:id="#+id/reminderViews_ll"
android:orientation="vertical"
android:gravity="center"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
/>
</LinearLayout>
I'm at a bit of a loss as to where to go from here. I was thinking invalidate layout, to force it to draw again after making the view visible, but that's never worked for me (seemingly), and if the reminderViews_ll can get a height of 96, then it can't be an issue with when it's calculating the dimensions of the LinearLayout.
I hope you have enjoyed reading this question as much as I have writing it. Any pointers, as always, appreciated.
The numbers you show look correct to me.
The container is width 420. The other views that are set to fill_parent or wrap_content take up all of the space (actually more). The Linear layout then goes to carve up the remaining space to any weighted views. Since there is no space to allocate, you get zero.
container_ll width 420
lineDivider_view - 420
reminder_img - 36
= -36
so this makes sense
reminderViews_ll width 0
There simply is no room to give it.
Why are you using a horizontal line divider in your horizontal view?
Ah, very confused: layout_width="fill_parent" and layout_weight="1.0" doesn't work?
I mean, layout_width="0dp" is guaranteed to be width 0, regardless of what you put into it, so that one will never do what you want. If you are using fill_parent and its still not working I'd question if you are adding your custom View into the right LinearLayout, because that really should work correctly.
I see that you've set android:layout_width for reminderViews_ll to 0 dp, you have to change this parameter, possibly dynamically if you want to. I don't really understand why you set it to 0 dp and then ask why it has zero width.
What is the difference between a View's Margin and Padding?
To help me remember the meaning of padding, I think of a big coat with lots of thick cotton padding. I'm inside my coat, but me and my padded coat are together. We're a unit.
But to remember margin, I think of, "Hey, give me some margin!" It's the empty space between me and you. Don't come inside my comfort zone -- my margin.
To make it more clear, here is a picture of padding and margin in a TextView:
xml layout for the image above
<?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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#c5e1b0"
android:textColor="#000000"
android:text="TextView margin only"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#f6c0c0"
android:textColor="#000000"
android:text="TextView margin only"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#c5e1b0"
android:padding="10dp"
android:textColor="#000000"
android:text="TextView padding only"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f6c0c0"
android:padding="10dp"
android:textColor="#000000"
android:text="TextView padding only"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#c5e1b0"
android:textColor="#000000"
android:padding="10dp"
android:text="TextView padding and margin"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#f6c0c0"
android:textColor="#000000"
android:padding="10dp"
android:text="TextView padding and margin"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#c5e1b0"
android:textColor="#000000"
android:text="TextView no padding no margin"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f6c0c0"
android:textColor="#000000"
android:text="TextView no padding no margin"
android:textSize="20sp" />
</LinearLayout>
Related
Gravity vs layout_gravity
Match_parent vs wrap_content
Padding is the space inside the border, between the border and the actual view's content. Note that padding goes completely around the content: there is padding on the top, bottom, right and left sides (which can be independent).
Margins are the spaces outside the border, between the border and the other elements next to this view. In the image, the margin is the grey area outside the entire object. Note that, like the padding, the margin goes completely around the content: there are margins on the top, bottom, right, and left sides.
An image says more than 1000 words (extracted from Margin Vs Padding - CSS Properties):
Padding is inside of a View.
Margin is outside of a View.
This difference may be relevant to background or size properties.
Padding is within the view, margin is outside. Padding is available for all views. Depending on the view, there may or may not be a visual difference between padding and margin.
For buttons, for example, the characteristic button background image includes the padding, but not the margin. In other words, adding more padding makes the button look visually bigger, while adding more margin just makes the gap between the button and the next control wider.
For TextViews, on the other hand, the visual effect of padding and margin is identical.
Whether or not margin is available is determined by the container of the view, not by the view itself. In LinearLayout margin is supported, in AbsoluteLayout (considered obsolete now) - no.
Below image will let you understand the padding and margin-
Padding means space between widget and widget original frame. But the margin is space between widget's original frame to boundaries other widget's frame..
Padding
Padding is inside of a View.For example if you give android:paddingLeft=20dp, then the items inside the view will arrange with 20dp width from left.You can also use paddingRight, paddingBottom, paddingTop which are to give padding from right, bottom and top respectively.
Margin
Margin is outside of a View. For example if you give android:marginLeft=20dp , then the view will be arranged after 20dp from left.
Padding is the space inside the border between the border and the actual image or cell contents.
Margins are the spaces outside the border, between the border and the other elements next to this object.
Sometimes you can achieve the same result by playing only with padding OR margin. Example :
Say View X contains view Y (aka : View Y is inside View X).
-View Y with Margin=30 OR View X with Padding=30 will achieve the same result: View Y will have an offset of 30.
In addition to all the correct answers above, one other difference is that padding increases the clickable area of a view, whereas margins do not. This is useful if you have a smallish clickable image but want to make the click handler forgiving.
For eg, see this image of my layout with an ImageView (the Android icon) where I set the paddingBotton to be 100dp (the image is the stock launcher mipmap ic_launcher). With the attached click handler I was able to click way outside and below the image and still register a click.
In simple words:
Padding - creates space inside the view's border.
Margin - creates space outside the view's border.
Let's just suppose you have a button in a view and the size of the view is 200 by 200, and the size of the button is 50 by 50, and the button title is HT. Now the difference between margin and padding is, you can set the margin of the button in the view, for example 20 from the left, 20 from the top, and padding will adjust the text position in the button or text view etc. for example, padding value is 20 from the left, so it will adjust the position of the text.
Margin refers to the extra space outside of an element. Padding refers to the extra space within an element. The margin is the extra space around the control. The padding is extra space inside the control.
It's hard to see the difference with margin and padding with a white fill, but with a colored fill you can see it fine.
In simple words:
padding changes the size of the box (with something).
margin changes the space between different boxes
Padding is used to add a blank space between a view and its contents.
Margin is used to add a space between different views.
For both padding and margin, we have two way to set those,
setting all sides with equal value
setting side specific values as per requirement
All sides with equal values:
You can use android:padding="15dp" for setting padding of 15dp all the sides
and android:layout_margin="15dp" for setting margin of 15dp all the sides
Sides with specific values:
Padding
android:paddingBottom Sets the padding at the bottom edge
android:paddingStart Sets the padding at the start edge means at the left side of view
android:paddingEnd Sets the padding at the end edge means at the right side of view
android:paddingTop Sets the padding at the top edge
Margin
android:layout_marginBottom Specifies extra space on the bottom side of this view.
android:layout_marginEnd Specifies extra space on the end side, means at the right side of this view.
android:layout_marginStart Specifies extra space on the start side, means at the left of this view.
android:layout_marginTop Specifies extra space on the top side of this view.