I want to set a background image in my app, which will fill all screen and scale if needed, so I set it in my main_layout.xml like that:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:id="#+id/imageView"
android:src="#drawable/bg_iphone_6_plus" />
and it looks like this
not very good, I need this picture to adjust in width too, actually.
ok, so this works in most cases and with all API's higher 16, but when I run my app on api lower 16 ( minTargetSdk=14 ), I see this:
I have no idea why it shows like that, I have already tried this tutorial, and replaced ImageView with com.inthecheesefactory.thecheeselibrary.widget.AdjustableImageView
but it didn't change anything at all
If your background image is only this gray picture with gradient in the middle, then move the drawable to android:background to parent container. You don't need additional ImageView for that.
But, if you want to set bitmap as background and keep ratio of this image on different devices and orientations, you should use ImageView and its android:scaleType with e.g. "centerCrop" (which usually is the best choice for backgrounds).
Try with replacing android:src property with android:background in your ImageView layout. I think that will solve your issue. If it is still causing the issue then please let me know.
Is there a way in android to make the margins extend to fill screens? The problem is that layouts I build for Nexus devices look great, but then when previewing on a regular device without the bottom controls there is an ugly space between the rest of the layout and the bottom. I would like the margins between items to increase when there is available space.
Pictures are added below. Sorry for the ugly cutting of some of the fields, I'm unable to show them at this time to due a contract. Notice how "advacned search" is far from the bottom, I would like the vertical margins between all items to increase and make sure this doesnt happen.
How can I acheive this in a relative layout?
Try using LinearLayout and empty Views between each of the items.
just empty View:
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#android:color/transparent" />
I'm trying to do my first app.
I'm doing a layout that contains four rows. There will be a title in the first row (10% height), two images in the second (40% height), two images in the third (40% height) and a button in the fourth (10% height).
Right now, I'm using a linear layout with vertical orientation. Using weight sum and weight, I have the correct proportion on each row.
But, if I use in the second and the third rows linear layout weight, then I get a warning about nested weights and bad performance. I understand the bad performance issue, but I don't know how to solve my problem without them.
I need each image be a 50% of its parent width.
Thanks for your help.
EDIT: That is a quick mockup of what i'm trying to accomplish
https://dl.dropbox.com/u/252856/androidlayout.jpg
In your particular situation you could make the two ImageViews occupy 50% of the parent's width without using weights with a block like this:
<RelativeLayout android:layout_width="match_parent" android:layout_height="0dp"
android:layout_weight="your_value">
<View android:id="#+id/anchor" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_centerHorizontal="true"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_alignParentLeft="true"
android:layout_alignRight="#id/anchor" />
<ImageView android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_alignParentRight="true"
android:layout_alignLeft="#id/anchor" />
</RelativeLayout>
You may want to take a look and consider whether you could make your layout work as a GridLayout. It's designed to handle situations where you want to arrange UI elements into a roughly grid-like pattern, while avoiding the performance issues that nested weights can cause. If your UI lends itself to this sort of layout, you can achieve both simpler implementation and faster performance by taking advantage of it.
GridLayout is supported as far back as API level 7, I believe, via the support library.
I have a view where I defined sizes using dip.
I want to include this in other layouts in different sizes. I thought setting the size in the include tag
<include
android:id="#+id/abc"
android:layout_width="100dip"
android:layout_height="100dip"
layout="#layout/myInclude"
/>
would make that my included layout is resized proportionally but it doesn't. So everything I defined using dip in the included layout appears with the same size and breaks the layout.
Is this expected behaviour and what can I do to solve this?
A possible solution in to use LinearLayout with weights in the included layout, instead of hardcode in dip. But with dip I have more control, and don't have to use LinearLayouts everywhere...
Thanks in advance.
If you specify a size in dip or any other fixed unit, it won't resize automatically. That would be weird, generally when you hardcode a size you don't want your view to be resized.
Layout weights (and LinearLayouts) are the only way to go.
Scaling the included view can be made programmatically in your activity/fragment. For now that’s what I’m using.
Demo of negative margin:
The scenario
Overlapping views by setting a negative margin to one of them so that it invades the bounding box of another view.
Thoughts
It seems to work the way you'd expect with overlapping of the layouts if they should. But I don't want to run into a bigger problem for unknowingly not doing things right. Emulators, physical devices, you name it, when you use negative margins everything seems to work correctly, one view invades another's views bounding box and depending on how it's declared in the layout it will be above or below the other view.
I'm also aware that since API 21 we can set the translationZ and elevation attributes to make view appear above or below other views but my concern basically comes from the fact that in the documentation for the layout_margin attributes it's clearly specified that margin values should be positive, let me quote:
Excerpt:
Specifies extra space on the left, top, right and bottom sides of this view. This space is outside this view's bounds. Margin values should be positive.
Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), in (inches), mm (millimeters)...
In the years since originally asking this question I haven't had any issues with negative margins, did try to avoid using them as much as possible, but did not encounter any issues, so even though the documentation states that, I'm not too worried about it.
In 2010, #RomainGuy (core Android engineer) stated that negative margins had unspecified behavior.
In 2011, #RomainGuy stated that you can use negative margins on LinearLayout and RelativeLayout.
In 2016, #RomainGuy stated that they have never been officially supported and won't be supported by ConstraintLayout.
In December 2020(v2.1.0, official release June 2021), negative margin support for constraints has been added to ConstraintLayout.
It is easy to work around this limitation though.
Add a helper view (height 0dp, width constrained to parent) at the bottom of your base view, at the bottom add the margin you want.
Then position your view below this one, effectively allowing it to have a "negative" margin but without having to use any unsupported negative value.
Hope this will help someone. Here is working sample code using ConstraintLayout based on #CommonsWare's answer:
Add an helper view (height 0dp, width constrained to parent) at the
bottom of your base view, at the bottom add the margin you want. Then
position your view below this one, effectively allowing it to have a
"negative" margin but without having to use any unsupported negative
value.
Sample code:
<TextView
android:id="#+id/below"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F1B36D"
android:padding="30dp"
android:text="I'm below"
android:textColor="#ffffff"
android:textSize="48sp"
android:textAlignment="center"
tools:layout_editor_absoluteX="129dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.v4.widget.Space
android:id="#+id/space"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="#+id/below"
app:layout_constraintLeft_toLeftOf="#id/below"
app:layout_constraintRight_toRightOf="#id/below" />
<TextView
android:id="#+id/top"
android:layout_width="100dp"
android:layout_height="60dp"
android:textAlignment="center"
android:textColor="#ffffff"
android:text="I'M ON TOP!"
android:background="#676563"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/space" />
Output:
Instead of negative margins you can use:
translationX and translationY.
Example:
android:layout_marginBottom = -2dp
android:translationY = -2dp
UPDATE:
Have in mind that the whole view is translated.
In case you want use negative margin,set enough padding for container and its clipToPadding to false and set negative margin for it's children so it won't clip the child view!
It might have been bad practice in the past but with Material Design and its floating action buttons, it seems to be inevitable and required in many cases now. Basically, when you have two separate layouts that you can't put into a single RelativeLayout because they need distinctly separate handling (think header and contents, for instance), the only way to overlap the FAB is to make it stick out of one those layouts using negative margins. And this creates additional problems with clickable areas.
For me, and regarding setting a negative margin on a TextView (I realize the OP is referring to a ViewGroup, but I was looking for issues with setting negative margins and I landed here)... I found a problem with 4.0.3 (API 15) ONLY and the setting of android:layout_marginTop or android:layout_marginBottom to a negative value such as -2dp.
For some reason the TextView does not display at all. It appears to be "gone" from the view (not just invisible).
When I tried this with the other 3 versions of layout_margin, I didn't see the issue.
Note that I haven't tried this on a real device, this is using a 4.0.3 emulator. This is the 2nd odd thing I've found that only affected 4.0.3, so my new rule is to always test with a 4.0.3 emulator :)
I have success with reducing the bottom margin of a TextView by using android:lineSpacingExtra="-2dp" which works even though I happen to have android:singleLine="true" (and so I wouldn't have thought that line spacing would be a factor).
No, you should not use negative margin. instead you should use translate. Even if negative margin work sometime, when you change layout programmably, translate would help. And view can't overflow the screen wen you use margin.
I've only known that it was possible for a rather short period of time. But I see no problem with it. Just be aware of screen sizes and such so you are sure not to accidentally make to items that shouldn't appear overlapped on the screen. (i.e. text on top of text is likely a bad idea.)