how can I set ImageView position in dpi fro android api 8? - android

my android app supports Android api 8
and I want to move an object x dpi to the left.
how can I do it?

You should transform the amount of dip to the right amount of pixels for the given screen.
This is the formula you should use:
pixels = dip * (density / 160)
the (density / 160) part is known as the density scale factor. You can get this scale factor using the following code.
float scale = getContext().getResources().getDisplayMetrics().density;
Than calculate the right amount of pixels from the given amount of dip and round it:
int pixels (int) (dip * scale + 0.5f);
In function form it would look like this.
public int getPixelFromDip(float dip){
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f);
}
Rolf

Related

How to get relative coordinate on a large screen if we have a coordinate for small screen in android

I have coordinates corresponding to screen resolution 600x400. Now I want to get the relative position of this coordinate for the screen resolution 1280x800. After getting the coordinates, I have to create a link on that coordinate..For example
Suppose I have a coordinate (5,5) for a 600*400 device resolution, so this coordinate will be at the left-bottom of the screen.Now i want to know what will be the relative coordinate of this on a 1280*800 screen resolution device so that it looks at the same position i.e bottom left of screen.
Thanks in advance.
Well sticking to what you asked ,you can get your new pixels as per follow
suppose the coordinates are (6,4) on 600*400 screen size, now calculate the % of x,y as per screen resolution ,as follow
(6 * 100 )/600 = 1%
and
(4* 100)/400 = 1%
now calculate the coordinates as per the new screen size as follow ,
(1 * 1280) /100 = 12.8
and
(1* 800) /100 = 8
so the coordinates in the new screen size are : (12.8, 8) which were previously (6,4) .
But there are better ways to go through in requirements like these , if you could be more specific with what you are actually doing.
Here is formula for converting dp to px, and px to dp based on screen density, so either way you can convert the coordinates appropriated to relative screen density.
public int doToPixel(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
public int pixelToDP(int px) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return dp;
}

How to change UI widget dimension from iPhone 4 Retina to Android

Expected Result
I have a some UI widgets whose dimensions are design for iPhone 4 Retina device. The unit is in pixels, e.g. a button with 30 pixels wide by 30 pixels high. I wanna copy the design style into Android devices, say the previous 30 by 30 button, takes 30/640 = 4.6875% of the screen width in iPhone 4 Retina and 30/960 = 9.375% of the screen height, then I expect it also takes 4.6875% of the Android device screen width, 9.375% of the screen height.
Problem
Don't know the size scale factor of iPhone 4 Retina device which is used in the following code.
Code
/**
* Change dip value to pixel value using density of current device
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
Log.d("ch", "density of current device : " + scale);
return (int) (dpValue * scale + 0.5f);
}
/**
* Change pixel value to dip value using density of current device
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
Log.d("congliu", "density of current device : " + scale);
return (int) (pxValue / scale + 0.5f);
}
Reference
iPhone 4 Retina
ppi : 326
resolution : 640 by 960 pixels
size scale factor : Unknown
Samsung Galaxy S
ppi : 233
resolution : 480 by 800 pixels
size scale factor : 1.5
Samsung Galaxy Note
ppi : 285
resolution : 800 by 1280 pixels
size scale factor : 2.0
There are several perspectives you should consider.
But i just following a simple way:
px -> dp
My image resources are located in xhdpi folder, using images for retina iphone.
Suppose you have a pixel value in ios, for example, 10,
if you want to get pixel value for your android device:
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
SCREEN_DENSITY = dm.density;
SCREEN_WIDTH_DP = (int) (SCREEN_WIDTH_PIXELS / dm.density);
public static int getScaledWidthPixelsByDP(int desingDP) {
double v = desingDP / 320f * SCREEN_WIDTH_PIXELS;
return (int) v;
}
Assuming that iPhone 4 Retina version's size scale factor is 2.0 (xhdpi in Android), I did a very simple workaround by just give those pixels value a half of it with dp unit. So 30px by 30px button turns to be 15dp by 15dp in xml file. Looks good and works on Google Nexus, Samsung Galaxy S, S2, S4, Note, Note2. The dp2px and px2dp methods are not used.

What is the unit of bitmap.getWidth() or bitmap.getHeight()

The developers website simply states that getHeight() will return the bitmap's height, but can someone tell me that is in pixel unit or dp unit?
It's pixel. In Java code you usually work with pixels, e.g. a view's width and height.
After Hours of Experimenting I found that it actually return height in dp units.You can verify it by changing the device screen in emulator.
bitmap.getWidth() returns width in dp unit or densitiy.
To get dpi (density per inch) for a device, use
float dpi = context.getResources().getDisplayMetrics().density;
To convert dp to px
float px = dp * dpi;
and to convert px to dp
float dp = px/dpi;
If you read on how android deals with views this not clear at all. See "Supporting Multiple Screeens". After reading that document I have come to the conclusion that "it depends." (And I'm still guessing as I have not verified my analysis.) If the View was declared with size "wrap_content", "fill_parent", or "dp" then you get "dp", otherwise you get pixels. If you used "dp" then scaling to pixels is achieved by multiplying by
getResources().getDisplayMetrics().density
For 160 dpi screen, this returns 1.0; for 320 pi screen this returns 2.0.
Dividing by getResources()....density.

Android - Drawing on the different devices

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.

Android and setting width and height programmatically in dp units

I'm doing:
button.setLayoutParams(new GridView.LayoutParams(65, 65));
According to the docs the units for the width and height (both 65 in the above) are "pixels". How do you force this to be device independent pixels, or "dp"?
You'll have to convert it from dps to pixels using the display scale factor.
final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);
I know this is an old question however I've found a much neater way of doing this conversion.
Java
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, getResources().getDisplayMetrics());
Kotlin
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)
simplest way(and even works from api 1) that tested is:
getResources().getDimensionPixelSize(R.dimen.example_dimen);
From documentations:
Retrieve a dimensional for a particular resource ID for use as a size
in raw pixels. This is the same as getDimension(int), except the
returned value is converted to integer pixels for use as a size. A
size conversion involves rounding the base value, and ensuring that a
non-zero base value is at least one pixel in size.
Yes it rounding the value but it's not very bad(just in odd values on hdpi and ldpi devices need to add a little value when ldpi is not very common)
I tested in a xxhdpi device that converts 4dp to 16(pixels) and that is true.
Looking at your requirement, there is alternate solution as well. It seems you know the dimensions in dp at compile time, so you can add a dimen entry in the resources. Then you can query the dimen entry and it will be automatically converted to pixels in this call:
final float inPixels= mActivity.getResources().getDimension(R.dimen.dimen_entry_in_dp);
And your dimens.xml will have:
<dimen name="dimen_entry_in_dp">72dp</dimen>
Extending this idea, you can simply store the value of 1dp or 1sp as a dimen entry and query the value and use it as a multiplier. Using this approach you will insulate the code from the math stuff and rely on the library to perform the calculations.
Based on drspaceboo's solution, with Kotlin you can use an extension to convert Float to dips more easily.
fun Float.toDips() =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, resources.displayMetrics);
Usage:
(65f).toDips()
Kotlin Version
val scale: Float = resources.displayMetrics.density
val resizedInDp = (stream.videoWidth * scale + 0.5f).toInt()
Usage:-
val params: ViewGroup.LayoutParams = yourLayout!!.layoutParams
val scale: Float = resources.displayMetrics.density
params.width = (widthDp * scale + 0.5f).toInt() // dp to px
params.height =
(heightDp * scale + 0.5f).toInt() // setting height according to aspect ratio
yourLayout!!.layoutParams = params

Categories

Resources