I want to develop an app which will support different screen sizes.
I've read the official guide a lot of times, but I can not understand this. I created a brand new app with a main activity, then I put a black square on the screen with 100dp x 100dp dimensions, just like this:
res/layout/activity_main.xml:
<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" >
<FrameLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#000000"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
When I run this application on my emulator - I get this screen:
And when I run the application on my device (Galaxy tab 2), I get a screen like this:
As you can see, the square running on device is smaller than running on the emulator.
I am using DP in my XML width and height. Is the square supposed to be in the same proportion in all resolutions? If not, what can I do to get this square in the same size in all resolutions?
Yes, this can be confusing.
However, different devices have different amounts of 'DP's. The purpose of this is so that larger screens can hold more content. If you're using images, you can provide different sizes for different screen densities.
For more info, see this page: http://developer.android.com/guide/practices/screens_support.html
Related
I am currently trying to adjust my Android App so it will look and feel similar on multiple screens/devices.
I know by now that a major part in this is to provide multiple image sizes for every image file according to the x1, x1.5, x2, x3, x4 ratios for mdpi, hdpi, xhpi, xxhdpi and xxxhdpi respectively, and I have finished doing so today.
After doing this, I have defined Density independent Pixel dimensions in the #dimen.xml values resource that correspond with the actual image sizes in pixels of the MDPI resources. Subsequently, i have set the imageviews in question's layout_width and layout_height to this dimension.
I am currently at a loss, however, as to why my application still looks significantly different on an MDPI emulator than it does on an HDPI emulator. To highlight what I mean, I'll provide the following screenshot showing the HDPI and MPDI emulator next to one another (left is HDPI (4" WVGA Nexus S) and right is MDPI (5.4" FWVGA)). I want both of them to look like the MPDI version, but what I've done so far apparently isn't working.
I have three theories of my own as to why this is not working the way I intend it to:
1. I am not supposed to set ImageView layout_width and layout_height to a dp value, but rather match_parent or wrap_content (?) (and change the structure of my .xml layouts in the process).
2. I am not only supposed to define multiple drawable resources, but also multiple layout resources for different screen sizes (?).
3. I have misunderstood the entire idea behind how this is supposed to work (?).
I will also give you an example of one of the list items that can be seen in the first screenshot (#drawable/phone_speed_icon is a 64 x64 pixel resource in MPDI and a 96x96 resource in HDPI, and #dimen/icon_attribute_size is 64dp):
<LinearLayout
android:id="#+id/llSpeed_PreSession"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingEnd="20dp"
android:paddingStart="20dp"
android:weightSum="100">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="#dimen/icon_attribute_size"
android:layout_weight="20"
android:weightSum="100">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="70"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="#dimen/icon_attribute_size"
android:layout_height="#dimen/icon_attribute_size"
android:src="#drawable/phone_speed_icon" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="30"
android:gravity="center_vertical"
android:paddingStart="10dp"
android:text="Speed"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#878787"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="80"
android:gravity="center">
<android.support.v7.widget.SwitchCompat
android:id="#+id/swSpeed_PreSession"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
In the end, I have four questions that I'd like answered:
1. How do I make the list items in screenshot 1 look the same on MDPI devices as HDPI devices? Does this have anything to do with one of the three theories I mentioned earlier?
2. Why is the header text ("What do you want to measure?") wrapped on one device, but not on the other? They use the sp unit (via android:style/TextApperance.TextApperance.Large)?
3. Shouldn't everything be more spaced out on an HDPI device (if anything) rather than less spaced out? The HDPI emulator looks as if it "has got way less pixels available", if you can understand what I'm saying even a little.
4. How do I make the Fragments on the second screenshot look the same? Or should i not even want this, because the HDPI is (for some reason) physically smaller, which is why the layout is less spread out?
Anyway, I have been at this all day and the more I read the more thouroughly confused I get, so any help is greatly appreciated!
You have the option to create multiple dimens.xml files depending on a variety of factors. Here you'll see what my current project looks like with the various dimens.xml files in Android Studio based on screen width.
However, you can have different requirements for each dimens file you want. For example, you can create dimens files for each density:
I have a Samsung Galaxy Tab on which I do development for Android phones. It uses the camera for scanning, so I can't run it on the emulator. Is there any way I can run it on the Tab device, but have it display the same size as a phone? This would be extremely helpful when testing the layouts.
A solution
You could place your entire layout inside another layout and make your phone layout if you may, have specific pixel dimensions. The gray area is the container which will expand to the dimensions of the tablet, the one with the turtle is your phone screen inside which your layout will reside.
The code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC">
<RelativeLayout
android:id="#+id/your_layout_inside_this"
android:layout_width="768px"
android:layout_height="1280px"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:background="#FFFFFF"></RelativeLayout>
</RelativeLayout>
The preview
Considerations
Don't use this on a production app. I don't think there is a problem with this approach as far as the testing goes and you may have to take into account the density of the tablet compared to the density of the phone you are testing.
If your testing expands to other things like I may infer from your question, such as taking a picture, you may have to skip using the native intents for taking a picture and use a surfaceview with the dimensions of the phone, but that's a totally different story and question.
I wonder how to make application look the same on different devices. I have read Supporting Multiple Screens many times but I still can't understand how to live.
Here is a sample layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"
android:textSize="30sp"
/>
</LinearLayout>
There is Galaxy S II (480x800) and Sensation XE (540x960). They are both hdpi, physical screen size is almost the same. I expected to see the same looking on both devices but in fact text on 540x960 is smaller then on 480x800:
(left is 480x800, right is 540x960)
I tried to specify text size as dimension resource and make separate folder values-w540dp but it took no effect.
How do you guys make your application look the same on different hdpi devices?
android:textAppearance="?android:attr/textAppearanceLarge"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAppearance="?android:attr/textAppearanceSmall"
These atributes may solve your problem here.Otherwise you have to setup your layout dynamically with some ratios(or factors you generate like :textSize=factor*height) using your screen height and width.
Have a look at metrics , if you specify your textsize in dp (Density-independent pixels) it should work. The default size for text should be around 14dp. (TextAppearance.small)
2 Sites that might be helpful as there are some nuggets in both related to your problem, however, neither is an exact 1-2-3 how to correct the issue you're seeing:
http://www.pushing-pixels.org/2011/11/08/deep-dive-into-responsive-mobile-design-part-1.html
http://www.alistapart.com/articles/fluidgrids/
The problem I am running into related to supporting multiple screen sizes - a fairly common one I believe. I have searched a lot, but have not found something helpful.
I have my project laid out traditionally, with folders to support the various sizes called layout, layout-small, layout-large, layout-xlarge.
So as I have found out, even within each of these size regimes, there screens are not all the same size. For example, my 320x480 screen qualifies for the normal size layout, but so does someone's 480x800. As you can imagine, the content of my app will not fill up the whole screen of a 480x800 device because there is more area. Here are examples of what it looks like:
On 320x480 (what I designed for):
On 480x800 (notice the extra space at the bottom):
Now, I have done a lot of research and applied lots of techniques in an effort to make my app look nice on all screen, but I feel like I am missing something fundamental. I have taken all the basic steps to use dp instead of px, use RelativeLayout everywhere, stuff like that. But I need some way for my app to re-size itself to better fit the larger screens. For example, the margins between the various components could increase a little to occupy more of the empty vertical space.
Any advice, or help? In the worst case, is there a way to design a layout which would fire up specifically for 480x800 screens (because they seem to be most common)? Thanks.
If I were you I'd use a layout like this:
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<!-- Your first form line -->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<!-- Your second form line -->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<!-- Your third form line -->
</LinearLayout>
<!-- .... -->
</LinearLayout>
This layout will produce this (without colors, of course :) ). The ratio of the lines (colored boxes) is fix, but it's size is dinamically fit to the screen height. The fill_parent and layout_weight do the trick.
If you want to use RelativeLayout, you have to set the whitespaces and heights programatically from JAVA (some explanation here)
320 : 480 has a different ratio than 480 : 800. So the latter simply has more vertical space in relation to the horizontal space than the former. So there is nothing wrong with your layout.
You need to design screens so that you always think about how the Views you define behave when the screen's size shrinks or grows. As you saw, screens may be varying greatly even in the same size-category.
In the case of the screen that you showed, you need to give the width of the EditText components by using weights, not exact dp amounts. You can find many articles on how you might do this, here's one for a start.
I am reading through http://developer.android.com/guide/practices/screens_support.html and trying to understand how pre-scaling works.
I have the following layout file which is optimized for the galaxy tab :
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativelayoutmain"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/mainmenu"
>
<ImageButton
android:id="#+id/start_button"
android:layout_marginLeft="150dip"
android:layout_marginTop ="70dip"
android:layout_width="500dip"
android:layout_height="214dip"
android:background="#drawable/startsession"
android:contentDescription="#string/descbuttonstart"
/>
I have placed the images for the screen in the drawable-ldpi folder. The problem is that when I test the app on a smaller screen (using the emulator) the screen does not scale properly - the button is massive and not positioned correctly.
Is it possible to just have one layout file for all screens and if so what is the secret to getting this working ?
Thank you.
NO , AFAIK its not possible you need to have three differents folders(hdpi,mdpi,ldpi) with different dimensions for buttons,images etc
and also for layout again you need to have three layout folders (layout-small,layout-medium,layout-large)
Screen size and screen resolution are two independent things. the resources in ldpi folder are for low resolution and not necessory small screen sizes. The way I prefer is to define resources for high resolution and let them scale down on others.