I am testing my app on a Nexus 5 (full HD screen) and an HTC One X (720p).
Using sp as a good Android developer, actually gives me a result I do not want!
The text on the Nexus 5 is bigger than on the HTC One X, even taking into account that the screen is bigger in size.
When I use 'dp' instead of 'sp', they are actually more alike...the result I want...
But you want to use sp, as that is the way you should do it.
So I created a values-sw380dp directory and put there a different value. But, the Nexus 5 does NOT use these values! Then I used this code:
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
Surprisingly: for both phones, the dpWidth == 360! So I have no way to do this nicely for 720p and 1080p screen ?
Does anyone have an idea or solution?
I am tempted to use DP...
Related
I read this official link because i want to set different XML for larger screen.
First, i checked my device's width (in dp) with this code :
private void getScreenDp() {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
}
The width is 320dp.
Then i create a new folder called layout-sw320dp. When i run the app in 320dp width device, its using layout-sw320dp correctly.
However, the layout that my apps used when running in 600dp width device is the one in layout-sw320dp instead of the normal layout folder. I tried to change the layout to layout-w320dp but the devices bigger than 320dp width still not using the normal layout as it should be.
Please kindly help me, i have spent hours for this.
I'm currently developing an app that as usual has to run on multiple devices but there is one more special than the others. An Acer DA241HL which is a 24" "Tablet" with a 1920x1080px resolution that should be wall mounted somewhere.
Is there a good way to identify this screen. Right now it reacts to the values-sw600dp folder. But what ever changes I make for this enormous tablet shouldn't affect normal tablet which would happen if I change stuff in that folder.
The following code:
DisplayMetrics metrics = getResources().getDisplayMetrics();
float density = getResources().getDisplayMetrics().density;
float dpHeight = metrics.heightPixels / density;
float dpWidth = metrics.widthPixels / density;
Log.e("screen", "******************************************************");
Log.w("screen", "d " + density + " y" + dpHeight + " x" + dpWidth + " deviceType:" + getResources().getString(R.string.device_type));
Log.e("screen", "******************************************************");
Print the following:
******************************************************
d 1.0 y1032.0 x1920.0 deviceType:5
******************************************************
But I dont see how I can make that useful.
The other way I thought about is to get the model number of the device but that creates new problem if they decide to get a similar device but not the same.
Suggestions?
Is there a good way to identify this screen
Use something like -swNNNdp, for a suitably high value of NNN.
Right now it reacts to the values-sw600dp folder
Well, sure, but that screen is far larger than 600dp in its smallest width.
But what ever changes I make for this enormous tablet shouldn't affect normal tablet which would happen if I change stuff in that folder.
Then add a res/values-sw1000dp/ directory, for resources to use for screens with 1000dp in the smallest width, which will include your Acer but will not include more normal-sized tablets.
I have two tablet devices:
1) Asus Memo Pad 172V tablet
Specs given online as: 600 * 1024 pixels, 7.0 inches (~170 ppi pixel density) LINK
Specs through code: 1024 * 552 pixels, 7.0 inches (160 ppi pixel density)
2) MID 7510 tablet
Specs given online as: 800 * 480 pixels, 7.0 inches (no density mentioned anywhere) LINK
Specs through code: 1024 * 552 pixels, 7.0 inches (160 ppi pixel density)
My problem is:
- Both the tablets have the same density and resolutions (by code), so how can I distinguish between them in order to set the bitmap height (width is coming correct for both) as in case of MID7510, the bitmap height is extended slight down.
- Is there any other factors that are responsible for causing different bitmap sizes for both
tablets ?
- Why are specs coming different by code and are given different online ?
Code to get density and resolution:
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
// Display device dpi (density) value in pixels
int screenDPIy = (int)dm.ydpi;
I'll try to answer to each question but I'll start by the more important one:
- Why are specs coming different by code and are given different online?
Because you find online what material is used for the device, its usually the correct values. You find by code specifications that are set up by the constructor when they are building their android version for their devices. Meaning : it can be false! especially for devices from unknown constructor or Chinese low cost such as 'weisung'.
Given that, answers for the other questions:
- Is there any other factors that are responsible for causing different bitmap sizes for both
tablets?
I dont think so, they have got different screen size and density but system think they are the same... it explain the difference on the final bitmap size.
- How can I distinguish between them?
Definitively not from the screen specifications. If you really need to manage 'weisung' devices you can always check for manufacturer in the device configuration by code. (Assuming they have correctly set up their identification in the manufacturer field XD)
Check the constant value : android.os.Build.MANUFACTURER
I'm really interested to know more in this topic too so any more information is welcome.
The chart was on drawable-hdpi folder.
I was doing simply this:
img.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
The height was not proper in MID 7510 doing so.
Setting height like this worked for both the tablets:
static int imgHeight = 0;
Drawable d = (BitmapDrawable) getResources().getDrawable(R.drawable.chart);
imgHeight = d.getIntrinsicHeight();
final ImageView img = new ImageView(getActivity());
img.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (imgHeight * 1.5)));
This is because 1 hdpi= 1.5 mdpi. So total height should be 1.5 times of image height.
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();