2016-06-23 10 views
5

Ich möchte eine SeekBar auf Leinwand programmgesteuert zeichnen. Ich schrieb Code, um die LayoutParams der SeekBar basierend auf der Gerätedichte festzulegen. Ich bin mit Schaltergehäuse mit Gerätedichte wieZeichnung auf Leinwand Problem in High-End-Geräte

final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); 
if(metrics.densityDpi <= DisplayMetrics.DENSITY_LOW){ 
     zoomBarParams = new LinearLayout.LayoutParams(18, 
       LayoutParams.FILL_PARENT); 
     } else if (metrics.densityDpi <= DisplayMetrics.DENSITY_MEDIUM){ 
      zoomBarParams = new LinearLayout.LayoutParams(24, 
        LayoutParams.FILL_PARENT); 

     }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_HIGH){ 
      zoomBarParams = new LinearLayout.LayoutParams(24, 
        LayoutParams.FILL_PARENT); 

     }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_XHIGH){ 
      zoomBarParams = new LinearLayout.LayoutParams(31, 
        LayoutParams.FILL_PARENT); 


     }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_XXHIGH){ 
      zoomBarParams = new LinearLayout.LayoutParams(60, 
        LayoutParams.FILL_PARENT); 

     }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_XXXHIGH){ 
      zoomBarParams = new LinearLayout.LayoutParams(60, 
        LayoutParams.FILL_PARENT); 

     } else { 
      zoomBarParams = new LinearLayout.LayoutParams(60, 
        LayoutParams.FILL_PARENT); 

     } 

Aber das funktioniert nicht in High-End-Geräten wie Samsung Note 5, Galaxy S6 Edge-etc..I glaubt, dass diese Geräte im Dichtebereich XXXHIGH kommt, dann Warum funktioniert das nicht ?? Gibt es eine Beziehung zwischen Gerätedichte und Bildschirmgröße beim Zeichnen auf Leinwand? Jede Hilfe wird sehr geschätzt.

+0

Ich denke, Ihr Problem ist, dass 'densityDpiValue' nicht garantiert ist, genau einer der von' DisplayMetrics' Konstanten angegebenen Dichte zu entsprechen. Nehmen wir an, Sie erhalten eine Dichte von 321 - es wird keinen der Fälle auslösen. Überprüfen Sie die Bereiche. –

+0

Als Nebenfrage - welches Problem versuchen Sie mit einem solchen Schalter zu lösen? Warum nicht stattdessen 'dp' Werte verwenden? –

+0

@DmitryZaitsev Ja. Ich habe meinen Code aktualisiert, um nach der Reichweite zu suchen. Das Problem wurde in Samsung Note 5 und Galaxy S6 Edge gelöst. Aber das Problem besteht immer noch in S6 Edge +.Bitte beachten Sie meinen aktualisierten Code in Frage. – Jas

Antwort

2

Warum versuchen Sie nicht, alleloszuwerdenFälle und etwas Generisches machen? Da Sie abhängig von der Bildschirmgröße unterschiedliche Pixelwerte eingeben müssen, können Sie stattdessen dp verwenden.

Sie können px von dp abhängig von der Bildschirmdichte des Geräts erhalten und diese in LayoutParams verwenden.

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); // You can cache "((float)metrics.densityDpi/DisplayMetrics.DENSITY_DEFAULT)" to avoid re-calculation. 
    return px; 
} 

So finden Sie die param wie folgt erstellen:

zoomBarParams = new LinearLayout.LayoutParams(convertDpToPixel(DP_VALUE, context), 
       LayoutParams.FILL_PARENT); 

wo DP_VALUE wird über alle Geräte konstant bleiben.

Ich hoffe, dass dies Ihr Problem lösen könnte.

2

Problem ist, gibt es keinen generischen Code für dieses Problem.
Wenn Sie die ursprüngliche Dichte wünschen, können Sie metrics.xdpi und metrics.ydpi für horizontale und vertikale Dichte verwenden.

oder diesen Code gehen Sie folgendermaßen vor:

public static String getDensity(Resources resources) { 
    switch (resources.getDisplayMetrics().densityDpi) { 
     case DisplayMetrics.DENSITY_LOW: 
      return "ldpi"; 
     case DisplayMetrics.DENSITY_MEDIUM: 
      return "mdpi"; 
     case DisplayMetrics.DENSITY_HIGH: 
      return "hdpi"; 
     case DisplayMetrics.DENSITY_XHIGH: 
      return "xhdpi"; 
     case DisplayMetrics.DENSITY_XXHIGH: 
      return "xxhdpi"; 
     case DisplayMetrics.DENSITY_XXXHIGH: 
      return "xxxhdpi"; 
     case DisplayMetrics.DENSITY_TV: 
      return "tvdpi"; 
     default: 
      return "unknown"; 
    } 

Eine sehr ausführliche Erläuterung zu diesem Thema von diesem Kerl hier gegeben:

https://stackoverflow.com/a/33789580/5476209

auch überprüfen DisplayMetrics Abschnitt in Android-Entwickler-Dokumentation

1

Wenn Sie auf Leinwand arbeiten, meine Empfehlung, nur mit Pixeln zu spielen. Anstelle von dpi können Sie prozentuale Breite und Höhe entsprechend Ihrer Anforderung verwenden. Das passt am besten zu jedem Gerät. Zum Beispiel, wenn Sie eine Suchleiste von 600 x 128px für die Bildschirmgröße 800 x 1280 px benötigen. Dann ist es wie 75% der Breite und 10% der Höhe. Jetzt wenden Sie diesen Prozentsatz von Code-

DisplayMetrics dm = getResources().getDisplayMetrics(); 
int seekBarWidth= dm.widthPixels * 75/100; 
int seekBarHeight= dm.heightPixels * 10/100; 

Und das wird für alle Bildschirmgrößen perfekt funktionieren. Lassen Sie es mich wissen, falls Sie weitere Hilfe benötigen :)