How to set margin with dp size in Android - android

I want set margin for views by programmatically, i should set 50dp for margin_top, i use this code
ViewGroup.MarginLayoutParams marginParams = new ViewGroup.MarginLayoutParams(searchView.getLayoutParams());
marginParams.setMargins(0, 75, 0, 0);
CoordinatorLayout.LayoutParams layoutParams = new CoordinatorLayout.LayoutParams(marginParams);
searchView.setLayoutParams(layoutParams);
but in this code set 50px! how can i set this 50dp, not px?!

You have to convert it:
final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);

For dimens.xml:
context.getResources().getDimensionPixelSize(R.dimen.view_height);
For harcoded value:
int height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,
getContext().getResources().getDisplayMetrics());

public static int dp(int px) {
return (int) (px * Resources.getSystem().getDisplayMetrics().density);
}
int margin = dp(50);

Use this code:
/**
* Convert dp to pixel
*
* #param dp
* #return px
*/
public static int dpToPx(final float dp) {
return Math.round(dp * (Resources.getSystem().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}

private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,getResources().getDisplayMetrics());
convert it!

Here's a Kotlin solution
You can use the following function:
fun dpToPx(context: Context, dp: Float): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics).roundToInt()
}
You could choose to take advantage of extensions instead:
// Use: 16f.dpToPx(context)
internal fun Float.dpToPx(context: Context): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, context.resources.displayMetrics).roundToInt()
}
Or if using a dimens resource, use the following:
context.resources.getDimensionPixelSize(R.dimen.some_dimen_id)

Related

does getHeight returns value in dp unit?

i am trying to get the height occupied by an item in a listview. so i wrote the following code:
mLisVieMeineDocs.post(new Runnable() {
#Override
public void run() {
h = mLisVieMeineDocs.getHeight();
Log.d(TAG, "getHeight :" + h);//returns 108
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mLisVieMeineDocs.getLayoutParams();
params.width = LinearLayout.LayoutParams.MATCH_PARENT;
params.height = h;
mLisVieMeineDocs.setLayoutParams(params);
}
});
as stated in the code, the "getHeight" returns 108. when i tried to set this value "108" in the layout_height of the container of the listview in the xml file as follows:
<LinearLayout
android:id="#+id/versicherungsListeActivity2mod_linLay_meineDocList_container"
android:layout_width="match_parent"
android:layout_height="108dp" <<<------
android:orientation="vertical"
android:layout_below="#+id/versicherungslistsactivity2mod_linLay_meineDocsBar_container">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<!--android:transcriptMode="alwaysScroll"
android:stackFromBottom="true"-->
<ListView
android:id="#+id/versicherungsListeActivity2mod_lisVie_meineDocs"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</ScrollView>
</LinearLayout>
i found that the linearlayout expands to wrap upto 2 items in the listview despit the code above stated that the height of the item in the listview is 108
But, when i change the 108 to 54dp in the xml file
android:layout_height="54dp"
then the linearlayout expands to to wrap exactly on item in the listview.
so, why "getHeight" returns as double as of the height of the view? why do i need to divide the value returned from "getHeight" to get the exact height of the view
Convert from DP to Pixel use below method:
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return px;
}
Convert from Pixel to DP use below method:
public static float convertPixelsToDp(float px, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
return dp;
}
Most of value in Java is Pixel, So you need transform this.
public static int dip2px(Context context, float dp) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
public static int px2dip(Context context, float px) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (px / scale + 0.5f);
}
Sometime you should set DP/SP value eg:
badgeCountTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
TypedValue.COMPLEX_UNIT_DIP, TypedValue.COMPLEX_UNIT_PX....
You need to convert pixel in to dp, see below code.
h = pxToDp(mLisVieMeineDocs.getHeight());
public static int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

How to convert pixels into dip(Density Independent Pixels) in Android

In my Android application I have pixels(69px) and I need to convert this pixels into dip(Density Independent Pixels).
Any suggestions?
Just divide your value in pixels by DisplayMetrics.density.
Hope this will be helpful
Resources r = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, r.getDisplayMetrics());
You can try this:
public int convertDiptoPx(int pixel){
float scale = getResources().getDisplayMetrics().density;
int dips=(int) ((pixel * scale) + 0.5f);
logMessage("Px=" +pixel+" DipValue="+dips );
return dips;
}
Editted:
public int convertPxtoDip(int pixel){
float scale = getResources().getDisplayMetrics().density;
int dips=(int) ((pixel / scale) + 0.5f);
return dips;
}

Convert dip to px in Android

I had written method to get the pixels from dip but it is not working. It give me runtime error.
Actually I was running this method in separate class and initialized in my Activity class
Board board = new Board(this);
board.execute(URL);
This code runs asynchronously. Please help me.
public float getpixels(int dp){
//Resources r = boardContext.getResources();
//float px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpis, r.getDisplayMetrics());
final float scale = this.boardContext.getResources().getDisplayMetrics().density;
int px = (int) (dp * scale + 0.5f);
return px;
}
Try this:
Java
public static float dipToPixels(Context context, float dipValue) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
}
Kotlin
fun Context.dipToPixels(dipValue: Float) =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, resources.displayMetrics)
You can add the dp value in dimen.xml and use
int pixels = getResources().getDimensionPixelSize(R.dimen.idDimension);
It's easier...
The formula is: px = dp * (dpi / 160), for having on a 160 dpi screen. See Convert dp units to pixel units for more information.
You could try:
public static int convertDipToPixels(float dips) {
return (int) (dips * appContext.getResources().getDisplayMetrics().density + 0.5f);
}
Hope this helps...
Try this for without passing context:
public static float dipToPixels(float dipValue) {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dipValue,
Resources.getSystem().getDisplayMetrics()
);
}

Formula px to dp, dp to px android

I am trying to calculate a variable amount of pixels to density independent pixels and vice-versa.
This formula (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160)); does not work on small devices because it is divided by zero.
This is my dp to px formula:
px = (int)(dp * (displayMetrics.densityDpi / 160));
Could someone give me some pointers?
Note: The widely used solution above is based on displayMetrics.density. However, the docs explain that this value is a rounded value, used with the screen 'buckets'. Eg. on my Nexus 10 it returns 2, where the real value would be 298dpi (real) / 160dpi (default) = 1.8625.
Depending on your requirements, you might need the exact transformation, which can be achieved like this:
[Edit] This is not meant to be mixed with Android's internal dp unit, as this is of course still based on the screen buckets. Use this where you want a unit that should render the same real size on different devices.
Convert dp to pixel:
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Convert pixel to dp:
public int pxToDp(int px) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Note that there are xdpi and ydpi properties, you might want to distinguish, but I can't imagine a sane display where these values differ greatly.
I solved my problem by using the following formulas. May other people benefit from it.
dp to px:
displayMetrics = context.getResources().getDisplayMetrics();
return (int)((dp * displayMetrics.density) + 0.5);
px to dp:
displayMetrics = context.getResources().getDisplayMetrics();
return (int) ((px/displayMetrics.density)+0.5);
Efficient way ever
DP to Pixel:
private int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
Pixel to DP:
private int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
Hope this will help you.
px to dp:
int valueInpx = ...;
int valueInDp= (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, valueInpx , getResources()
.getDisplayMetrics());
Just call getResources().getDimensionPixelSize(R.dimen.your_dimension) to convert from dp units to pixels
Use This function
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
Use these Kotlin extensions:
/**
* Converts Pixel to DP.
*/
val Int.pxToDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
/**
* Converts DP to Pixel.
*/
val Int.dpToPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
px = dp * (dpi / 160)
dp = px * (160 / dpi)
In most of the cases, conversion functions are called frequently. We can optimize it by adding memoization. So,it does not calculate every-time the function is called.
Let's declare a HashMap which will store the calculated values.
private static Map<Float, Float> pxCache = new HashMap<>();
A function which calculates pixel values :
public static float calculateDpToPixel(float dp, Context context) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return px;
}
A memoization function which returns the value from HashMap and maintains the record of previous values.
Memoization can be implemented in different ways in Java. For Java 7 :
public static float convertDpToPixel(float dp, final Context context) {
Float f = pxCache.get(dp);
if (f == null) {
synchronized (pxCache) {
f = calculateDpToPixel(dp, context);
pxCache.put(dp, f);
}
}
return f;
}
Java 8 supports Lambda function :
public static float convertDpToPixel(float dp, final Context context) {
pxCache.computeIfAbsent(dp, y ->calculateDpToPixel(dp,context));
}
Thanks.
You can use [DisplayMatrics][1] and determine the screen density. Something like this:
int pixelsValue = 5; // margin in pixels
float d = context.getResources().getDisplayMetrics().density;
int margin = (int)(pixelsValue * d);
As I remember it's better to use flooring for offsets and rounding for widths.
try this
http://labs.skinkers.com/content/android_dp_px_calculator/
If you're looking for an online calculator for converting DP, SP, inches, millimeters, points or pixels to and from one another at different screen densities, this is the most complete tool I know of.
Below funtions worked well for me across devices.
It is taken from https://gist.github.com/laaptu/7867851
public static float convertPixelsToDp(float px){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return Math.round(dp);
}
public static float convertDpToPixel(float dp){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return Math.round(px);
}
// for getting in terms of Decimal/Float
public static float convertPixelsToDp(float px, Context context) {
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return Math.round(dp);
}
public static float convertDpToPixel(float dp, Context context) {
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return Math.round(px);
}
// for getting in terms of Integer
private int convertPxToDp(int px, Context context) {
Resources resources = context.getResources();
return Math.round(px / (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
private int convertDpToPx(int dp, Context context) {
Resources resources = context.getResources();
return Math.round(dp * (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
________________________________________________________________________________
public static float convertPixelsToDp(float px){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return Math.round(dp);
}
public static float convertDpToPixel(float dp){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return Math.round(px);
}
private int convertDpToPx(int dp){
return Math.round(dp*(getResources().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT));
}
private int convertPxToDp(int px){
return Math.round(px/(Resources.getSystem().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT));
}
Elegant kotlin solution :)
val Int.dp get() = this / (Resources.getSystem().displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
val Float.dp get() = this / (Resources.getSystem().displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
val Int.px get() = this * Resources.getSystem().displayMetrics.density
val Float.px get() = this * Resources.getSystem().displayMetrics.density
Usage:
val dpValue = 2.dp
val pxFromDpValue = 2.px
Improtant:
I am not sure if Resources.getSystem() will work correctly with orientation changes.
If want to work in for example fragment or activity just add it it in to base fragment or base activity and use it like this:
abstract class BaseFragment : Fragment() {
val Int.dp get() = this / (resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
val Float.dp get() = this / (resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
val Int.px get() = this * resources.displayMetrics.density
val Float.px get() = this * resources.displayMetrics.density
.......
}
Feel free to use this method I wrote:
int dpToPx(int dp)
{
return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
The answer accepted above is not fully accurate. According to information obtained by inspecting Android source code:
Resources.getDimension() and getDimensionPixelOffset()/getDimensionPixelSize() differ only in that the former returns float while the latter two return the same value rounded to int appropriatelly. For all of them, the return value is in raw pixels.
All three functions are implementedy by calling Resources.getValue() and converting thus obtained TypedValue by calling TypedValue.complexToDimension(), TypedValue.complexToDimensionPixelOffset() and TypedValue.complexToDimensionPixelSize(), respectively.
Therefore, if you want to obtain "raw" value together with the unit specified in XML source, call Resources.getValue() and use methods of the TypedValue class.
with help of other answers I wrote this function.
public static int convertToPixels(Context context, int nDP)
{
final float conversionScale = context.getResources().getDisplayMetrics().density;
return (int) ((nDP * conversionScale) + 0.5f) ;
}
DisplayMetrics displayMetrics = contaxt.getResources()
.getDisplayMetrics();
int densityDpi = (int) (displayMetrics.density * 160f);
int ratio = (densityDpi / DisplayMetrics.DENSITY_DEFAULT);
int px;
if (ratio == 0) {
px = dp;
} else {
px = Math.round(dp * ratio);
}
variation on ct_robs answer above, if you are using integers, that not only avoids divide by 0 it also produces a usable result on small devices:
in integer calculations involving division for greatest precision multiply first before dividing to reduce truncation effects.
px = dp * dpi / 160
dp = px * 160 / dpi
5 * 120 = 600 / 160 = 3
instead of
5 * (120 / 160 = 0) = 0
if you want rounded result do this
px = (10 * dp * dpi / 160 + 5) / 10
dp = (10 * px * 160 / dpi + 5) / 10
10 * 5 * 120 = 6000 / 160 = 37 + 5 = 42 / 10 = 4
Here's a other way to do it using kotlin extensions:
val Int.dpToPx: Int
get() = Math.round(this * Resources.getSystem().displayMetrics.density)
val Int.pxToDp: Int
get() = Math.round(this / Resources.getSystem().displayMetrics.density)
and then it can be used like this from anywhere
12.dpToPx
244.pxToDp

Programmatically set height on LayoutParams as density-independent pixels

Is there any way to set the height/width of a LayoutParams as density-independent pixels (dp)? It looks like the height/width, when set programmatically, are in pixels and not dp.
You need to convert your dip value into pixels:
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, <HEIGHT>, getResources().getDisplayMetrics());
For me this does the trick.
public static int getDPI(int size, DisplayMetrics metrics){
return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;
}
Call the function like this,
DisplayMetrics metrics;
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int heigh = getDPI(height or width, metrics);
Since it may be used multiple times:
public static int convDpToPx(Context context, float dp) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}
I found it more practical to use the conversion rate, as usally more than one value has to be converted. Since the conversion rate does not change, it saves a bit of processing time.
/**
* Get conversion rate from dp into px.<br>
* E.g. to convert 100dp: px = (int) (100 * convRate);
* #param context e.g. activity
* #return conversion rate
*/
public static float convRateDpToPx(Context context) {
return context.getResources().getDisplayMetrics().densityDpi / 160f;
}
Here is my snippet:
public class DpiUtils {
public static int toPixels(int dp, DisplayMetrics metrics) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}
}
where DisplayMetrics metrics = getResources().getDisplayMetrics()
The answered solution didn't work for me, the height of the view was still off. I ended up with this, which works well:
protected int dp2px(int dp){
final float scale = getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
And if you want the other way round, pixels to dp ...
protected float px2dp(float px){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return Math.round(dp);
}

Categories

Resources