2013-06-14 3 views
5

Как я могу получить доступную высоту экрана в Android? Мне нужна высота за вычетом строки состояния или строки меню или любых других украшений, которые могут быть на экране, и мне нужно, чтобы она работала на всех устройствах. Кроме того, мне нужно знать это в функции onCreate. Я знаю, что этот вопрос задавали раньше, но я уже пробовал их решения, и никто из них не работает. Вот некоторые из вещей, которые я попробовал:Как получить высоту экрана в Android?

Это не принимает во внимание строку в строке состояния/меню:

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

Ни делает это:

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

Также это:

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

Это не работает:

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 
} 

Затем я использовал следующий код, чтобы вычесть высоту строки состояния и строки меню с высоты экрана:

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; 

На API 17 он дает правильно вычисляет высоту строки состояния и меню бар в портрете, но не в ландшафте. На API 10, она возвращает 0. Мне нужно работать в идеале на всех устройствах или минимального API 10.

+0

Вы пробовали это код: http://stackoverflow.com/a/13026919/611600 – Ali

+0

Да, я пробовал это. См. Мой ответ ниже. Спасибо –

+0

Возможный дубликат [Получить высоту экрана в Android] (http://stackoverflow.com/questions/17353822/get-the-screen-height-in-android) –

ответ

0

Вот как мне удалось получить правильные размеры экрана для всех устройств:

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

Вам действительно нужны эти виды сверху и снизу? Не достаточно ли иметь макет, охватывающий весь экран, и просто получить его высоту в 'onGlobalLayout'? –

0

Лучшее решение, которое я смог придумать это:

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); 

Я тестировал на API 7 - 17. К сожалению, на API 13 имеется дополнительное пространство внизу как по горизонтали, так и по вертикали, а на API 10, 8 и 7 недостаточно места внизу как по горизонтали, так и по вертикали. (Я не тестировал устаревшие API).

+0

Вы могли найти решение? – Jaydev

0

Вы пробовали выполнять вычисления высоты в onWindowFocusChanged класса Activity? Это устраняет API проблемы путем расчета того, что вы действительно хотите, а не возиться с меню баров и т.д.

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

Я не пробовал это, но он будет работать, только если он вызывается перед 'OnCreate'. –

+0

Как раз для моего собственного образования, какие методы или команды вы используете, которые должны быть заполнены до onCreate? В моем собственном решении мне удалось переместить много функций из onCreate в onWindosFocusChange, и все появилось правильно после того, как экран был ddisplayed для пользователя. – smirciat

+0

Мне просто нужно получить правильную высоту и ширину экрана до или во время OnCreate, чтобы я мог придать моим объектам правильный размер и положение. У меня есть работа. См. Мое решение. Кроме того, ваш код не будет работать, потому что сначала вызывается OnCreate. Спасибо в любом случае за вашу помощь –

Смежные вопросы