This question might be trivial to some of you.
I am facing a dumb issue working with designers and developers.
According to the designers the android button from material design has a particular style, default button style (top button in the image).
Designer defines a fix height and width 50dp for instance. So they expect to have a button of those dimensions.
But developers when using a default android button, the default button contains margins.
So we use a custom drawable background, in this case the button has the expected dimensions (button a the bottom). But the style is not exactly the same (very few differences, but still). We could try to imitate the default style, but I am not sure it is worth.
So how do you do when working with designers that just use a default button from the material android patterns and expect to have the exact size?
You consider size with margins? You create a background style? You try to imitate as much as you can the default button? others?
and this is the simple code used
<Button
android:layout_width="50dp"
android:layout_height="50dp"
/>
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/my_button_shape"/>
tha parameter margin is deferent then hight and width. margin determines the distance from point A to the button.
to et the height and width you can use in your xml file the following code:
example:
<Button
android:id = "#id/myButton"
android:layout_width = "50dp"
android:layout_hight = "50dp"
android:text = "test"
android:layout_marginTop = "100dp"
/>
the margin top 100dp determines that my button is 100dp from the top of my layout but the width and height determines the button size
The problem is 9-patch for the default button already includes a margin, so visually the button looks smaller than expected. Possible solutions include negative margins or duplicating the default 9-patch and removing the margin, but each option has its own drawbacks.
As #egonzal says, it would be interesting to know other developers solutions when facing the problem.
I am a bit of an android noob, and have been struggling with this problem for far too long.
What I'm aiming for:
Two ImageViews. The first will be the width of the screen, and drawn to match the proportions of its src image (so far so easy). The second ImageView needs to be scaled, so that its width is a fixed multiple (between 0 and 1) of the first image.
I will ultimately then need to be able to touch-drag the second smaller image around on top of the first, fixed image, although this part is not the point of this question.
This will all generally be done programmatically, as the src images and the scale multiple are not known until runtime.
What I've tried: I can overlay two ImageViews in a RelativeLayout, using alignParentTop and so on. This works fine, but I can't see how to scale the images in this case.
I can alternatively scale the two ImageViews using a LinearLayout, by setting their layout_weights to 1 and the scale multiple respectively. In this case I can't get the images overlapping however (not strictly true - I have managed this with negative margins, but it is a very hacky solution and will make it almost impossible to implement the movement of the top image later).
So my question is: is there a way to fix either of the two solutions I have tried to implement? Or is there perhaps a better way to approach the problem?
(I'm not necessarily looking for an answer in code, just the approach I should take)
Well with what I understand,
You can use a Constraint Layout
Place 1st ImageView on your desired place
with constraints to your parent
Place Second ImageView on your desired place
with constraints to the parent (NOT WITH ANY OTHER CHILD VIEW)
The Approach is if you put a SubView In ConstraintLayout with Constraints to Parent, you can manipulate (Scale / translate) without any effect on other views.
to change the position of the View in runtime you can use
view.setTranslationX() and view.setTranslationY();
you can also create a view programmatically with Constraints to the parent
(my personal preference)
you can use this to overlay different Views in ConstraintLayout
<ImageView
android:id="imageID1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="yourImageStable"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
// put your own constraints-
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</ImageView>
<ImageView
android:id="imageID2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="yourImageUnStable"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
Note: This two constraint value will draw an ImageView from the Top-Left
corner of the Parent View (on Position x=0, y=0)
Remember: the View which you want to overlay should be written next to the other,
like here ImageID2 can overlay ImageID1.
</ImageView>
This question already has answers here:
Difference between a View's Padding and Margin
(15 answers)
Closed 4 years ago.
I have referred questions on SO. ALso checked an answer:
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.
Also, more on padding and margins from:
http://developer.android.com/reference/android/view/View.html
http://developer.android.com/reference/android/view/ViewGroup.MarginLayoutParams.html
But what is the difference fundamentally between padding and margins ? Would the behaviour differ depending on O.S. and devices?
I have a normal, simple layout. No problem with code, have used layout folders - layout and layout-sw600dp plus drawables-4dpi. Can't make layout without margin or padding, which one is more appropriate?
Margin
Margins make up the vertical and horizontal areas between elements. If elements have no margins around them, they will bump right up against each other. In other words, he space outside of, or between, elements is what comprises the margin areas.
Padding
The padding of an element is the horizontal and vertical space that’s set around the content area of the targeted element. So padding is on the inside of a box, not the outside.
Padding is for inside/within components. Eg. TextView , Button, EditText etc.
Eg. space between the Text and Border
Margin is to be applied for the on-outside of the components.
Eg. space between left edge of the screen and border of your component
Visual representation is great in : Difference between a View's Padding and Margin
With Padding, i have seen a difference in 2.2, 2.3 and say 4.3, 4.4
in such cases:
<RelativeLayout 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="ASDFGHJKL" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:text="#string/hello_world" />
</RelativeLayout>
Also, check the use of dimens:
http://developer.android.com/guide/topics/resources/more-resources.html
In Simple words .. if you want to take your widget like TextView, EditText far away from other. You should use margin from top,right,left,bottom.
By increasing padding it will increase the inner spacing not making the widget far apart from others..
Like 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.
Margin: Between border and its parent layout
Padding: Between content and border
refer to this
The difference between margin and padding and use cases are clearly explained by +Nick Butcher in Udacity's video. Here's the excerpt:
...if you want the touchable area or the background of the object to be enlarged, then use padding, otherwise use margin...
what is the difference fundamentally between padding and margins ?
For the differences - Rohan Khandwal has shared a very perfect link.
Would the behaviour differ depending on O.S. and devices?
Now If we are talking about the behaviour of the view which has been given diffrent margins & padding. Then It will definitely look diffrent in different devices with diffrent resolutions.
Thats why we are given diffrent dimen/values/layout folders which have their own meanings.
The difference between android margin and padding is that even though the text is how much sp you want away from the edge, margin is not spaced or colored in. It is only the text and the color you set with it all "alone". With padding though, the text is away from the edge of the screen just like margin but, in padding the text is away and all the space between the text and the edge of the screen is filled in with the color or any text preference you chose to be. This is the difference between android margin and android padding.
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.
Padding Increases the size of the view where as margin doesn't because it is outside the view
The padding is expressed in pixels for the left, top, right, and bottom parts of the view. Padding can be used to offset the content of the view by a specific amount of pixels.
For instance, a left padding of 2 will push the view's content by 2 pixels to the right of the left edge.
Padding can be set using the setPadding(int, int, int, int) method and queried by calling getPaddingLeft(), getPaddingTop(), getPaddingRight(), and getPaddingBottom().
Margins are the spaces outside the border, between the border and the other elements next to this view.
Note that, like the padding, the margin goes completely around the content :there are margins on the top, bottom, right, and left sides.
Margin can be set using the setMargins(int left, int top, int right, int bottom) method.
I've noticed a strange behavior in RelativeLayout when you align a view to the layout's side
(any side) and having a large margin in the same direction.
I have 2 RelativeLayouts that each contains a simple view. In one layout that view is align to the top and left, in the other to the bottom and right:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="110dp"
android:layout_gravity="center"
android:background="#ff555555" >
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:background="#aa8711" />
</RelativeLayout>
<RelativeLayout
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginBottom="110dp"
android:layout_gravity="center"
android:background="#ff555555" >
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#998877" />
</RelativeLayout>
</FrameLayout>
It looks like this:
I added 130dp of margin in each direction of parent alignment. That means that the view should be only partially visible in the layout. This is what happens:
As you can see, the views are now smaller than the original size, as the get pushed on the "walls" of the layout. Next I tried to give a margin that is bigger than the layout, so I gave them 151dp of margin in the aligned directions. It looked like this:
The bottom-right aligned view now "breaks out" of the layout and is again the same size as it was originally. On the other hand, the top-left aligned view is too in its original size, but completely inside the layout instead of outside of it.
I've tried this individually and in every permutation of alignment and got the same results.
Question one: Can anyone explain this inconsistent behavior?
I tried the same thing, this time comparing the behavior to that of a FrameLayout.
Initial setup:
and after margins:
The FrameLayout keeps the view in its original size at all time and simply lets the view "exit" it. I tried to give a negative margin in the opposite direction of at least the size of the view that should be outside of the RelativeLayout and saw the same behavior as happens in the FrameLayout by default.
Question 2: Can anyone explain the difference in behavior and the opposite negative margin effect?
Why should it be only partially visible?
I added 130dp of margin in each direction of parent alignment. That
means that the view should be only partially visible in the layout
The box is getting smaller because preference is given to keeping it inside the parent layout at all costs, while still applying the margin. Since the smaller child view is 50dp, you have added a margin of 130dp, the total width it needs is 180dp but the parent view itself is only 150dp wide. That is 130dp + 50dp > 150dp - the child plus the margin cannot fit inside the parent.
This is "silly input" and the XML interpreter is doing its best to render something. The decision that it makes in the end is that it can alter the width of the child box and still respect the margin constraint. Or mathematically
130dp + 20dp == 150dp
Basically it shrinks the width of the inner box down from the assigned 50dp to 20dp so that it can fit inside the parent with its added margin. And if you look at the size of the square 20dp looks about right. It is 60% smaller.
This is clever behaviour by the interpreter because as screen sizes change and it runs into issues like this it should always preserve the margin constraint opposed to the width constraint.
In summary the interpreter is doing its best to fit the box, and its margin inside its parent, to do so it is making the box smaller. It is choosing to preserve the given margin, over the given width - probably because of the top-most parent layout.
When you say "this should be partially visible" I assume you think the child will render half inside the parent bounds, and half outside the parent bounds, similar to windows form development. This is not the case though because it will always try to keep children inside the bounds of parents in most layouts.
The choices that are made depend on the top-most parent layout too, some layouts may prefer to preserve the width of the child box rather than the margin, or even render the box outside of the parent's bounds.
In the second case:
so I gave them 151dp of margin in the aligned directions.
You are going beyond the point in which the interpreter can shrink the image. It cannot shrink the image to negative 1. That is
50dp + 151dp > 150dp
It can't meet this margin constraint you have given it so the behaviour is fairly unpredictable. At a guess I would say it knows it cannot keep both the images, along with their margins inside the parent. So it simply renders one inside and one outside.
Once again, this is silly input and the interpreter is doing its best to render what you want.
Can anyone explain the difference in behavior and the opposite negative margin effect?
A negative margin will do different things depending on the type of layout in its parent, and that it is aligned too. In a frame layout it will behave differently to a relative layout. Usually if you are looking at negative layouts you have chosen the wrong parent containers and you are trying to hack it to get it to look right.
I don't know what you are trying to do exactly but maybe you just need tweak your thought process a little and think of the poor interpreting trying to understand the XML you give it.
You wouldn't be the first person to be utterly confused by android's XML layouts. Nesting layouts inside layouts is always confusing and the behaviour changes depending on a number of things like margins, alignments, widths, etc. Most people I know simply muck around with it until it is right and try different container layout types to get the right design.
In short, avoid playing with margins (like flash or winforms) and play without layout types instead to get things where you want them.
hope that helps, sorry for tl;dr.
I have custom row for data representation but in first text when text is long it is in two lines but second line is half cut by height (like text view doesn't wrap content)
<TextView
android:id="#+id/txtDate"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:singleLine="false"
android:maxLines="3"
style="#style/row"
android:layout_weight="1"/>
<TextView
android:id="#+id/txtTime"
android:layout_width="0dip"
android:layout_height="wrap_content"
style="#style/row"
android:layout_weight="1"/>
<Button
android:id="#+id/imbDetail"
android:layout_width="36dip"
android:layout_height="36dip"
android:background="#drawable/selector_detail_arrow" />
How to make that has height enough to show all content ?
your height is wrap content which means it'll wrap them to give the shortest view of text. Use fill_parent to display everything.
android:layout_height="fill_parent"
Either attribute can be applied to View's (visual control) horizontal
or vertical size. It's used to set a View or Layouts size based on
either it's contents or the size of it's parent layout rather than
explicitly specifying a dimension.
fill_parent (deprecated and renamed MATCH_PARENT in API Level 8 and
higher)
Setting the layout of a widget to fill_parent will force it to expand
to take up as much space as is available within the layout element
it's been placed in. It's roughly equivalent of setting the dockstyle
of a Windows Form Control to Fill.
Setting a top level layout or control to fill_parent will force it to
take up the whole screen.
wrap_content
Setting a View's size to wrap_content will force it to expand only far
enough to contain the values (or child controls) it contains. For
controls -- like text boxes (TextView) or images (ImageView) -- this
will wrap the text or image being shown. For layout elements it will
resize the layout to fit the controls / layouts added as its children.
It's roughly the equivalent of setting a Windows Form Control's
Autosize property to True.
check this answer: Here