ความสูงของแถบสถานะใน Android คืออะไร มันเหมือนเดิมหรือไม่
จากการวัดของฉันดูเหมือนว่ามันจะ 25dp แต่ฉันไม่แน่ใจว่ามันมีความสูงเท่ากันในทุกแพลตฟอร์มหรือไม่
(ฉันต้องการทราบสิ่งนี้ในการดำเนินการเปลี่ยนสีจางจากกิจกรรมที่ไม่มีแถบสถานะไปเป็นสถานะที่เหมาะสม)
ความสูงของแถบสถานะใน Android คืออะไร มันเหมือนเดิมหรือไม่
จากการวัดของฉันดูเหมือนว่ามันจะ 25dp แต่ฉันไม่แน่ใจว่ามันมีความสูงเท่ากันในทุกแพลตฟอร์มหรือไม่
(ฉันต้องการทราบสิ่งนี้ในการดำเนินการเปลี่ยนสีจางจากกิจกรรมที่ไม่มีแถบสถานะไปเป็นสถานะที่เหมาะสม)
คำตอบ:
คำถามนี้ตอบก่อน ... ความสูงของแถบสถานะ?
อัพเดท ::
ตกลงความสูงของแถบสถานะขึ้นอยู่กับขนาดหน้าจอตัวอย่างเช่นในอุปกรณ์ที่มีขนาดหน้าจอ 240 X 320 ความสูงของแถบสถานะคือ 20px สำหรับอุปกรณ์ที่มีขนาดหน้าจอ 320 X 480 ความสูงของแถบสถานะคือ 25px สำหรับ อุปกรณ์ที่มี 480 x 800 ความสูงของแถบสถานะจะต้องเป็น 38px
ดังนั้นฉันแนะนำให้ใช้สคริปต์นี้เพื่อรับความสูงของแถบสถานะ
Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
int statusBarHeight = rectangle.top;
int contentViewTop =
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight= contentViewTop - statusBarHeight;
Log.i("*** Elenasys :: ", "StatusBar Height= " + statusBarHeight + " , TitleBar Height = " + titleBarHeight);
onCreate()วิธีการกิจกรรมของคุณใช้วิธีนี้:public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)ไม่ใช่วิธีที่ถูกต้องในการรับความสูงของแถบสถานะหากคุณอยู่ในโหมดหลายหน้าต่าง + หมุนตามแนวตั้ง + หน้าต่างที่สอง คุณจะได้รับค่ามาก (รวมความสูงที่ 1)
จากตัวอย่างโค้ดที่ฉันเคยใช้เพื่อให้ได้ความสูงของแถบสถานะมีเพียงอันเดียวที่ดูเหมือนจะใช้งานได้จริงในonCreateวิธีการของอันActivityนี้คือ:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
เห็นได้ชัดว่าความสูงที่แท้จริงของแถบสถานะจะถูกเก็บไว้เป็นทรัพยากร Android รหัสข้างต้นสามารถเพิ่มเข้าไปในContextWrapperชั้นเรียน (เช่น an Activity)
พบได้ที่http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/
บนอุปกรณ์ MDPI แถบสถานะคือ 25px เราสามารถใช้สิ่งนี้เป็นฐานและคูณด้วยความหนาแน่น (ปัดขึ้น) เพื่อรับความสูงของแถบสถานะบนอุปกรณ์ใด ๆ :
int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);
สำหรับการอ้างอิง: ldpi = .75, mdpi = 1, hdpi = 1.5, xhdpi = 2
การเข้ารหัสขนาดหรือการใช้การสะท้อนกลับเพื่อให้ได้ค่าstatus_bar_heightถือว่าเป็นการปฏิบัติที่ไม่ดี คริส Banes พูดคุยเกี่ยวกับเรื่องนี้ในที่ Droidcon นิวยอร์ก วิธีที่แนะนำในการรับขนาดแถบสถานะคือผ่านOnApplyWindowInsetsListener :
myView.setOnApplyWindowInsetsListener { view, insets -> {
val statusBarSize = insets.systemWindowInsetTop
return insets
}
นี้ถูกบันทึกอยู่ใน API 20 และยังเป็นที่ backported ผ่านViewAppCompat
ฉันได้รวมโซลูชันบางอย่างเข้าด้วยกัน:
public static int getStatusBarHeight(final Context context) {
final Resources resources = context.getResources();
final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
return resources.getDimensionPixelSize(resourceId);
else
return (int) Math.ceil((VERSION.SDK_INT >= VERSION_CODES.M ? 24 : 25) * resources.getDisplayMetrics().density);
}
ทางเลือกอื่น:
final View view = findViewById(android.R.id.content);
runJustBeforeBeingDrawn(view, new Runnable() {
@Override
public void run() {
int statusBarHeight = getResources().getDisplayMetrics().heightPixels - view.getMeasuredHeight();
}
});
แก้ไข: ทางเลือกในการเรียกใช้ JustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126
ตามแนวทางการออกแบบของ Google ; ความสูงของแถบสถานะคือ 24 dp
หากคุณต้องการความสูงของแถบสถานะเป็นพิกเซลคุณสามารถใช้วิธีการด้านล่าง:
private static int statusBarHeight(android.content.res.Resources res) {
return (int) (24 * res.getDisplayMetrics().density);
}
ซึ่งสามารถเรียกใช้จากกิจกรรมด้วย:
statusBarHeight(getResources());
ความสูงเริ่มต้นที่ใช้เป็น 25dp ด้วย Android Marshmallow (API 23) ความสูงจะลดลงเป็น 24dp
อัปเดต: โปรดทราบว่าตั้งแต่อายุของรอยหยักและการชกทั้งกล้องเริ่มต้นขึ้นการใช้ความสูงคงที่สำหรับแถบสถานะจะไม่ทำงานอีกต่อไป โปรดใช้ส่วนแทรกหน้าต่างแทน!
สิ่งนี้ยังใช้งานได้กับลิงก์ refrence
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
ฉันมีปัญหาแบบเดียวกันกับการได้รับความสูงของแถบสถานะใน onCreate มันใช้งานได้สำหรับฉัน
private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;
private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;
private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;
ภายในบนสร้าง:
DisplayMetrics displayMetrics = new DisplayMetrics();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
int statusBarHeight;
switch (displayMetrics.densityDpi) {
case DisplayMetrics.DENSITY_HIGH:
statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
break;
case DisplayMetrics.DENSITY_MEDIUM:
statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
break;
case DisplayMetrics.DENSITY_LOW:
statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
break;
default:
statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
}
ดู:
http://developer.android.com/reference/android/util/DisplayMetrics.html http://developer.android.com/guide/practices/ui_guidelines/icon_design.html
ความสูงอย่างเป็นทางการ24dpเป็นที่ที่ระบุไว้อย่างเป็นทางการโดย Google บนหน้าเว็บของ Android การออกแบบ
ใช่เมื่อฉันลองดูด้วยจะให้ผลลัพธ์ 25px นี่คือรหัสทั้งหมด:
public class SpinActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout lySpin = new LinearLayout(this);
lySpin.setOrientation(LinearLayout.VERTICAL);
lySpin.post(new Runnable()
{
public void run()
{
Rect rect = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
int contentViewTop =
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight = contentViewTop - statusBarHeight;
System.out.println("TitleBarHeight: " + titleBarHeight
+ ", StatusBarHeight: " + statusBarHeight);
}
}
}
}
240x320 - 20px
320x480 - 25px
480x800 + - 38px
ลองสิ่งนี้:
Rect rect = new Rect();
Window win = this.getWindow();
win.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight = contentViewTop - statusBarHeight;
Log.d("ID-ANDROID-CONTENT", "titleBarHeight = " + titleBarHeight );
มันไม่ได้ผลสำหรับฉันในวิธี onCreate สำหรับกิจกรรม แต่ทำเมื่อฉันใส่ไว้ใน onClickListener และให้ค่าการวัด 25
ความสูงของแถบสถานะคือ 24dp ใน android 6.0
<!-- Height of the status bar -->
<dimen name="status_bar_height">24dp</dimen>
<!-- Height of the bottom navigation / system bar. -->
<dimen name="navigation_bar_height">48dp</dimen>
คุณสามารถหาคำตอบได้ในซอร์สโค้ด: frameworks \ base \ core \ res \ res \ values \ dimens.xml
@android:dimen/status_bar_heightไม่ได้ผลสำหรับฉัน
เพื่อแก้ปัญหานี้ฉันใช้วิธีการรวมกัน สิ่งนี้จำเป็นสำหรับแท็บเล็ตที่แถบระบบจะลบพิกเซลเมื่อ display.getHeight () ถูกเรียกใช้ ดังนั้นก่อนอื่นให้ตรวจสอบว่ามีแถบของระบบอยู่หรือไม่จากนั้น Ben Claytons เข้าใกล้ซึ่งทำงานได้ดีบนโทรศัพท์
public int getStatusBarHeight() {
int statusBarHeight = 0;
if (!hasOnScreenSystemBar()) {
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
}
return statusBarHeight;
}
private boolean hasOnScreenSystemBar() {
Display display = getWindowManager().getDefaultDisplay();
int rawDisplayHeight = 0;
try {
Method getRawHeight = Display.class.getMethod("getRawHeight");
rawDisplayHeight = (Integer) getRawHeight.invoke(display);
} catch (Exception ex) {
}
int UIRequestedHeight = display.getHeight();
return rawDisplayHeight - UIRequestedHeight > 0;
}
ขอบคุณ@Niklas +1 นี่เป็นวิธีที่ถูกต้องที่จะทำ
public class MyActivity extends Activity implements android.support.v4.View.OnApplyWindowInsetsListener {
Rect windowInsets;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
View rootview = findViewById(android.R.id.content);
android.support.v4.View.ViewCompat.setOnApplyWindowInsetsListener(rootview, this);
}
android.support.v4.View.WindowInsetsCompat android.support.v4.View.OnApplyWindowInsetsListener.OnApplyWindowInsets(View v, android.support.v4.View.WindowInsetsCompat insets)
{
windowInsets = new Rect();
windowInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
//StatusBarHeight = insets.getSystemWindowInsetTop();
//Refresh/Adjust view accordingly
return insets;
}
}
โปรดแก้ตัวฉันหากรหัสไม่ถูกต้อง 100% แปลงจาก Xamarin C # แต่นี่เป็นเพียงของมัน ใช้งานได้กับ Notches ฯลฯ
โซลูชันเต็มหน้าจอที่ถูกจับคู่:
วิธีการแก้ปัญหานี้อาจดูเหมือนวิธีแก้ปัญหา แต่จริง ๆ แล้วบัญชีว่าแอปของคุณเป็นแบบเต็มหน้าจอ (หรือที่ซ่อนแถบสถานะ) หรือไม่:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int barheight = size.y - findViewById(R.id.rootView).getHeight();
วิธีนี้หากแอปของคุณเต็มหน้าจอในปัจจุบันbarheightจะเท่ากับ 0
โดยส่วนตัวฉันต้องใช้สิ่งนี้เพื่อแก้ไขพิกัด TouchEvent สัมบูรณ์ให้กับบัญชีสำหรับแถบสถานะดังนี้:
@Override
public boolean onTouch(View view,MotionEvent event) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int YCoord = (int)event.getRawY() - size.y + rootView.getHeight());
}
และนั่นจะได้รับพิกัด y ที่แน่นอนไม่ว่าจะเป็นแอปแบบเต็มหน้าจอหรือไม่
สนุก
บน Android 4.1 และสูงกว่าคุณสามารถตั้งค่าเนื้อหาแอปพลิเคชันของคุณให้ปรากฏด้านหลังแถบสถานะเพื่อให้เนื้อหาไม่ปรับขนาดเนื่องจากแถบสถานะจะซ่อนและแสดง หากต้องการทำสิ่งนี้ให้ใช้ SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN คุณอาจต้องใช้ SYSTEM_UI_FLAG_LAYOUT_STABLE เพื่อช่วยให้แอปของคุณรักษาเลย์เอาต์ที่เสถียร
เมื่อคุณใช้วิธีการนี้จะเป็นความรับผิดชอบของคุณเพื่อให้แน่ใจว่าส่วนที่สำคัญของ UI ของแอปของคุณ (ตัวอย่างเช่นการควบคุมในตัวในแอปพลิเคชั่นแผนที่) จะไม่ได้รับความคุ้มครองจากแถบระบบ นี่อาจทำให้แอปของคุณใช้งานไม่ได้ ในกรณีส่วนใหญ่คุณสามารถจัดการสิ่งนี้ได้โดยการเพิ่มคุณสมบัติ android: fitsSystemWindows ไปยังไฟล์เลย์เอาต์ XML ของคุณตั้งค่าเป็นจริง การทำเช่นนี้จะเป็นการปรับช่องว่างภายในของ ViewGroup แม่ให้เหลือที่ว่างสำหรับหน้าต่างระบบ นี่เพียงพอสำหรับการใช้งานส่วนใหญ่
อย่างไรก็ตามในบางกรณีคุณอาจจำเป็นต้องปรับเปลี่ยนการแพ็ดเริ่มต้นเพื่อให้ได้เลย์เอาต์ที่ต้องการสำหรับแอพของคุณ ในการจัดการโดยตรงกับเนื้อหาของคุณที่สัมพันธ์กับแถบระบบ (ซึ่งใช้พื้นที่ที่เรียกว่า "content insets" ของหน้าต่าง) ให้แทนที่ fitSystemWindows (rectets insets) เมธอด fitSystemWindows () ถูกเรียกโดยลำดับชั้นมุมมองเมื่อเนื้อหาที่แทรกสำหรับหน้าต่างมีการเปลี่ยนแปลงเพื่อให้หน้าต่างปรับเนื้อหาตามความเหมาะสม ด้วยการเอาชนะวิธีนี้คุณสามารถจัดการกับสิ่งที่แทรก (และรูปแบบของแอพของคุณ) ตามที่คุณต้องการ
แบบฟอร์ม: https://developer.android.com/training/system-ui/status.html#behind
ถ้าคุณรู้ว่าขนาด VS สูง
ชอบ
ตัวอย่างเช่นในอุปกรณ์ที่มีขนาดหน้าจอ 320 X 480 ความสูงของแถบสถานะคือ 25px สำหรับอุปกรณ์ที่มี 480 x 800 ความสูงของแถบสถานะต้องเป็น 38px
จากนั้นคุณสามารถรับความกว้างของมุมมอง / ขนาดหน้าจอคุณสามารถใช้คำสั่ง if else เพื่อรับความสูงของแถบสถานะ
เหตุผลที่คำตอบยอดนิยมใช้ไม่ได้กับบางคนเพราะคุณไม่สามารถรับมุมมองได้จนกว่าจะพร้อมที่จะแสดงผล ใช้OnGlobalLayoutListenerมิติเพื่อบอกขนาดเมื่อคุณสามารถ:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= 16) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
// Nice one, Google
decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
rect.top; // This is the height of the status bar
}
}
}
นี่เป็นวิธีที่น่าเชื่อถือที่สุด
เนื่องจากโหมดหลายหน้าต่างพร้อมใช้งานในขณะนี้แอปของคุณอาจไม่มีแถบสถานะอยู่ด้านบน
โซลูชันต่อไปนี้จัดการทุกกรณีโดยอัตโนมัติเพื่อคุณ
android:fitsSystemWindows="true"
หรือเป็นโปรแกรม
findViewById(R.id.your_root_view).setFitsSystemWindows(true);
คุณยังสามารถดูรูทได้ด้วย
findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการรับรูทดู - https://stackoverflow.com/a/4488149/9640177
เมื่อเร็ว ๆ นี้ปัญหานี้มีความเกี่ยวข้องกับฉันเพราะรอยขีดข่วนใน Pixel 3XL ของฉัน ฉันชอบวิธีแก้ปัญหาของนักพัฒนาระบบ Androidแต่ฉันต้องการที่จะรับความสูงของแถบสถานะได้ตามต้องการเพราะมันเป็นสิ่งจำเป็นสำหรับภาพเคลื่อนไหวแบบเต็มหน้าจอที่ฉันต้องการเล่นโดยเฉพาะ ฟังก์ชั่นด้านล่างเปิดใช้งานแบบสอบถามที่เชื่อถือได้:
private val DEFAULT_INSET = 96
fun getInsets(view: View?): Int {
var inset = DEFAULT_INSET
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Safe because only P supports notches
inset = view?.rootWindowInsets?.stableInsetTop ?: DEFAULT_INSET
}
return inset
}
fun blurView(rootView: View?, a: SpacesActivity?) {
val screenBitmap = getBitmapFromView(rootView!!)
val heightDifference = getInsets(rootView)
val croppedMap = Bitmap.createBitmap(
screenBitmap, 0, heightDifference,
screenBitmap.width,
screenBitmap.height - heightDifference)
val blurredScreen = blurBitmap(croppedMap)
if (blurredScreen != null) {
val myDrawable = BitmapDrawable(a!!.resources, blurredScreen)
a.errorHudFrameLayout?.background = myDrawable
a.appBarLayout?.visibility = View.INVISIBLE
}
}
แล้วในชั้นเรียนกิจกรรม:
fun blurView() {
this.runOnUiThread {
Helper.blurView(this)
}
}
แน่นอนว่าคุณจะต้องการส่งผ่านการอ้างอิงที่อ่อนแอของกิจกรรมไปยังพารามิเตอร์เมธอดคลาส Helper แบบสแตติก แต่เพื่อความกะทัดรัดที่ฉันงดเว้นในตัวอย่างนี้ blurBitmapและerrorHudFrameLayoutจะถูกตัดออกด้วยเหตุผลเดียวกันเนื่องจากพวกเขาไม่ได้เกี่ยวข้องโดยตรงกับการได้รับความสูงของแถบสถานะ
รุ่น Kotlin ที่รวมสองโซลูชั่นที่ดีที่สุด
fun getStatusBarHeight(): Int {
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
return if (resourceId > 0) resources.getDimensionPixelSize(resourceId)
else Rect().apply { window.decorView.getWindowVisibleDisplayFrame(this) }.top
}
status_bar_heightค่าถ้ามีstatus_bar_heightไม่มีอยู่ให้คำนวณความสูงของแถบสถานะจากการตกแต่งหน้าต่าง