I want to make a game with exact the same Layout across all devices. I'm familiar with dp, wrap_content and fill_parent. But they don't produce the EXACT same Layout.
Is there a way to make the width and height of various views, as well as their mangins from the edges of the device screen, in percentages relative to the screen width and height?
Something like:
android:layout_width="40%"
I know the above XML code doesn't work, but is there a workaround? Isn't there a in-Java solution to this? Something?
In the image below is what I'm trying to achive to happen in all devices.
I know the above XML code doesn't work, but is there a workaround?
LinearLayout and android:layout_weight allow you to work on a percentage basis. The following layout has three buttons, given 50%, 30%, and 20% of the screen respectively:
<?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:orientation="vertical">
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="50"
android:text="#string/fifty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="30"
android:text="#string/thirty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="20"
android:text="#string/twenty_percent"/>
</LinearLayout>
To do things on a percentage basis, set the width or height (for horizontal or vertical LinearLayouts, respectively) to be 0dp, then assign android:layout_weight to the desired percentage (e.g., 20). If the sum of the weights will not add to 100, add android:weightSum="100" to the LinearLayout itself.
Of course, doing things on a percentage basis will not give you "the EXACT same Layout" for any conventional definition of the term "EXACT". But, perhaps it will meet your needs. It certainly can implement the marked-up design from your screenshot.
Related
Alright so I'm trying to have an image set up such that:
the base of the image is lined up with the centre of the layout
the image scales with the layout to fit in background image
What I've done to achieve that is the following:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="2"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.9"/>
<ImageView
android:id="#+id/widget_icon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_weight="0.1"
android:src="#drawable/widget_icon"/>
</LinearLayout>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
So I would expect the image to take up 10% of the space in the top half of the window no matter what the window height/width is set to but what I've come to realize is that it's not the case.. seems like the image doesn't scale down past its "real" size? I'm not entirely sure but I'm getting some really wonky and seemingly not linear scaling happening when it comes to widget_icon. Is this a known issue or am I doing something wrong here?
You should look into the ImageView ScaleTypes
It looks like you might also not understand how weight works
typically you would set width or height to 0dp and then set the weight. if you have 2 items and you set the weights to 1 they would both take up half of the respective width or height.. if you set one to 1 and the other to 2, then the one set to 2 would take up 2/3 of the layout's width or height and the one set to 1 would be 1/3
hope that helps
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background_gradient" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
<ImageButton
android:id="#+id/buttonLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/log"
android:onClick="log" />
</RelativeLayout>
</FrameLayout>
I was expecting my button to appear in the center of the screen. However, it appears on the TOP center of the screen (that is, the button is center horizontally, but not vertically).
It seems to me that the RelativeLayout is behaving like it was defined with "wrap_content" instead of "fill_parent".
The funny thing is that, if I give an actual value to my RelativeLayout height property (android:layout_height), like:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="100dp"
android:gravity="center" >
Then the button behaves correctly (i.e. the button is also centred vertically). But I don`t want to use actual values. I want to use fill_parent! Why doesn't it work with "fill_parent" ??
Does anybody know what's going on?
Thank you in advance!
RelativeLayout requires you to specify the position of the elements in the Layout. I don't see any layout_below or layout_toLeftOf tags. Gravity works on LinearLayouts. In general, LinearLayouts are easier to work with, and they scale much better to different screen sizes. I suggest you replace the RelativeLayout by a LinearLayout, and also the FrameLayout by a LinearLayout. You use a FrameLayout typically if you want to use multiple overlapping layouts, which you don't do.
I recommend you read up on using layouts in the Android sdk reference documentation, like here: http://bit.ly/djmnn7
You specified fill_parent for both the layout_width and layout_height of your RelativeLayout, therefore it fills up it's parent view.
By default, a relative layout arranges it's children to the top-left corner, regardless you use fill_parent for the size.
You should achieve the desired aspect by taking advantage of the RelativeLayout's own attribute set, which helps you arrange the child views relatively to each other or to their parent:
<ImageButton
android:id="#+id/buttonLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/log"
android:onClick="log" />
Using the android:layout_centerInParent you can achieve this. This attribute if set true, centers this child horizontally and vertically within its parent.
I just know this is simple and in about 30 minutes time, I'll hate myself...
I have a splashscreen which consists of a static image which fills the screen. So I simply set the background attribute of whatever root view I use in my layout.
The image has a blank area over which I need to place an "I accept" button. To deal with different resolutions, I must position it using a percentage of the display height - 58% is the spot.
I can't use layout_weight because that sizes the button and absolutelayout (setting the y position in code) is deprecated.
How can I achieve this? I don't care what viewgroup is the parent and I'm fine with having "blank" views filling up space.
I am aiming to do this entirely in layout XML to keep my code clean...
Thanks!
You say you can't use layout_weight, but that's your only option if you want to do it purely in XML. I don't understand why you think you can't use it anyway. Here's an example of how you might do it:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/splash"
android:orientation="vertical" >
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="58" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="42" >
<!-- Place buttons here -->
</LinearLayout>
</LinearLayout>
I don't see any other way that to use a layout_weight... Also the whole class AbsoluteLayout is deprecated, so try to avoid using it. I suggest to use an LinearLayout as your rootView with a given weight_sum of 1. add another Space-filling LinearLayout width a weight of 0.58 and below your Button with wrap_content attributes. Unfortunately I cannot tell you more unless you post your xml, so that I can see, what you try to achieve.
Kind of this should work:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/your_desired_background"
android:orientation="vertical"
android:weight_sum="1">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight=".58" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
I am fairly new at the whole Android thing so I am hoping this is something obvious that I am overlooking since I have not been able to find a solution online yet.
I am creating a view which contains an ImageView and a "bottom bar". The problem I am having is that since the image is larger than the screen and I would prefer to use something similar to "fill_parent" or "wrap_content". Ideally I would set the ImageView's height to "fill_parent-44px", but I have not found a way to do this in the XML.
Eventually I plan to have the ImageView function with multi-touch zoom, so it is therefore not an option to resize the image for different screen resolutions.
Thanks for any help.
It's easy to do this with a RelativeLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<View android:id="#+id/bottombar"
android:background="#FFCC00"
android:layout_height="40dp"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true" />
<ImageView android:id="#+id/image"
android:src="#drawable/someimage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/bottombar"/>
</RelativeLayout>
The important things here are android:layout_alignParentBottom and android:layout_above (see RelativeLayout.LayoutParams for all possible layout attributes).
The android:layout_height="fill_parent" is more or less ignored given the right RelativeLayout parameters, it just needs to be there to please the Android UI system.
The android:background is just for highlighting in the UI designer, and the bottombar View can be replaced by any other view like, TextView, LinearLayout, etc.
My goal is to display 6 images (1 image, 6 times) across one line on my screen. My approach was to nest a RelativeLayout inside of a LinearLayout. My issue is that when I'm in 'portrait' mode, I cannot see all of my images. The more I resize my image, the more of the images I can fit, But I'm at a point where I do not want it to be any smaller. I assumed that by default, it would just wrap what it can't fit, but that doesnt seem to be the case. Theres no auto re-size to fit? Also, how can I manually decide how much space is between each image? Thanks!
Basically, you need to provide two different xml files for your app, one for portrait, once for landscape as per: Providing Resources. android will pick the proper xml file based on orientation.
and this ImageView.ScaleType explains the different scaling styles
Here is what I would suggest:
res/layout-land/main.xml
<?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:orientation="horizontal">
<ImageView
android:id="#+id/debris_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:weight="1"
android:src="#drawable/image1"
</ImageView
... repeat 5 more times ...
</LinearLayout>
the weight element should make them all fit but there might be a conflict with scaleType. anyway that should do it for your landscape, for portrait, you could either make it so there were two rows of images, or you could use a horizontalScrollView as below:
res/layout-port/main.xml
<?xml version="1.0" encoding="utf-8" ?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/debris_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:weight="1"
android:padding="15dp"
android:src="#drawable/image1"
</ImageView
... repeat 5 more times ...
</LinearLayout>
</HorizontalScrollView>
really, you could prolly just use the portrait main.xml as your only layout file and just have it be horizontally scrolling regardless of orientation. you might need to change some times in the portrait main.xml as i am at work and im not sure how well weight works with horizontalScrollView
as far as the space between each element, you would use android:padding like i have above.