2013-06-14 12 views
5

Jak mogę uzyskać dostępną wysokość ekranu w systemie Android? Potrzebuję wysokości bez paska stanu/paska menu lub innych dekoracji, które mogą być na ekranie i potrzebuję ich do pracy na wszystkich urządzeniach. Ponadto, muszę to wiedzieć w funkcji onCreate. Wiem, że to pytanie było już wcześniej zadawane, ale już wypróbowałem ich rozwiązania i żaden z nich nie działa. Oto niektóre z rzeczy, próbowałem:Jak uzyskać wysokość ekranu w systemie Android?

nie uwzględnia Pasek stanu Pasek/menu:

Display display = getWindowManager().getDefaultDisplay(); 
screenWidth = display.getWidth(); 
screenHeight = display.getHeight(); 

ani nie to:

Point size = new Point(); 
getWindowManager().getDefaultDisplay().getSize(size); 
screenWidth = size.x; 
screenHeight = size.y; 

Ani to:

Point size = new Point(); 
getWindowManager().getDefaultDisplay().getRealSize(size); 
screenWidth = size.x; 
screenHeight = size.y; 

To nie działa:

Display display = getWindowManager().getDefaultDisplay(); 
DisplayMetrics metrics = new DisplayMetrics(); 
display.getMetrics(metrics); 
// since SDK_INT = 1; 
screenWidth = metrics.widthPixels; 
screenHeight = metrics.heightPixels; 
try 
{ 
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar) 
    screenWidth = (Integer) Display.class.getMethod("getRawWidth").invoke(display); 
    screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display); 
} 
catch (Exception ignored) 
{ 
    // Do nothing 
} 
try 
{ 
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar) 
    Point realSize = new Point(); 
    Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize); 
    screenWidth = realSize.x; 
    screenHeight = realSize.y; 
} 
catch (Exception ignored) 
{ 
    // Do nothing 
} 

I wtedy używany następujący kod odjąć wysokość paska stanu i paska menu od wysokości ekranu:

int result = 0; 
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 
if (resourceId > 0) 
    result = getResources().getDimensionPixelSize(resourceId); 
screenHeight -= result; 
result = 0; 
if (screenHeight >= screenWidth) 
    resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); 
else 
    resourceId = getResources().getIdentifier("navigation_bar_height_landscape", "dimen", "android"); 
if (resourceId > 0) 
    result = getResources().getDimensionPixelSize(resourceId); 
screenHeight -= result; 

Na API 17 Daje to poprawnie oblicza wysokość paska stanu i menu pasek w pionie, ale nie w krajobrazie. Na API 10, zwraca 0. Muszę go do pracy najlepiej na wszystkich urządzeniach lub minimalnej API 10.

+0

Czy próbowałeś to code: http://stackoverflow.com/a/13026919/611600 – Ali

+0

Tak, próbowałem tego. Zobacz moją odpowiedź poniżej. Dzięki –

+0

możliwy duplikat [Uzyskaj wysokość ekranu w systemie Android] (http://stackoverflow.com/questions/17353822/get-the-screen-height-in-android) –

Odpowiedz

0

Oto, jak udało mi się uzyskać poprawne wymiary ekranu dla wszystkich urządzeń:

public class MainActivity extends Activity 
{ 
    static int ScreenWidth; 
    static int ScreenHeight; 
    static int ScreenWidthLandscape; 
    static int ScreenHeightLandscape; 

    private RelativeLayout layout; 
    private RelativeLayout.LayoutParams params; 
    private View top; 
    private View bottom; 

    @SuppressWarnings("deprecation") 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     layout = new RelativeLayout(this); 
     top = new View(this); 
     bottom = new View(this); 
     RelativeLayout.LayoutParams viewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); 
     viewParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
     top.setLayoutParams(viewParams); 
     viewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); 
     viewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 
     bottom.setLayoutParams(viewParams); 
     layout.addView(top); 
     layout.addView(bottom); 
     setContentView(layout); 
     final Intent intent = new Intent(this, myPackage.learnSpanishVerbs.Start.class); 

     final View view = getWindow().getDecorView().getRootView(); 
     ViewTreeObserver vto = view.getViewTreeObserver(); 
     vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
     { 
      @Override 
      public void onGlobalLayout() 
      { 
       int topLoc[] = new int[2]; 
       top.getLocationOnScreen(topLoc); 
       int BottomLoc[] = new int[2]; 
       bottom.getLocationOnScreen(BottomLoc); 
       boolean portrait = getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE; 
       if (portrait) 
       { 
        ScreenWidth = top.getWidth(); 
        ScreenHeight = BottomLoc[1] - topLoc[1]; 
       } 
       else 
       { 
        ScreenWidthLandscape = top.getWidth(); 
        ScreenHeightLandscape = BottomLoc[1] - topLoc[1]; 
       } 

       if (Build.VERSION.SDK_INT < 16) 
        view.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
       else 
        view.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
       startActivity(intent); 
       finish(); 
      } 
     }); 
    } 
} 
+0

Czy naprawdę potrzebujesz widoków z góry i z dołu? Czy nie wystarczy mieć układ obejmujący cały ekran i po prostu uzyskać jego wysokość w 'onGlobalLayout'? –

0

Najlepszym rozwiązaniem udało mi się wymyślić to:

Display display = getWindowManager().getDefaultDisplay(); 
DisplayMetrics metrics = new DisplayMetrics(); 
display.getMetrics(metrics); 
screenWidth = metrics.widthPixels; 
screenHeight = metrics.heightPixels; 

TypedValue tv = new TypedValue(); 
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
{ 
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) 
     screenHeight -= TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); 
} 

int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 
if (resourceId > 0) 
    screenHeight -= getResources().getDimensionPixelSize(resourceId); 

Ja testowałem go w API 7 - 17. Niestety, w interfejsie API 13 na dole znajduje się dodatkowa przestrzeń zarówno w poziomie, jak iw pionie, aw interfejsach API 10, 8 i 7 nie ma wystarczającej ilości miejsca na dole, zarówno w poziomie, jak iw pionie. (Nie testowałem na przestarzałych API).

+0

Czy byłeś w stanie znaleźć rozwiązanie tego problemu? – Jaydev

0

Czy próbowałeś wykonać obliczenia wysokości w OnWindowFocusChanged z klasy Activity? Eliminuje to problemy API poprzez obliczenie, co naprawdę chcesz, nie brudząc z pasków menu itp

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
     super.onWindowFocusChanged(hasFocus); 
     View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT); 
     screenHeight=content.getHeight(); 
} 
+0

Nie próbowałem tego, ale będzie działać tylko wtedy, gdy zostanie wywołany przed 'OnCreate'. –

+0

Tylko dla mojej własnej edukacji, jakie metody lub polecenia używasz, które muszą być kompletne przed onCreate? W moim własnym rozwiązaniu byłem w stanie przenieść wiele funkcji z onCreate do onWindosFocusChange i rzeczy pojawiły się poprawnie po wyświetleniu ekranu dla użytkownika. – smirciat

+0

Po prostu potrzebuję uzyskać prawidłową wysokość i szerokość ekranu przed lub w trakcie OnCreate, aby móc podać obiektom prawidłowy rozmiar i położenie. Mam to działa. Zobacz moje rozwiązanie. Twój kod nie będzie działał, ponieważ OnCreate jest wywoływany jako pierwszy. Dziękujemy za pomoc –

Powiązane problemy