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);
}
Related
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)
I read that there is two kinds of referent pixels - w3c reference pixel and dip pixel. I do not understand how can I use the dip pixels. Do I have to write, for example, "width:100dip" or something like that. How can I specify this dip-pixels in my html+css+javascript code?
In XML:
android:layout_width="100dp"
In Java:
int width = dpToPx(100);
public static int dpToPx(int dpWidth) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
float screenDpWidth = displayMetrics.widthPixels / displayMetrics.density;
int screenPxWidth = Math.round((screenDpWidth) * displayMetrics.density);
int dpPxWidth = Math.round(screenPxWidth / screenDPWidth);
return dpPxWidth * dpWidth;
}
I have a custom action bar which i want a 80ish! height for it.
so i set my layouts height as 80dp with this code:
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
xdpi = displayMetrics.xdpi;
x = Math.round(80 * (xdpi / DisplayMetrics.DENSITY_DEFAULT))
... new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, x);
but its HUGE in xxxhdpi devices.
when i remove the conversion and use 80pixels value directly, it seems ok,
When to use converted dp and when to use direct pixel?
Edit:
the problem was somewhere else, i stored the "80dp" value in xml and retrieve it with "context.getResources().getDimension()", and it seems it converts the dimension to pixel internally and i was actually converting the converted value! I wonder if the same thing happens when using "sp" for fonts....
You're doing the right thing it's just your conversion is wrong, it should be something like this:
float scale = context.getResources().getDisplayMetrics().density;
x = Math.round(80 * scale);
... new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, x);
Convert dp to pixel:
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
Convert pixel to dp:
public int pxToDp(int px) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return dp;
}
Pixel to Dp converter
public static float pxToDp(float px) {
float densityDpi = Resources.getSystem().getDisplayMetrics().densityDpi;
return px / (densityDpi / 160f);
}
Dp to Pixel converter
public static int dpToPx(int dp) {
float density = Resources.getSystem().getDisplayMetrics().density;
return Math.round(dp * density);
}
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()
);
}
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);
}