Ok, I've looked around and around and cannot figure out what to do with this.
TimePicker has some hidden spacing around it. When I put two TimePickers one under another as:
<LinearLayout
android:orientation="vertical"
android:background="#440044"
android:layout_margin="-30dp"
android:padding="-30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TimePicker
android:id="#+id/timePickerA"
android:scaleY="0.50"
android:scaleX="0.50"
android:layout_margin="-30dp"
android:padding="-30dp"
android:background="#989898"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TimePicker
android:id="#+id/timePickerB"
android:scaleY="0.50"
android:scaleX="0.50"
android:layout_margin="-30dp"
android:padding="-30dp"
android:background="#989898"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
the TimePickers still have a huge amount of space around each of them. Notice I even tried using both negative margins and padding in both the TimePickers and the parent LinearLayout. These have no impact at all on the spacing around the TimePickers.
The scaleX and Y are obviously to reduce the size of these ridiculously huge TimePickers!
I'm trying to avoid making a custom if possible.
The problem is that when you use android:scaleY="0.50" and android:scaleX="0.50" you don't decrease the View at his half, you just re-scale it. That means your TimePicker still have the same width and height but the drawing area will be reduced to half (half X and half Y).
See the image below, the blue rectangle represent the real width and height of your View (the TimePicker).
As a solution:
I think it's better if you make a custom one.
Otherwise as workaround you can use a RelativeLayout and play with margins, something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#440044"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TimePicker
android:id="#+id/timePickerA"
android:scaleY="0.50"
android:scaleX="0.50"
android:background="#989898"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TimePicker
android:id="#+id/timePickerB"
android:scaleY="0.50"
android:scaleX="0.50"
android:background="#989898"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/timePickerA"
android:focusableInTouchMode="false"
android:touchscreenBlocksFocus="false"
android:layout_marginTop="-80dp" />
</RelativeLayout>
PS: I don't guarantee that you'll have the same result in different screen density/size.
Related
I'm building an injection tracking app for diabetics and other people who take regular injections, and I'm trying to align 8 checkboxes on top of an image of a body so the user can specify where they got the injection. The problem is that aligning it right now only works for a very specific screen size, and whenever the size is different, the checkboxes move around and end up not on the correct body part. Is there some way I can accomplish this? Hardcoding the margins doesn't seem to be working well. Any help would be appreciated. Thank you.
Here's what i want it to look like ideally, and here is what it actually looks like on a specific screen size which shifts everything around. It gets more extreme than that of course the larger or smaller the screen size.
and here's my code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.injectiontracker.MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/date_and_time_layout"
android:src="#drawable/blank_body" />
<CheckBox
android:id="#+id/abdomen_left"
style="#style/InjectionCheckbox"
android:layout_alignBaseline="#+id/abdomen_right"
android:layout_alignBottom="#+id/abdomen_right"
android:layout_toRightOf="#+id/abdomen_right"
android:layout_toEndOf="#+id/abdomen_right" />
<CheckBox
android:id="#+id/thigh_left"
style="#style/InjectionCheckbox"
android:layout_alignBaseline="#+id/thigh_right"
android:layout_alignBottom="#+id/thigh_right"
android:layout_toRightOf="#+id/thigh_right"
android:layout_toEndOf="#+id/thigh_right" />
<ImageView
android:id="#+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="#drawable/ic_save_black_48dp" />
<CheckBox
android:id="#+id/buttocks_left"
style="#style/InjectionCheckbox"
android:layout_below="#+id/abdomen_left"
android:layout_alignLeft="#+id/arm_left"
android:layout_alignStart="#+id/arm_left"
android:layout_marginLeft="24dp"
android:layout_marginStart="24dp" />
<CheckBox
android:id="#+id/arm_left"
style="#style/InjectionCheckbox"
android:layout_marginRight="74dp"
android:layout_marginEnd="74dp"
android:layout_above="#+id/abdomen_left"
android:layout_toLeftOf="#+id/save"
android:layout_toStartOf="#+id/save"
android:layout_marginBottom="16dp" />
<CheckBox
android:id="#+id/buttocks_right"
style="#style/InjectionCheckbox"
android:layout_width="wrap_content"
android:layout_alignBaseline="#+id/buttocks_left"
android:layout_alignBottom="#+id/buttocks_left"
android:layout_toRightOf="#+id/buttocks_left"
android:layout_toEndOf="#+id/buttocks_left" />
<CheckBox
android:id="#+id/arm_right"
style="#style/InjectionCheckbox"
android:layout_alignBaseline="#+id/arm_left"
android:layout_alignBottom="#+id/arm_left"
android:layout_toRightOf="#+id/buttocks_right"
android:layout_toEndOf="#+id/buttocks_right" />
<CheckBox
android:id="#+id/abdomen_right"
style="#style/InjectionCheckbox"
android:layout_marginLeft="55dp"
android:layout_marginStart="55dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<CheckBox
android:id="#+id/thigh_right"
style="#style/InjectionCheckbox"
android:layout_marginTop="11dp"
android:layout_below="#+id/buttocks_left"
android:layout_alignLeft="#+id/abdomen_right"
android:layout_alignStart="#+id/abdomen_right" />
I think what will help you the most here is PercentFrameLayout.
This is a support library so you have to add
compile 'com.android.support:percent:24.2.1'
to your build.gradle file (the version will vary depending on what you've updated).
Your current layout uses wrap_content for the width and height of the ImageView. If your screen width is smaller that the width of the image, then the ImageView is going to have a different aspect ratio than the image itself, and this is going to make getting an accurate layout difficult.
A good approach is to have at least two layouts
one layout for smaller devices like phones where the screen width may be smaller than your image
another layout for larger devices like tablets where the screen width is larger than your image
See How to support multiple screens if you aren't familiar with alternate layouts.
First you need to ensure that the aspect ratio of the ImageView matches the image. Do this by specifying android:adjustViewBounds="true" along with a width of match_parent and a height of wrap_content.
Then wrap the ImageView in a PercentFrameLayout that also has a width of match_parent and a height of wrap_content.
Now you have a view that is somewhat predictable for using percentages. I downloaded the image that you linked to and used it to come up with this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.percent.PercentFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/blank_body" />
<CheckBox
android:id="#+id/abdomen_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="15.5%"
app:layout_marginTopPercent="32%"/>
<CheckBox
android:id="#+id/abdomen_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="25%"
app:layout_marginTopPercent="32%"/>
<CheckBox
android:id="#+id/thigh_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="15.5%"
app:layout_marginTopPercent="47%"/>
<CheckBox
android:id="#+id/thigh_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="25%"
app:layout_marginTopPercent="47%"/>
<CheckBox
android:id="#+id/arm_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="57%"
app:layout_marginTopPercent="22%"/>
<CheckBox
android:id="#+id/arm_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="82.5%"
app:layout_marginTopPercent="22%"/>
<CheckBox
android:id="#+id/buttocks_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="64%"
app:layout_marginTopPercent="38.5%"/>
<CheckBox
android:id="#+id/buttocks_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_marginLeftPercent="73.5%"
app:layout_marginTopPercent="38.5%"/>
</android.support.percent.PercentFrameLayout>
</RelativeLayout>
(Sorry, I remove your styles and such since I didn't have access to those.)
For the larger devices, your alternate layout should specify a fixed width for the PercentFrameLayout:
<android.support.percent.PercentFrameLayout
android:layout_width="600dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
then you would position this within your larger RelativeLayout as you require (I show center/top as an example).
This should get you a pretty acceptable result.
You will still see some slight distortion depending screen width since you are measuring to the left and top of the checkbox. For a pixel-perfect layout, you would need to make a custom layout component that can position the centers of the checkboxes right at the points of interest.
I have an TextView with a variable width, but maximum is 250dp. But somehow Android sets it always to maxwidth.
With a shorter text and without maxwidth it works, but then the text is long enough that the field exceeds the screen width, it overlaps the arrow.
I already tried this two variants, which give the same result as in the picture
<TextView
android:id="#+id/bubbleText"
style="#style/MarkerText"
android:maxWidth="250dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF0000"
android:layout_marginEnd="#dimen/defaultSpacing" />
<TextView
android:id="#+id/bubbleText"
style="#style/MarkerText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/defaultSpacing"
android:layout_weight="1"
android:background="#FF0000"
android:maxWidth="250dp"
android:singleLine="false" />
I want it to look like this:
Additional infos:
Complete XML
<LinearLayout
android:id="#+id/markerTextBubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="invisible" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/marker_text_background" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="#dimen/tinySpacing"
android:paddingEnd="#dimen/defaultSpacing"
android:paddingStart="#dimen/defaultSpacing"
android:paddingTop="#dimen/tinySpacing" >
<TextView
android:id="#+id/bubbleText"
style="#style/MarkerText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/defaultSpacing"
android:background="#FF0000"
android:maxWidth="250dp" />
<mypackage.IconTextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/MarkerTextIcon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/icon_map_arrow" />
</LinearLayout>
</LinearLayout>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginBottom="-5dp"
android:layout_marginTop="-1dp"
android:src="#drawable/marker_text_background_rectangle" />
</LinearLayout>
<style name="MarkerText" parent="android:Widget.Holo.Light.TextView">
<item name="android:textColor">#color/myWhite</item>
<item name="android:textSize">#dimen/markerTextSize</item>
</style>
<dimen name="markerTextSize">22sp</dimen>
The problem occurs in this independent snippet too:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF0000"
android:maxWidth="250dp"
android:text="1. Willkommen bei meiner APP"
android:textSize="22sp" />
Not 100% sure, but I think the problem is that it is a multi-line text.
Does the view behave as expected when the text is shorter? i.e. "1. Welcome"
What I think happens is the following:
The view tries to make it on one line, then it expands until its maximum width, given that is not enough for rendering, makes it a multi-line, but does not stretch the view.
You could try with "1. Willkommen bei\nmeiner APP" to see if it shows the expected behaviour.
Hope this helps.
Using the maxWidth won't be causing it to stretch.
It would most likely be in your code for:
android:layout_marginEnd="#dimen/defaultSpacing"
and check any dimensions:
style="#style/MarkerText"
As setting the maxWidth alone will not cause this.
There must be some figure that is putting padding between your text and the right side textview, or possibly some peculiar margin mess up.
Using maxWidth should not force it out to the right like that, as I showed you in the image, I think it's the nested layouts and there is a lot of coding defining margins and padding within your layouts and elements, this could be forcing your texview to move to the right, and the text will automatically wrap, as it cannot fit in the first row, but the textview itself is still being pushed to the right.
I'm trying to scale a horizontal LinearLayout that contains DatePicker and TimePicker adding
android:scaleX="0.6"
android:scaleY="0.6"
The problem is that this scales the content but increases the margin at the same time, so I cannot use the space properly. In the picture the marked white area is the space gained by scaling, but I cannot use this space (in fact, the clock on the right is cropped)
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:scaleX="0.6"
android:scaleY="0.6">
<DatePicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/datePicker"
android:layout_gravity="center_horizontal"
android:calendarViewShown="false"
android:spinnersShown="false"
android:layoutMode="opticalBounds"
android:measureAllChildren="true" />
<TimePicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/timePicker"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="5dp" />
</LinearLayout>
Any solution to scale the view without this blank space problem?
I would suggest you not to use xscale & yscale.
Instead what you can do is provide weight for date picker & time picker.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal">
<DatePicker
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:id="#+id/datePicker"
android:layout_gravity="center_horizontal"
android:calendarViewShown="false"
android:spinnersShown="false"
android:layoutMode="opticalBounds"
android:measureAllChildren="true" />
<TimePicker
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:id="#+id/timePicker"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="5dp" />
</LinearLayout>
you can add padding at sides or modify the weights as an how you want.
Are you able to use the date and time picker in a dialog instead? I think that may be your only option. I'm not aware of a way to shrink the size of the DatePicker and TimePicker the way you're trying to. See http://developer.android.com/guide/topics/ui/controls/pickers.html#DatePickerFragment.
Scalling will not change your controls size it means your data picker will take same space in your layout regardless if it is scalled up or down. only thier apperance changes
I have a linear layout with 4 images with horizontal orientation. My problem is that the first image is cropped and i cant see both of them in my galaxy s,only in some emulators..any help please?this is my linear layout code:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageButton
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#drawable/header_new_3"
android:layout_weight="1"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#drawable/header_btn1"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#drawable/header_btn2"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#drawable/header_btn3"
/>
</LinearLayout>
this is what i want
and this is what i get
#Jamo: image1:
image2,3,4:
Your containing layout is fill_parent, meaning it's restricted to the width of its parent (probably the whole screen). Each ImageButton is set to width wrap_content, meaning it just fits the width of its content. If the widths of the backgrounds of the images you're using sum up to more than the total parent width, you're going to have problems. This seems to be what's happening. You can't fit more pixels into a screen than what you have.
Update:
With your provided graphics, the "hello" image is 138px and the star is 60px. 138 + 60 * 3 = 318. If your screen is 480px wide (I think the Galaxy S is 480 wide) then you should be able to fit. If you put these into the default or mdpi folder (and the Galaxy S is hdpi) then these will be scaled to 1.5x that, which is 477px. That should still fit.
The only way I know to create something similiar is to use RelativeLayout like this:
<RelativeLayout android:layout_height="wrap_content"
android:layout_width="fill_parent">
<ImageView android:layout_alignParentRight="true"
android:id="#+id/iv4"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/icon"/>
<ImageView android:layout_toLeftOf="#id/iv4"
android:id="#+id/iv3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/icon"/>
<ImageView android:layout_toLeftOf="#id/iv3"
android:id="#+id/iv2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/icon"/>
<ImageView android:layout_toLeftOf="#id/iv2"
android:id="#+id/iv1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:src="#drawable/icon"/>
</RelativeLayout>
We chatted about this in a previous question. Please post the whole layout file. The layout_weight won't do much, as hinted at in other posts, if the total width is being constrained by whatever is the parent of the outer LinearLayout.
Also, some thoughts.
You have "fill_parent" for the ImageView heights. I think those should be "wrap_content". You're setting the images with 'background' rather than 'src', which is kind of weird.
Also, that first image should be in another layout container, to allow stretching that doesn't screw up the 'hello'.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_weight="1">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/header_new_3"
android:layout_gravity="center"
/>
</LinearLayout>
Not 100% sure on that being exactly what you want, but the ultimate goal would be to stretch the first image without shearing it in any way.
I am using a list view in Android 1.5 to show a list of images and text next to the image. I am trying to vertically center the text but the text is at the top of the row instead of centered. Below is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<ImageView android:id="#+id/item_image" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:paddingRight="10dip"
android:src="#drawable/default_image" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="#id/item_image"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
/>
</RelativeLayout>
It seems strange that I need to set alignParentTop="true" when I'm trying to vertically center the text, but if I don't the text does not even show up. What am I doing wrong?
EDIT following the comments:
It turns out making this work with RelativeLayout isn't easy. At the bottom of the answer I've included a RelativeLayout that gives the effect wanted, but only until it's included in a ListView. After that, the same problems as described in the question occurred. This was fixed by instead using LinearLayout(s).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:orientation="horizontal">
<ImageView android:id="#+id/pickImageImage"
android:layout_width="100dp"
android:layout_height="80dp"
android:background="#drawable/icon"
android:scaleType="fitXY"
android:layout_marginRight="10dp"/>
<TextView android:id="#+id/pickImageText"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="left|center_vertical"
android:text="I'm the text"/>
</LinearLayout>
If you want to have two text boxes, you can nest a second orientation="vertical" and LinearLayout after the ImageView and then put the text boxes in there.
This works, but I have to admit I don't know why the RelativeLayouts didn't. For example, this blog post by Romain Guy specifically says that the RelativeLayout should. When I tried it, I never got it to quite work; admittedly I didn't do it exactly as he did, but my only changes were with some attributes of the TextViews, which shouldn't have made that much of a difference.
Here's the original answer:
I think you're confusing Android with all those somewhat contradictory instructions in RelativeLayout. I reformatted your thing to this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<ImageView android:id="#+id/item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:src="#drawable/icon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/item_image"
android:layout_centerVertical="true"
android:text="Blah!"/>
</RelativeLayout>
And that works fine. I removed many of your redundant android:layout_alignParentxxx because they weren't necessary. This view now comes up with the picture in the top left corner and the text vertically centered next to it. If you want the picture vertically centered as well, then you can't have the RelativeLayout be on android:layout_height="wrap_content" because it's trying to make itself no taller than the height of the picture. You'd have to specify a height, e.g. 80dp, and then set the ImageView to a fixed height like 60dp with android:scaleType="fitXY" to make it scale down to fit properly.
Was stuck on a similar issue for a while, but found this from CommonsWare:
"When you inflate the layout, use inflate(R.layout.whatever, parent, false), where parent is the ListView."
Works but only when you set the height of the row to a specific value (ie you can't use wrap_content).
Baseline directive would do it, but ImageView simply does not support baseline alignment as of today. You can work around this by creating a subclass of ImageView, override the getBaseline() method and return the height of the image.