I'm providing an option for text sizes and one of them is for the EditText boxes. I've determined the original text size using EditText#getTextSize(). The result is given in pixels. Once the user selects the text size, I use edittext.setTextSize(TypedValue.COMPLEX_UNIT_SP, chosen) to apply the text size.
Problem is different screen sizes give me wildly different text sizes, e.g. on an ICS phone, EditText.getTextSize() returns 36, which is absolutely massive and definitely not the default text size used throughout the system.
What am I doing wrong?
You are probably seeing different values due to different screen densities and the fact that the value you get from getTextSize() is in pixels(px). Density Independent Pixels(dp) and Scaled Pixels(sp) are adjusted to be independent of the screen density and they are what you should be using. To get dp or sp from px you can use a simple conversion like this:
public static float pxToDp( float px, Context context ) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / ( metrics.densityDpi / 160f );
return dp;
}
or this (which I took from this post):
public static float pixelsToSp(Context context, Float px) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px/scaledDensity;
}
Related
I have a textView in another view.
I want to calculate in runtime the actual display size of that text
and of its container.
If the text is too big to fit in the view I have few shorted text content alternatives.
I have read the textView doc, but it only shows [setTextSize][1]
how can i get the text size (in dp I guess ?) according to the actual screen.
(orientation, screen size, font size and so on)
TextView actually has a getTextSize() method, which returns the font size in pixels for you. You can check here the documentation. Of course this pixel value will vary accordingly to the screen density of the device. If you want to convert that value for dp or sp on runtime, you can do the following:
Pixels for SP:
float sp = px / getResources().getDisplayMetrics().scaledDensity;
Pixels for DP:
float dp = px / getResources().getDisplayMetrics().densityDpi;
When I tried same text size on top different resolution bitmaps on a canvas. Same text size looked small on a bigger resolution and bigger on a small resolution image. Please Help me understand this.
You need to set proper text size for your Paint, that accounts for density. Paint.setTextSize(float), takes in a float value. You need to ensure that this is not a constant value, but one that accounts for density.
How to get the density? You get that information from DisplayMetrics.scaledDensity or DisplayMetrics.density. Once you have this value, multiply this with the fontSize and set that value as the text size. Somthing like the below.
Paint.setTextSize(density * 10f);
This way a text with 10f font size will look the same in all devices with varying densities. You can find more information on density and scaledDensity here: http://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity
This is way you can make all text uniform size in all device.
canvas.drawText(hourText, getPx(TEXT_SIZE, activity), getPx(TEXT_SIZE / 3, activity), nPaint);
public static int getPx(int dp, Activity activity) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
float logicalDensity = metrics.density;
return (int) Math.ceil(dp * logicalDensity);
}
if a Custom View of size 500w*600h in dp , remain same as px in (1152w*720h)px screens of android , then what will be view's size in dp and px on screen of (480w*600h)px screens. And how to calculate for different size of View.
The dp / px ratio is based on the density of the screen of the device.
I would encourage you to read the Android docs on the subject.
http://developer.android.com/guide/practices/screens_support.html
Each classification of screen density has a specific px multiplier associated with it i.e. mdpi = px * 1 and hdpi = px * 1.5
Here is a nice little calculator to help you make sense of it:
http://labs.rampinteractive.co.uk/android_dp_px_calculator/
Assuming that you specified your view sizes in dp(same as dip), you can use get an instance of DisplayMetrics to convert the dp to actual pixels for your current device.
A handy function you can add to a utility class for doing conversions:
private static float dipToPixels(Context context, int dip)
{
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, metrics);
}
I would like to know how to create an android UI designs for multiple screen sizes programatically?
Take for example a Button or Layout set for 3.5inch programatically using width and height will look very small in 5inch device
similarly Button or layout created for 5 inch device will get trimmed for 3.5 inch device.
So would like to know how to handle it
Use Density pixels (dp) instead of pixels.
read here android supporting multiple screens
Is use these helper methods to convert between density pixels and real pixels :
/**
* Converts dp unit to equivalent pixels, depending on device density.
*
* #param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
* #return float value to represent px equivalent to dp depending on device density
*/
public static float dpToPixel(float dp){
Resources resources = MyApplication.getAppContext().getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return px;
}
/**
* Converts device specific pixels to density independent pixels.
*
* #param px A value in px (pixels) unit. Which we need to convert into db
* #return float value to represent dp equivalent to px value
*/
public static float convertPixelsToDp(float px){
Resources resources = MyApplication.getAppContext().getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return dp;
}
(MyApplication is a class that extends the Application class)
public class MyApplication extends Application
android supports the variety of screen sizes, and resolutions in a very good fashion.
you can provide different layouts to different screen sizes by using the smallest width qualifier.
you can also provide different versions of each image/icon for each screen density.
check Deacoy's link for further information.
Always remember the best way to start diving into a new technology is the official documentation.
In my app I create a canvas and add some bitmaps on it. The problem is that the objects are adding why touch the screen. So on one screens they appear on the middle on different the same, but their position in pixels are different.
I mean that I got tablet and smartphone. When I touch one the object appear on both devices (multiplayer) but its not in the same place, because its passing the position by x and y.
If someone understand what I mean, can you help me?
Probably it must have something common with counting the ratio.
I am guessing the problem you are having is that the screens are different resolutions and you are passing pixel data. You will need to use dp values and before sending them convert the dp to pixel values. On the receiving device you will need to convert the pixel values being sent back to dp on the given device. Use the methods below for the conversion.
To Convert DP to Pixels:
final float scale = getResources().getDisplayMetrics().density;
int pixelValue = (int) (DESIRED_DP_VALUE * scale + 0.5f);
To Convert Pixels to DP:
final float scale = getResources().getDisplayMetrics().density;
int dpValue = (int) ((DESIRED_PIXEL_VALUE) - 0.5f / scale);
The call to getDisplayMetrics().density is what will give you a scale value based on the current device. The dp value is meant to be density independent.
How do you define the metrics? If you are using pixels, use a density independent solution:
public int GetDipsFromPixel(float pixels)
{
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
And use it like this in you class:
textView.setHeight(GetDipsFromPixel(50));
This way the the height of the textview will be the same dps on both devices, even if their resolution is different.