My hardware:
Google Glass(screen density=1.5, resolution 640*360px)
Vuzix M100(screen density=0.75, resolution 432*244px)
Here's how my layout looks like on Google Glass:
and on Vuzix:
Layout source:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/activity_margin"
android:baselineAligned="false"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/content_secondary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:paddingRight="#dimen/layout_padding">
</FrameLayout>
<View
android:layout_width="#dimen/separator_width"
android:layout_height="match_parent"
android:layout_marginBottom="#dimen/separator_margin_bottom"
android:layout_marginTop="#dimen/separator_margin_top"
android:background="#android:color/darker_gray" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_instructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/instruction_sign_in"
android:textSize="#dimen/instructions_text_size" />
<FrameLayout
android:id="#+id/content_primary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/container_primary_padding_left" >
</FrameLayout>
</LinearLayout>
<dimen name="activity_margin">1dp</dimen>
<dimen name="separator_width">1dp</dimen>
<dimen name="separator_margin_top">30dp</dimen>
<dimen name="separator_margin_bottom">30dp</dimen>
<dimen name="instructions_text_size">20sp</dimen>
<dimen name="layout_padding">3dp</dimen>
<dimen name="medium_text_size">30sp</dimen>
<dimen name="small_text_size">22sp</dimen>
<dimen name="almost_large_text_size">50sp</dimen>
<dimen name="large_text_size">60sp</dimen>
<dimen name="huge_text_size">100sp</dimen>
<dimen name="container_primary_padding_left">10dp</dimen>
Source for right layout section:
<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:padding="10dp">
<TextView
android:layout_below="#id/tv_row_label"
android:id="#+id/tv_destination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="AA"
android:textSize="#dimen/huge_text_size" />
</RelativeLayout>
As you can see all values are density-independent. But layouts still look different. What could be the problem?
The problem is your devices have a different physical size. This might not be visible due to the screens being projected, but it's the only possible reason.
Density-independent means your widgets share the same physical size between different screen densities. Be it an hdpi or and ldpi device, what you want to be XX dp in size is YY cm on any device.
Now, as you have devices that differ in physical size, you see bigger spaces between your widgets on one device because its screen is bigger. While the widgets have the same physical size as on the other device, there is more empty space left.
One solution would be to use a TextView that automatically adjusts the text size on the space it has available, such as this one.
Related
I do design for android. I have a few phones. they have different resolutions. I have a design in resolving 1440X2560 px. screen has 3 squares with different widths. width of 1440 pixels in xxxhdpi = 360 dpi.I have the width for each layout. Now if I run the application on Samsung Galaxy Note 4 (1440x2560 640 dpi) everything looks as it should. Now if I run the application on Nexus 6 (1440x2560 ? dpi) the picture is not the entire screen. I found that the nexus 6 has resolution betwen xxhdpi and xxxhdpi. the question is how I mark the screen so that it looked the same on all phones? or I should not use dpi?enter link description here
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<LinearLayout
android:orientation="horizontal"
android:layout_width="60dp"
android:layout_height="100dp"
android:background="#ffff2622">
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="200dp"
android:layout_height="100dp"
android:background="#ff42ff20">
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#ff4934ff">
</LinearLayout>
</LinearLayout>
</LinearLayout>
According to this the Nexus 6 really is between xxhdpi and xxxhdpi with scale around 3.5. I am not a fan of layout weighting as #Squonk suggested so I would reccomend using dimensions.
Create values folders for different screen widths such as values-w320dp, values-w360dp, values-w410dp etc. There you can define your dimensions for different screen widths.
<resources>
<dimen name="left_column">60dp</dimen>
<dimen name="middle_column">200dp</dimen>
<dimen name="right_column">100dp</dimen>
</resources>
In your xml you can then reference layout_width="#dimen/left_column"
I would also recommend setting only the left and right column widths and have the middle one fill the remaining space. You could do that with a RelativeLayout.
It seems to me you want to create your 'squares' to have a ratio of 60:200:100 (which is also 3:10:5). Try the following to set width by layout_weight...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="3"
android:background="#ffff2622">
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="10"
android:background="#ff42ff20">
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="5"
android:background="#ff4934ff">
</LinearLayout>
</LinearLayout>
</LinearLayout>
Using android:layout_width=0dp and android:layout_weight= will give each element a size based on a percentage of the sum of all weight values.
I have a good understanding of the difference between px, dp and sp.
The problem is, when I put a TextView ( or ImageView ) on the screen, the dpi is irrelevant.
On a 3 inch high screen with 160 dpi, a text size of 80px will be 1/2 an inch, or 1/6th the height. On a 7 inch high screen with 160 dpi, it's still 1/2 inch, but that is now 1/14th of the height.
The problem is, using dp (or sp), what looks good on a phone disappears on a tablet.
Is there a way to specify fractional screen size, like percent?
I not sure if you can specify size in percent, but why you dont define different dimensions for screen in dimen.xml file. It is very hard to use the same values dp and sp for all screen sizes.
You need to create different dimens.xml different resource folders
res/values-ldpi/dimens.xml
res/values-mdpi/dimens.xml
res/values-hdpi/dimens.xml
Next add some values to these files
<!-- in values-ldpi/dimens.xml -->
<dimen name="textSize">25dip</dimen>
<!-- in values-mdpi/dimens.xml -->
<dimen name="textSize">20dip</dimen>
Finaly reference to dimensions in your layout file:
<TextView
android:layout_toRightOf="#id/at"
android:layout_below="#id/hw"
android:textSize="#dimen/textSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
EDIT:
If you want set height of image to 1/10 of screen size you need to use android:layout_weight attribute in your view containers. Check the example below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/imageView"
android:background="#drawable/ic_launcher" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:weightSum="1"
android:layout_weight="9"
>
</LinearLayout>
</LinearLayout>
This will give textSize depending upon the density.
TextView text = new TextView(this);
text.setText("text");
TextView.setTextSize(16 * getResources().getDisplayMetrics().density);
OR
Create dimens.xml in values-ldpi,mdpi and hdpi.
<dimen name="textSize">30dip</dimen>
<dimen name="textSize">10dip</dimen>
and then add this in your layout.
<TextView
android:textSize="#dimen/textSize"
//rest code here
/>
I have an image spinner in my Android action bar, but when I click it, the images are not scaled down. This is a screenshot of my application:
Here is my spinner layout code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside" >
</ImageView>
</LinearLayout>
This is the item declaration in menu.xml:
<item
android:id="#+id/menu_spinner"
android:actionViewClass="android.widget.Spinner"
android:showAsAction="ifRoom"
android:title="Share"/>
Use wrap_content instead of match_parent for ImageView in both android:layout_width and android:layout_height as below...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside" >
</ImageView>
</LinearLayout>
Maybe someone could give an comprehensive answer, but you need to use resource filtering for screen dpi.
E.g "drawable-mdpi", "drawable-hdpi"
Just place appropriate(scaled) sizes inside folders
Edit:
Alright i tried similar layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff920f">
<ImageView
android:id="#+id/main_spinner_item_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/abc_ic_cab_done_holo_light"
android:scaleType="fitCenter"/>
</FrameLayout>
in a sample project and everything worked fine. As i mentioned before you need to scale your icon for screen dpi. There is a folder - size list below
"drawable-mdpi", 32x32
"drawable-hdpi", 48x48
"drawable-xhdpi", 72x72
"drawable-xxhdpi", 96x96
For more sample, see Action Bar Icon Pack here
For a game I have six buttons which look good on mdpi. The 4 left buttons are 100x100px:
If I switch to hdpi, it looks like this:
The xml looks like this (I omitted all but one button to keep it simple):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gameContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:orientation="vertical" >
<com.mydomain.mygame.game.GameSurface
android:id="#+id/gameSurface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_game" >
</com.mydomain.mygame.game.GameSurface>
<RelativeLayout
android:id="#+id/controlButtonContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/button_left"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="100dp"
android:contentDescription="#string/button_left"
android:background="#drawable/control_button" />
</RelativeLayout>
</FrameLayout>
<LinearLayout
android:id="#+id/emptyBar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:baselineAligned="false"
android:gravity="center"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
These attempts didn't work:
I tried to use 100dp instead of wrap_content. I tried src instead of background as well as I tried different scaleType attributes.
Probably I could calculate the scaling factor in code, but I can't imagine that this is the proper way to do that. Why does it not scaled automatically, because what are dp then for? So how can I configure the right ratio in xml?
Please avoid use of specific size like 100dp . Try to use WRAP_CONTENT or MATCH_PARENT . and for different different screen sizes please use drawable-folders like drawable-hdpi and drawable-mdpi etc . And Put corrosponding images of android:background="#drawable/control_button" in all its specific folders .
Refer these linkes for multiple screen sizes :
http://developer.android.com/guide/practices/screens_support.html
http://developer.android.com/training/multiscreen/screensizes.html
Help to understand please.
I need to show up in a specific box.
I do it like this:
<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:background="#drawable/fon"
tools:context=".MainActivity" >
....
<TextView
android:id="#+id/textView3"
android:layout_width="200dp"
android:layout_height="210dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:includeFontPadding="false"
android:lineSpacingMultiplier="0.8"
android:textAlignment="center"
android:textColor="#color/black"
android:textSize="20sp" />
....
</RelativeLayout>
Everything works at four inch screen well but if take a big diagonal, it will be bad. At increase in the screen the textView size doesn't change.
I use "dp" and "sp", instead of static "px", but does not work...
Why Is this happening ?
screenshots:
4 inch
5.4 inch
You can create different resource directories for different screen sizes and densities and then create dimens.xml in each of them providing text size to be used on specific screen size, for example:
res/values-sw420dp/dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="font_size">26sp</dimen>
</resources>
res/values-sw600dp/dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="font_size">30sp</dimen>
</resources>
res/values-sw720dp/dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="font_size">36sp</dimen>
</resources>
And then call it in your layout file:
android:textSize="#dimen/font_size"
This is a solution for the text size, but you can do the same thing for width and height.
More resources:
Supporting Different Screen Sizes
Dimension Resource Type
Supporting Multiple Screen Sizes
The text view size is static because you have defined a fixed size to them.Use wrap content.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
You should adjust the TextView android:layout_width and android:layout_height to
android:layout_width="wrap_content"
android:layout_height="wrap_content"
If you want the TextView to center inside the white background, you should add another attribute
android:layout_centerInParent="true"