Java 如何在Android中获得屏幕高度?
如何在Android中获得可用的屏幕高度?我需要的高度减去状态栏/菜单栏或任何其他装饰,可能会在屏幕上,我需要它的所有设备的工作。另外,我需要在onCreate函数中了解这一点。我知道以前有人问过这个问题,但我已经尝试过他们的解决方案,但没有一个有效。以下是我尝试过的一些事情: 这不考虑状态栏/菜单栏:Java 如何在Android中获得屏幕高度?,java,android,size,height,screen,Java,Android,Size,Height,Screen,如何在Android中获得可用的屏幕高度?我需要的高度减去状态栏/菜单栏或任何其他装饰,可能会在屏幕上,我需要它的所有设备的工作。另外,我需要在onCreate函数中了解这一点。我知道以前有人问过这个问题,但我已经尝试过他们的解决方案,但没有一个有效。以下是我尝试过的一些事情: 这不考虑状态栏/菜单栏: Display display = getWindowManager().getDefaultDisplay(); screenWidth = display.getWidth(); scree
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的理想工作 我想出的最佳解决方案是:
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)。您是否尝试过在活动类的onWindowFocusChanged中进行高度计算?通过计算您真正想要的内容,而不是弄乱菜单栏等,这消除了API的麻烦
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
screenHeight=content.getHeight();
}
以下是我如何为所有设备获得正确的屏幕尺寸:
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();
}
});
}
}
公共类MainActivity扩展活动
{
静态屏幕宽度;
静态屏幕高度;
静态景观;
静态屏幕高度景观;
私人住宅布局;
私有RelativeLayout.LayoutParams参数;
私家视窗;
私有视图底部;
@抑制警告(“弃用”)
@TargetApi(Build.VERSION\u code.JELLY\u BEAN)
@凌驾
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
布局=新的RelativeLayout(本);
顶部=新视图(此视图);
底部=新视图(此);
RelativeLayout.LayoutParams viewParams=新的RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_父项,1);
viewParams.addRule(RelativeLayout.ALIGN\u PARENT\u TOP);
top.setLayoutParams(viewParams);
viewParams=新的RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_父项,1);
viewParams.addRule(RelativeLayout.ALIGN\u PARENT\u BOTTOM);
bottom.setLayoutParams(viewParams);
布局。添加视图(顶部);
布局。添加视图(底部);
setContentView(布局);
最终意图=新意图(这个,myPackage.learnPanishVerbs.Start.class);
最终视图=getWindow().getDecorView().getRootView();
ViewTreeObserver vto=view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(新的OnGlobalLayoutListener()
{
@凌驾
公共图书馆
{
int-topLoc[]=新的int[2];
top.GetLocationOn屏幕(topLoc);
int BottomLoc[]=新int[2];
底部。getLocationOnScreen(底部定位);
布尔纵向=getResources().getConfiguration().orientation!=Configuration.orientation\u横向;
如果(肖像)
{
ScreenWidth=top.getWidth();
屏幕高度=底部位置[1]-顶部位置[1];
}
其他的
{
ScreenWidth横向=top.getWidth();
屏幕高度横向=底部位置[1]-顶部位置[1];
}
如果(Build.VERSION.SDK_INT<16)
view.getViewTreeObserver();
其他的
view.getViewTreeObserver();
星触觉(意向);
完成();
}
});
}
}
你试过这个代码吗:是的,我试过了。见下面我的答案。感谢可能的副本我没有尝试过这个,但只有在OnCreate
之前调用它,它才会起作用。只是为了我自己的教育,您使用哪些方法或命令需要在OnCreate之前完成?在我自己的解决方案中,我能够将许多功能从onCreate移动到onWindosFocusChange,并且在为用户显示屏幕数据后,屏幕显示正确。我只需要在onCreate之前或期间获得正确的屏幕高度和宽度,以便为我的对象提供正确的大小和位置。我让它工作。看看我的解决方案。此外,您的代码将无法工作,因为首先调用OnCreate。无论如何谢谢你的帮助我很高兴你有你需要的!谢谢你和我一起工作!你真的需要那些顶视图和底视图吗?在整个屏幕上有一个布局,并在onGlobalLayout
中获得其高度,这还不够吗?您能找到解决方案吗?