Impostare l'altezza su LayoutParams a livello di codice come pixel indipendenti dalla densità


123

C'è un modo per impostare l'altezza / larghezza di un LayoutParams come pixel indipendenti dalla densità (dp)? Sembra che l'altezza / larghezza, se impostate a livello di programmazione, siano in pixel e non dp.

Risposte:


271

Devi convertire il tuo valore di dip in pixel:

int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, <HEIGHT>, getResources().getDisplayMetrics());

Per me questo fa il trucco.


10
Penso che getActivity (). GetResources (). GetDimension (resourceID) faccia le corrette operazioni di conversione.
StErMi

3
Funziona per me, ma è diverso ... se imposto la larghezza / altezza di un ImageView utilizzando il metodo sopra rispetto all'utilizzo di xml. Nell'XML ho impostato 85dp mentre il metodo sopra ha bisogno di "75" per produrre la stessa dimensione. Qualche idea sul perché?
Dirk

1
@Dirk Probabilmente c'è un problema di riempimento / margine quando lo imposti in modo programmatico (di solito devi specificare il riempimento da solo quando imposti il ​​codice). Non dovrebbe esserci alcuna differenza tra l'impostazione di dp in XML o nel codice.
Tiago

11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Chiama la funzione in questo modo,

DisplayMetrics metrics;
metrics = new DisplayMetrics();         
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int heigh = getDPI(height or width, metrics);

Questo è ... davvero sbagliato. Hai hardcoded per supportare solo un numero fisso di densità. Se si desidera ridimensionare in base al fattore di ridimensionamento della densità, moltiplicare semplicemente per developer.android.com/reference/android/util/… che sarebbe anche lo stesso di fare (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
hackbod

1
Sì, la tua nuova risposta è ragionevole. O come ho detto, moltiplicare semplicemente per metrics.density. Ecco a cosa serve.
hackbod

6

Poiché può essere utilizzato più volte:

public static int convDpToPx(Context context, float dp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}

Ho trovato più pratico utilizzare il tasso di conversione, poiché di solito è necessario convertire più di un valore. Poiché il tasso di conversione non cambia, consente di risparmiare un po 'di tempo di elaborazione.

/**
 * 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;
}

5

Ecco il mio frammento:

public class DpiUtils {

    public static int toPixels(int dp, DisplayMetrics metrics) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
    }

}

dove DisplayMetrics metrics = getResources().getDisplayMetrics()


0

La soluzione risposta non ha funzionato per me, l'altezza della vista era ancora spenta. Ho finito con questo, che funziona bene:

protected int dp2px(int dp){
    final float scale = getResources().getDisplayMetrics().density;
    return (int) (dp * scale + 0.5f);
}

E se vuoi il contrario, i pixel a dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.