解像度が480 x 800のPantechデバイス用にピクセル単位で指定された高さと幅でアプリケーションを作成しました。
G1デバイスの高さと幅を変換する必要があります。私はそれをdpに変換することで問題が解決し、両方のデバイスに同じ解決策が提供されると思いました。
ピクセルをdpに変換する簡単な方法はありますか? 助言がありますか?
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
/**
* This method 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
* @param context Context to get resources and device specific display metrics
* @return A float value to represent px equivalent to dp depending on device density
*/
public static float convertDpToPixel(float dp, Context context){
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
/**
* This method converts device specific pixels to density independent pixels.
*
* @param px A value in px (pixels) unit. Which we need to convert into db
* @param context Context to get resources and device specific display metrics
* @return A float value to represent dp equivalent to px value
*/
public static float convertPixelsToDp(float px, Context context){
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
できればUtil.Javaクラスに入れる
public static float dpFromPx(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float pxFromDp(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
density
は等しい
ldpi
上の.75
(120
dpi)mdpi
上の1.0
(160
dpi;ベースライン)hdpi
上の1.5
(240
dpi)xhdpi
上の2.0
(320
dpi)xxhdpi
上の3.0
(480
dpi)xxxhdpi
上の4.0
(640
dpi)この オンラインコンバータ を使用してdpi値で遊んでください。
編集:dpi
バケットとdensity
の間に1:1の関係はないようです。 xxhdpi
であるNexus 5X
は(2.625
の代わりに)density
の値が3
であるように見えます。 Device Metrics で自分の目で確かめてください。
XMLのディメンションを使用できるのであれば、とても簡単です。
あなたのres/values/dimens.xml
に:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="thumbnail_height">120dp</dimen>
...
...
</resources>
その後、あなたのJavaで:
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
Android開発ガイドによると:
px = dp * (dpi / 160)
しかし、多くの場合、ピクセル単位のデザインを受け取ったときは、これとは逆の方法でこれを実行します。そう:
dp = px / (dpi / 160)
240dpiデバイスを使用している場合、この比率は1.5です(前述のとおり)。これは、アプリケーションの60pxアイコンが40dpに等しいことを意味します。
あなたはこれを使うことができます.. コンテキストなし
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);
}
@Stanが述べたように..このアプローチを使うとシステムが密度を変えると問題を引き起こすかもしれません。だからそれに気をつけて!
個人的に私はそれをするためにContextを使っています。
Context
がなければ、エレガントな静的メソッド:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
DP to Pixel
の場合
dimens.xml
に値を作成します
<dimen name="textSize">20dp</dimen>
pixel
でその値を次のように取得します。
int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
したがって、次の公式を使用して、dpで指定された寸法から正しいピクセル数を計算できます。
public int convertToPx(int dp) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (dp * scale + 0.5f);
}
Kotlinを使っている人のために:
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
使用法:
64.toPx
32.toDp
Android SDKにはデフォルトのutilがあります。 http://developer.Android.com/reference/Android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
これはあなたにピクセルへの変換dpを与えるべきです:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
これにより、dpへの変換ピクセルが得られます。
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
fun convertDpToPixel(dp: Float, context: Context): Float {
return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
fun convertPixelsToDp(px: Float, context: Context): Float {
return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
public static float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
public static float convertPixelsToDp(float px, Context context) {
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
おそらく、values/dimenの中にディメンションがある場合の最善の方法は、getDimension()メソッドから直接ディメンションを取得することです。これにより、すでにピクセル値に変換されたディメンションが返されます。
context.getResources().getDimension(R.dimen.my_dimension)
これをもっとよく説明するために、
getDimension(int resourceId)
fLOATとしてすでにピクセルに変換された寸法を返します。
getDimensionPixelSize(int resourceId)
同じ値を返しますがintに切り捨てられますので、IN ANTEGERとして。
見る アンドロイドリファレンス
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics());
}
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
リソースはcontext.getResources()です。
kotlin-extensionを使うとより良くなります
fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()
fun Int.toDp(context: Context): Int = (this / context.resources.displayMetrics.density).toInt()
更新:
displayMetrics
は global shared Resources の一部であるため、Resources.getSystem()
を使用できます。
fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
このような:
public class ScreenUtils {
public static float dpToPx(Context context, float dp) {
if (context == null) {
return -1;
}
return dp * context.getResources().getDisplayMetrics().density;
}
public static float pxToDp(Context context, float px) {
if (context == null) {
return -1;
}
return px / context.getResources().getDisplayMetrics().density;
}
}
contextに依存し、float値を返します。staticメソッド
パフォーマンスが重要なアプリケーションを開発する場合は、次の最適化クラスを検討してください。
public final class DimensionUtils {
private static boolean isInitialised = false;
private static float pixelsPerOneDp;
// Suppress default constructor for noninstantiability.
private DimensionUtils() {
throw new AssertionError();
}
private static void initialise(View view) {
pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f;
isInitialised = true;
}
public static float pxToDp(View view, float px) {
if (!isInitialised) {
initialise(view);
}
return px / pixelsPerOneDp;
}
public static float dpToPx(View view, float dp) {
if (!isInitialised) {
initialise(view);
}
return dp * pixelsPerOneDp;
}
}
Kotlinの拡張機能を使ったもっと洗練されたアプローチ
/**
* Converts dp to pixel
*/
val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()
/**
* Converts pixel to dp
*/
val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
使用法:
println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
これは私にとってどのように機能するかです。
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
float d = displaymetrics.density;
int heightInPixels=(int) (h/d);
幅についても同じことができます。
ピクセルをdpに変換するには、 TypedValue を使用します。
ドキュメントが述べたように:動的に型付けされたデータ値のためのコンテナ。
applyDimension メソッドを使用します。
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
次のように、次元を保持するアンパックされた複素数データ値を最終的な浮動小数点値に変換します。
Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());
お役に立てば幸いです。
ピクセルと同じようにdpを使うべきです。それだけです。独立したピクセルを表示します。中密度の画面と同じ数値を使用します。高密度の画面では、サイズは魔法のように正確になります。
ただし、必要なのはレイアウト設計のfill_parentオプションです。ビューまたはコントロールを親コンテナの残りのサイズすべてに拡張する場合は、fill_parentを使用します。
PX
とDP
は異なりますが似ています。
DP
は、画面の物理的なサイズだけを考慮したときの解像度です。あなたがDP
を使うとき、それはあなたのレイアウトを異なったpixel
密度を持つ他の同じようなサイズのスクリーンに合わせるでしょう。
たまに実際にはpixels
が欲しいのですが、コードでディメンションを扱うときは、変換しない限り、実際のpixels
を常に扱っています。
Androidデバイスでは、通常のサイズのhdpi
スクリーン、DP
の800x480 is 533x320
(私は信じています)。 DP
をpixels /1.5
に変換し、*1.5
に戻す。これは1つの画面サイズとdpi
の場合のみで、設計によって変わります。私たちのアーティストは私にpixels
をくれました、そして私は上記の1.5
式でDP
に変換します。
Integer の値が必要な場合は、Math.round()を使用してfloatを最も近い整数に丸めます。
public static int pxFromDp(final float dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}
これは私のために動作します(C#):
int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
コトリン
fun spToPx(ctx: Context, sp: Float): Float {
return sp * ctx.resources.displayMetrics.scaledDensity
}
fun pxToDp(context: Context, px: Float): Float {
return px / context.resources.displayMetrics.density
}
fun dpToPx(context: Context, dp: Float): Float {
return dp * context.resources.displayMetrics.density
}
Java
public static float spToPx(Context ctx,float sp){
return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}
public static float pxToDp(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float dpToPx(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
React Native Javaコードには、すでにutilクラスがあります。
import com.facebook.react.uimanager.PixelUtil;
float dp = PixelUtil.toDIPFromPixel(somePixelValue);
最良の答えはAndroidフレームワーク自体から得られます。この平等を使用するだけです...
public static int dpToPixels(final DisplayMetrics display_metrics, final float dps) {
final float scale = display_metrics.density;
return (int) (dps * scale + 0.5f);
}
(dpをpxに変換)
Xamarin.Android用
float DpToPixel(float dp)
{
var resources = Context.Resources;
var metrics = resources.DisplayMetrics;
return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}
カスタムレンダラを作成するときは、これを非静的にする必要があります。