I am new to Android. I like having the free range of drawing objects where ever I want. So i have been using Absolute Layout. I get a message saying to use a different layout. And I have read that this is because of the different res of different phones. My question is, is this the only reason in not using Absolute Layout? I have made a method that uses metrics to adjust the pixels.
public int widthRatio(double ratioIn){
DisplayMetrics dm = new DisplayMetrics(); //gets screen properties
getWindowManager().getDefaultDisplay().getMetrics(dm);
double screenWidth = dm.widthPixels; //gets screen height
double ratio = screenWidth/100; //gets the ratio in terms of %
int displayWidth = (int)(ratio*ratioIn); //multiplies ratio desired % of screen
return displayWidth;
}
//method to get height or Ypos that is a one size fits all
public int heightRatio(double ratioIn){
DisplayMetrics dm = new DisplayMetrics(); //gets screen properties
getWindowManager().getDefaultDisplay().getMetrics(dm);
double screenHeight = dm.heightPixels; //gets screen height
double ratio = screenHeight/100; //gets the ratio in terms of %
int newHeight = (int)(ratio*ratioIn); //multiplies ratio by desired % of screen
return newHeight;
}
//sets size of any view (button, text, ...) to a one size fits all screens
public void setSizeByRatio(View object, int width, int height){
LayoutParams params = object.getLayoutParams();
params.width = widthRatio(width);
params.height = heightRatio(height);
}
So if i say setSizeByRatio(Button, 10, 25); It will set the buttons width to 10% of the width of the screen and the height to 25% percent of the screen.
Are there any phones that Absolute Layouts do not work on? Does this layout cause any other issues?
The reason why the AbsoluteLayout is deprecated is because you have alternatives in the LinearLayout or the GridLayout that does the same and more. It seems that you are trying to calculate positions based on absolute positions and number of pixels, an approach that should in general be avoided due to issues with varoius screen sizes and densities.
Read the link that #amiekuser provided and focus on the understanding how the best practice is. Some hints are creating images for ldpi, mdpi and hdpi folders, using the unit for dpi (density independent pixels) instead of raw pixels and how to test your app on multiple screen sizes and densities using the emulator.
Edit:
To set the x- and y-position of a View you must use LayoutParams. See this question on how to to set the TopMargin and LeftMargin for a View using LayoutParams.
Android phones comes in many form factors i.e. not only it varies greatly in terms of screen size(2.7", 3.2", 3.7" ....) but also in terms of resolution (480X800, 480X848 etc).
Google itself suggest not to use AbsoluteLayout. in fact its deprecated in the newer api versions.
The link below explains all these in details:
http://developer.android.com/guide/practices/screens_support.html
Check the best practices section.
Related
I'm searching for a way to keep view size proportioned on all devices. I experimented with many maths calculations (e.g. mixing screen size, density, percentage, etc.) but haven't found any solutions, just different results for each device tested.
Let me present an example: Suppose I'm testing an app on a sw-360dp and eventually I find a size view that works.
relativeLayoutParams.width = 150;
relativeLayoutParams.height = 250;
This has the effect of creating a view with size about 1/3 of screen width and 1/2 screen height.
How can I dynamically arrive at value for width and height, that lets the view keep the aspect ratio of 1/3 width to 1/2 height? At least I think that's what the documentation is suggesting when it says: "calculate exact view size (or margin, padding, etc.) from a percentage of screen size".
Or have I misinterpreted it?
Any help will be appreciated.
You can get the device screen size and there by define the ratio,
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Then,
width = (int) size.x * 1/3 ;
height = (int) size.y * 1/2 ;
I have an ImageView with matchParent property in width.
how can i know its runtime width on my device (using eclipse, without adding code programmatically)?
how can I know the conversion ratio between dpi to pxls in my device?
I have an ImageView ... how can i know its runtime width on my device
You can get the width when the ImageView is measured, i.e. later than the runtime. However you can get the screen's width and height like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
And if for example your ImageView takes up a specific portion of your screen you can measure it using the screen's width and height.
how can I know the conversion ratio between dpi to pxls in my device?
To convert say 20 pixels to DP do (adding to the above code):
int dp = 20 / metrics.density:
Extra: Here's a dpi to pixel calculator
If you don't want to use the TreeObserverListener way, you can try to get the View to measure itself and give you what the dimensions would be if it were calculated. In my experience, this has worked in most cases but not all; especially if the View is in some special dynamic layout or the ordering of the hierarchy prevents the dimensions from being calculated in the correct order. You might find luck in refering to this popular answer.
I am developing an Android app that is causing me problems with devices that have 1024 as their width dimension. I have tried creating a layout folder layout-w1024 and layout-mdpi-sw1024dp; but the device uses the layout-mdpi folder instead. I am using 15 as the minimum android version.
Is there any other way using which I can separate 1024 devices?
You can do it programmatically if it's suitable for your project, something like this would call a different layout depending on the dimensions of the screen. This has some limitations though since it can only be called from an Activity (shouldn't be a problem in your case) and if you have problems with layouts all over your application it may not be very scalable.
The conditional width == 1024 should probably be replaced with something greater than or more specific, you'll need to play with this for a while to make it work. You should also account for the height of the screen, not only the width.
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
Or if you want it in pixels instead:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
And then:
//Depending on the width, set one layout or anotherone
setContentView(width == 1024?R.layout.for1024:R.layout.normal);
Source
At the top of my app, I have a title which should be shown in the middle, and a button on the right. As the textViews length is behind my control, I sometimes have my title crossing the button due to long length of the content of it.
After following this, I somehow tend to solve the problem. My device was HTC desire. Unfortunately, if I check with Galaxy SIII, it doesn't do the trick.
I am wondering how I can manage this in terms of different devices with different densities.
My controls inside the relative layout
You can also check the device screen density by this--
WindowManager wm = (WindowManager) _context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
And can manage accordingly whats your apps needed..
just use weightsum in your xml and make width of all the views as fill parent ..... this makes auto resizing of your textview
you can maintain layouts according to their DPI`s
replicate the same XML data in XHDPI (As S3 falls in XHDPI) and test it similarly replicate the XML data in HDPI
but
keep in mind the following Thing Pixel Ratio of the layOut as
following
in LDPI its 1:0.75
in MDPI its 1:1
in HDPI its 1:1.5
in XHDPI its 1:2
Display display = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
float density = dm.density;
int screenWidth = display.getWidth();
With this code above, you'll have your screen density as float.. So you can use it to calculate your textView's width like:
int newWidth = (int) (density * 100);
which 100 is here based size.
Or you can have a ratio according to your screenWdith.
int newWidth = screenWidth / 2;
This question already has answers here:
How do you make layouts for several Android screen sizes?
(3 answers)
Closed 9 years ago.
I am developing the app in 320*480. How do make the app to be run in 480*854 screen? When i tried to run in 480*854 screen, the app original design looks like small. Do I want to create separate layouts for each screen in android? If so, please provide me the sample hint to proceed.
I have implemented my own way of Handling Multiple Screen Resolutions.
You could certainly avoid this problem by setting LayoutParams at run time in terms of Percentage
The Problem occurs only with Views/Layouts that have some constant width or height lets say 280dp. Solution is quite simple if we programmatically set Layout Params of our Views/Layouts in terms of Percentage and only use constant width or height where necessary, elsewhere try to use match_parent to fill up empty space or use weights and define every View relative to other Views this will help your layout to look good in almost every screen resolutions
Here is a sample xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/mLayout"
android:layout_width="280px"
android:layout_height="300px" />
</RelativeLayout>
Notice: I have used px for fixed sized layout's width/height because in LayoutParams layoutParams = new LayoutParams(int width, int height); the width and height take value as pixels
Here is an example code of setting width and height in terms of percentage
final ViewTreeObserver mLayoutObserver = mLayout.getViewTreeObserver();
mLayoutObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
DisplayMetrics metrics = getResources().getDisplayMetrics();
int deviceWidth = metrics.widthPixels;
int deviceHeight = metrics.heightPixels;
float widthInPercentage = ( (float) 280 / 320 ) * 100;
float heightInPercentage = ( (float) 300 / 480 ) * 100;
int mLayoutWidth = (int) ( (widthInPercentage * deviceWidth) / 100 );
int mLayoutHeight = (int) ( (heightInPercentage * deviceHeight) / 100 );
LayoutParams layoutParams = new LayoutParams(mLayoutWidth, mLayoutHeight);
mLayout.setLayoutParams(layoutParams);
}
});
Now might be some people are wondering what is happening here
float widthInPercentage = ( (float) 280 / 320 ) * 100
Let me explain 280 is the width of my LinearLayout and 320 is the width of my device screen(on which i'm developing), i know currently i'm testing on a device having resolution 320 x 480, what i'm doing is calculating how much area my layout is covering in terms of percentage and then
int mLayoutWidth = (int) ( (widthInPercentage * deviceWidth) / 100 )
here i'm calculating the new width for my layout according to the screen resolution and by this way your Views/Layouts will look exactly the same on every screen resolution.
Conclusion: If you need to set some constant width/height for your Views/Layouts always set value in px in layout file (i.e xml) and then programmatically set LayoutParams.
A Suggestion for Google Android Engineers, i guess you guys should seriously think of changing the dp/dip units to percentage
for that you can make your layout dynamic with reference to available width and Height of the device
Display mDisplay= activity.getWindowManager().getDefaultDisplay();
int width= mDisplay.getWidth();
int Height= mDisplay.getHeight();
set your layout in terms of perecentage with reference to avail size
Mr. Babar,
I think you should follow the below formula instead of calculating like
float widthInPercentage = ( (float) 280 / 320 ) * 100;
float heightInPercentage = ( (float) 300 / 480 ) * 100;
int mLayoutWidth = (int) ( (widthInPercentage * deviceWidth) / 100 );
int mLayoutHeight = (int) ( (heightInPercentage * deviceHeight) / 100 );
I would suggest like if you take this as follows:
int baseWidth=320;
int baseHeight=480;
int mLayoutWidth = (int) ( (280* deviceWidth) / baseWidth);
int mLayoutHeight = (int) ( (300* deviceHeight) / baseHeight);
Also this is going to work for Views and not for text-sizes;
In Android, you don't go by the the absolute resolution, but rather focus on the screen density.
And yes you might need to create different layout to support various densities and screen sizes. In general there are four densities supported by Android (low, medium, high, extra high)
I suggest you read Supporting Multiple Screens for Android. I think it will help you achieve what you need to do. It has various sections on Designing alternative layouts and drawables and other useful info related to supporting multiple screen resolutions.
hi welcome to stack overflow...
From version 1.6 onward, Android supports multiple screen resolutions and densities separated into three classes:
Small: devices with a screen size smaller than the T-Mobile G1 or Samsung I7500, like the HTC Tattoo
Normal: devices with a screen size roughly the same as the G1 or I7500.
Large: devices with a screen size larger than the G1 or I7500 (such as a tablet-style device.)
Developers can control if and how apps appears to devices in each group by using tools introduced in the Android framework APIs and SDK. Details on implementation can be found in the Android Dev Guide article Supporting Multiple Screens. you may refer this link MultiResolution
or may use
Display displayparm= activity.getWindowManager().getDefaultDisplay();
int width= displayparm.getWidth();
int Height= displayparm.getHeight();