ใน Android 12 มี API สาธารณะพร้อมใช้งานสำหรับ การใช้เอฟเฟกต์การเบลอหน้าต่าง เช่น การเบลอพื้นหลังและการเบลอพื้นหลัง
ใช้การเบลอหน้าต่างหรือการเบลอขอบหน้าต่างเพื่อเบลอหน้าจอด้านหลัง หน้าต่างที่กำหนด การเบลอหน้าต่างมี 2 ประเภท ซึ่งสามารถใช้เพื่อให้ได้ เอฟเฟ็กต์ภาพ:
การเบลอพื้นหลังช่วยให้คุณสร้างหน้าต่างที่มีพื้นหลังเบลอ ก็เกิดเอฟเฟกต์กระจกน้ำแข็งเกาะ
เบลอด้านหลัง ให้คุณเบลอทั้งหน้าจอด้านหลังหน้าต่าง (กล่องโต้ตอบ) เพื่อสร้างเอฟเฟกต์ระยะชัดลึก
เอฟเฟกต์ 2 อย่างนี้สามารถใช้แยกกันหรือใช้ร่วมกันได้ ดังที่ปรากฏในรูปต่อไปนี้
a |
ข |
ค |
รูปที่ 1 เบลอพื้นหลังเท่านั้น (a), เบลอด้านหลังเท่านั้น (b), เบลอพื้นหลัง และเบลอด้านหลัง (c)
ฟีเจอร์เบลอหน้าต่างจะทำงานได้กับหน้าต่างทุกบาน ซึ่งหมายความว่า มีแอปอื่นอยู่หลังหน้าต่าง เอฟเฟ็กต์นี้ไม่เหมือนกับ เอฟเฟกต์ภาพเบลอ ซึ่งจะเบลอเนื้อหาภายในหน้าต่างเดียวกัน การเบลอหน้าต่างคือ ซึ่งมีประโยชน์สำหรับกล่องโต้ตอบ Bottom Sheet และหน้าต่างแบบลอยอื่นๆ
การใช้งาน
นักพัฒนาแอป
นักพัฒนาแอปต้องระบุรัศมีการเบลอเพื่อสร้างเอฟเฟกต์เบลอ รัศมีการเบลอจะควบคุมความเข้มของการเบลอ กล่าวคือ ยิ่งรัศมีสูง ยิ่งเบลอมากเท่าไหร่ การเบลอ 0 พิกเซลหมายความว่าไม่มีการเบลอ สำหรับการเบลอด้านหลัง รัศมี 20 พิกเซลจะทำให้มีระยะชัดลึกของภาพที่ดี รัศมีการเบลอ 80 พิกเซลจะเกิดเอฟเฟกต์กระจกน้ำแข็งเกาะที่ดี หลีกเลี่ยงการเบลอ รัศมีสูงกว่า 150 พิกเซล เนื่องจากจะส่งผลต่อประสิทธิภาพอย่างมาก
เลือกการเบลอเพื่อให้ได้เอฟเฟกต์เบลอที่ต้องการและเพิ่มความอ่านง่าย ค่ารัศมีซึ่งเสริมด้วยชั้นสีโปร่งแสง
การเบลอพื้นหลัง
ใช้การเบลอพื้นหลังบนหน้าต่างแบบลอยเพื่อสร้างเอฟเฟกต์พื้นหลังของหน้าต่าง ซึ่งเป็นภาพเบลอของเนื้อหา หากต้องการเพิ่มพื้นหลังแบบเบลอให้กับหน้าต่าง ให้ทำดังนี้
เรียก Window#setBackgroundBlurRadius(int) ไปยัง กำหนดรัศมีการเบลอพื้นหลัง หรือตั้งค่า R.attr.windowBackgroundBlurRadius ในธีมหน้าต่าง
ตั้งค่า R.attr.windowIsTranslucent เป็นจริงเพื่อทำให้หน้าต่างโปร่งแสง ใช้การเบลอใต้หน้าต่าง พื้นผิว ดังนั้นหน้าต่างต้องโปร่งแสงเพื่อให้มองเห็นการเบลอ
(ไม่บังคับ) เรียก Window#setBackgroundDrawableResource(int) เพื่อ เพิ่มพื้นหลังหน้าต่างสี่เหลี่ยมผืนผ้าซึ่งถอนออกได้สีโปร่งแสง หรือตั้งค่า R.attr.windowBackground ในธีมหน้าต่าง
สำหรับหน้าต่างที่มีมุมโค้งมน ให้ระบุมุมโค้งมนสำหรับ พื้นที่ที่เบลอโดยการตั้งค่า ShapeDrawable โดยใช้มุมโค้งมน เป็นพื้นหลังของหน้าต่าง ซึ่งถอนออกได้
จัดการสถานะเปิดใช้และปิดใช้การเบลอ โปรดดูหลักเกณฑ์การใช้การเบลอหน้าต่างในแอป สำหรับข้อมูลเพิ่มเติม
เบลอด้านหลัง
ส่วนการเบลอด้านหลังจะเบลอทั้งหน้าจอด้านหลังหน้าต่าง ใช้เอฟเฟกต์นี้แล้ว เพื่อดึงความสนใจของผู้ใช้ไปที่เนื้อหาหน้าต่างด้วยการเบลอ บนหน้าจอด้านหลังหน้าต่าง
หากต้องการเบลอเนื้อหาด้านหลังหน้าต่าง ให้ทำตามขั้นตอนต่อไปนี้
เพิ่ม
FLAG_BLUR_BEHIND
ที่ธงหน้าต่างเพื่อเปิดใช้การเบลอด้านหลัง หรือตั้งค่าในธีมหน้าต่าง R.attr.windowBlurBehindEnabledโทรหา
WindowManager.LayoutParams#setBlurBehindRadius
ถึง กำหนดรัศมีด้านหลัง หรือตั้งค่าในธีมหน้าต่าง R.attr.windowBlurBehindRadiusหรือเลือกเสริมการหรี่แสงเสริม
จัดการสถานะเปิดใช้และปิดใช้การเบลอ โปรดดูหลักเกณฑ์การใช้การเบลอหน้าต่างในแอป สำหรับข้อมูลเพิ่มเติม
หลักเกณฑ์การใช้การเบลอหน้าต่างในแอป
การรองรับการเบลอหน้าต่างจะขึ้นอยู่กับปัจจัยต่อไปนี้
เวอร์ชัน Android: API การเบลอหน้าต่างพร้อมใช้งานใน Android 12 และ สูงขึ้น ตรวจสอบ SDK ของอุปกรณ์เพื่อดูเวอร์ชัน Android
ประสิทธิภาพของกราฟิก: อุปกรณ์ที่มี GPU ที่มีประสิทธิภาพต่ำกว่าอาจเลือกที่จะไม่ทำ รองรับการเบลอหน้าต่าง
สถานะระบบ: เซิร์ฟเวอร์ของระบบอาจปิดใช้งานการเบลอหน้าต่างชั่วคราวใน เช่น ขณะอยู่ในโหมดประหยัดแบตเตอรี่ขณะเล่นวิดีโอ เนื้อหาวิดีโอต่างๆ หรือเนื่องจากนักพัฒนาซอฟต์แวร์ลบล้าง
หากต้องการให้แอปใช้งานร่วมกันได้กับ Android ทุกเวอร์ชัน อุปกรณ์ และสถานะของระบบ ให้ทำตามหลักเกณฑ์ต่อไปนี้
เพิ่ม Listener ผ่านทาง WindowManager#addCrossWindowBlurEnabledListener เพื่อแจ้งให้คุณทราบเมื่อเปิดหรือปิดใช้การเบลอหน้าต่าง นอกจากนี้ ใช้
WindowManager#isCrossWindowBlurEnabled
เพื่อค้นหา เปิดใช้การเบลอหน้าต่างอยู่หรือไม่ใช้พื้นหลังหน้าต่าง 2 เวอร์ชันเพื่อรองรับ หรือปิดใช้งานการเบลอหน้าต่าง
เมื่อเปิดใช้การเบลอ พื้นหลังหน้าต่างควรโปร่งแสงเพื่อให้ ความเบลอที่มองเห็นได้ ในสถานะนี้ เมื่อปิดการเบลอ เนื้อหาในหน้าต่าง ทับซ้อนกับเนื้อหาของหน้าต่างที่ซ่อนอยู่โดยตรง ทำให้ หน้าต่างที่ทับซ้อนกัน อ่านได้น้อยลง เพื่อไม่ให้หน้าต่างเบลอ ปิดใช้อยู่ ให้ปรับเปลี่ยน UI ของแอปดังนี้
หากต้องการเบลอพื้นหลัง ให้เพิ่มอัลฟ่าของพื้นหลังหน้าต่าง ทำให้ระบายสีได้ ทำให้ดูคลุมเครือมากขึ้น
หากต้องการเบลอด้านหลัง ให้เพิ่มเลเยอร์สลัวโดยมีระดับแสงสลัวสูงขึ้น
ตัวอย่างการเบลอด้านหลังและการเบลอพื้นหลัง
ส่วนนี้แสดงตัวอย่างกิจกรรมที่ใช้การเบลอ ด้านหลังและพื้นหลัง
ตัวอย่างต่อไปนี้ของ MainActivity.java
คือกล่องโต้ตอบที่มีการเบลอ
ด้านหลังรัศมี 20 พิกเซล และรัศมีการเบลอพื้นหลัง 80 พิกเซล มี
มุมโค้งมน ซึ่งกำหนดไว้ใน XML ในพื้นหลังหน้าต่างซึ่งถอนออกได้ ถูกต้อง
จัดการ Android เวอร์ชันต่างๆ หลายอุปกรณ์ (ที่อาจจะไม่
รองรับการเบลอหน้าต่าง) และการเบลอรันไทม์ตามการเปิดใช้หรือปิดใช้การเปลี่ยนแปลง ช่วยให้มั่นใจได้ว่า
เนื้อหาของกล่องโต้ตอบสามารถอ่านได้ภายใต้เงื่อนไขเหล่านั้นโดยการปรับ
พื้นหลังของหน้าต่าง Alpha ที่ถอนออกได้และจำนวนการสลัวหน้าต่าง
public class MainActivity extends Activity {
private final int mBackgroundBlurRadius = 80;
private final int mBlurBehindRadius = 20;
// We set a different dim amount depending on whether window blur is enabled or disabled
private final float mDimAmountWithBlur = 0.1f;
private final float mDimAmountNoBlur = 0.4f;
// We set a different alpha depending on whether window blur is enabled or disabled
private final int mWindowBackgroundAlphaWithBlur = 170;
private final int mWindowBackgroundAlphaNoBlur = 255;
// Use a rectangular shape drawable for the window background. The outline of this drawable
// dictates the shape and rounded corners for the window background blur area.
private Drawable mWindowBackgroundDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWindowBackgroundDrawable = getDrawable(R.drawable.window_background);
getWindow().setBackgroundDrawable(mWindowBackgroundDrawable);
if (buildIsAtLeastS()) {
// Enable blur behind. This can also be done in xml with R.attr#windowBlurBehindEnabled
getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
// Register a listener to adjust window UI whenever window blurs are enabled/disabled
setupWindowBlurListener();
} else {
// Window blurs are not available prior to Android S
updateWindowForBlurs(false /* blursEnabled */);
}
// Enable dim. This can also be done in xml, see R.attr#backgroundDimEnabled
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
/**
* Set up a window blur listener.
*
* Window blurs might be disabled at runtime in response to user preferences or system states
* (e.g. battery saving mode). WindowManager#addCrossWindowBlurEnabledListener allows to
* listen for when that happens. In that callback we adjust the UI to account for the
* added/missing window blurs.
*
* For the window background blur we adjust the window background drawable alpha:
* - lower when window blurs are enabled to make the blur visible through the window
* background drawable
* - higher when window blurs are disabled to ensure that the window contents are readable
*
* For window blur behind we adjust the dim amount:
* - higher when window blurs are disabled - the dim creates a depth of field effect,
* bringing the user's attention to the dialog window
* - lower when window blurs are enabled - no need for a high alpha, the blur behind is
* enough to create a depth of field effect
*/
@RequiresApi(api = Build.VERSION_CODES.S)
private void setupWindowBlurListener() {
Consumer<Boolean> windowBlurEnabledListener = this::updateWindowForBlurs;
getWindow().getDecorView().addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
getWindowManager().addCrossWindowBlurEnabledListener(
windowBlurEnabledListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
getWindowManager().removeCrossWindowBlurEnabledListener(
windowBlurEnabledListener);
}
});
}
private void updateWindowForBlurs(boolean blursEnabled) {
mWindowBackgroundDrawable.setAlpha(blursEnabled && mBackgroundBlurRadius > 0 ?
mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);
getWindow().setDimAmount(blursEnabled && mBlurBehindRadius > 0 ?
mDimAmountWithBlur : mDimAmountNoBlur);
if (buildIsAtLeastS()) {
// Set the window background blur and blur behind radii
getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);
getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);
getWindow().setAttributes(getWindow().getAttributes());
}
}
private static boolean buildIsAtLeastS() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
}
}
หากต้องการสร้างมุมโค้งมนสำหรับหน้าต่าง เราจะกำหนดพื้นหลังของหน้าต่างใน
res/drawable/window_background.xml
เป็น ShapeDrawable ที่มีมุมโค้งมน
ที่มีรัศมี 20 dp ดังต่อไปนี้
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners android:radius="20dp"/>
<solid android:color="#AAAAAA"/>
</shape>
หน้าต่างจะเบลอการเบลอเนื้อหาของหน้าต่างใต้กิจกรรมนั้น ภาพที่เบลอจะถูกวาดใต้หน้าต่างกิจกรรมนี้ ดังนั้น หน้าต่างกิจกรรมต้องโปร่งแสงเพื่อให้เบลอ มองเห็นได้ เพื่อให้หน้าต่างโปร่งแสง เราตั้งค่า R.attr.windowIsTranslucent ใน ธีมกิจกรรมดังนี้
<style name="Theme.BlurryDialog" parent="Theme.MaterialComponents.Dialog">
<item name="android:windowIsTranslucent">true</item>
</style>
OEM และพาร์ทเนอร์
หากต้องการให้อุปกรณ์เบลอหน้าต่าง OEM ต้องประกาศว่าอุปกรณ์นั้น รองรับการเบลอหน้าต่าง
วิธีตรวจสอบว่าอุปกรณ์รองรับการเบลอหน้าต่างหรือไม่
ตรวจสอบว่าอุปกรณ์รองรับการทำงานของ GPU เพิ่มเติม อุปกรณ์ระดับล่าง อาจไม่สามารถรองรับโหลดเพิ่มเติม ซึ่งอาจทำให้เฟรมลดลงได้ เปิดใช้การเบลอหน้าต่างเฉพาะในอุปกรณ์ทดสอบที่มีกำลัง GPU เพียงพอ
หากคุณมีเครื่องมือการแสดงผลที่ปรับแต่งแล้ว โปรดตรวจสอบว่าเครื่องมือแสดงผล จะใช้ตรรกะการเบลอ Android 12 เริ่มต้น เครื่องมือการแสดงผล ใช้ตรรกะการเบลอใน
BlurFilter.cpp
เมื่อแน่ใจว่าอุปกรณ์รองรับการเบลอหน้าต่างแล้ว ให้ตั้งค่าต่อไปนี้
ปุ่มพื้นผิว sysprop
:
PRODUCT_VENDOR_PROPERTIES += \
ro.surface_flinger.supports_background_blur=1
การตรวจสอบความถูกต้อง
เพื่อตรวจสอบว่าหน้าต่างแอปได้รับการจัดการอย่างเหมาะสมเมื่อสลับระหว่างการเบลอ เปิดใช้และเบลอสถานะปิดใช้ ให้ทำตามขั้นตอนต่อไปนี้
เปิด UI ที่มีการเบลอ
เปิดหรือปิดใช้การเบลอหน้าต่างโดยเปิดและปิดการเบลอหน้าต่าง
ตรวจสอบว่า UI ของหน้าต่างเปลี่ยนเป็นและออกจากสถานะเบลอตามที่คาดไว้
เปิดและปิดการเบลอหน้าต่าง
หากต้องการทดสอบการแสดงผล UI หน้าต่างด้วยเอฟเฟกต์เบลอหน้าต่าง ให้เปิดใช้งาน หรือ ปิดใช้การเบลอโดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
จากตัวเลือกสำหรับนักพัฒนาแอป ให้ทำดังนี้
การตั้งค่า -> ระบบ -> ตัวเลือกสำหรับนักพัฒนาแอป -> การแสดงผลที่มีการเร่งด้วยฮาร์ดแวร์ -> อนุญาตการเบลอระดับหน้าต่าง
จากเทอร์มินัลในอุปกรณ์ที่รูท ให้ทำดังนี้
adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them
วิธีตรวจสอบว่าอุปกรณ์ Android 12 ขึ้นไปรองรับ Windows หรือไม่
เรียกใช้การเบลอและระบุว่าเปิดใช้การเบลอหน้าต่างอยู่หรือไม่
adb shell wm disable-blur
ในอุปกรณ์ที่รูท
การแก้ปัญหา
ใช้คำแนะนำต่อไปนี้เป็นแนวทางในการแก้ปัญหาระหว่างการตรวจสอบความถูกต้อง
ไม่มีการเบลอ
ตรวจสอบว่าการเบลอเปิดใช้อยู่และฮาร์ดแวร์ของคุณรองรับ โปรดดูหัวข้อเปิดและปิดการเบลอหน้าต่าง
ตรวจสอบว่าได้ตั้งค่าสีพื้นหลังของหน้าต่างโปร่งแสงแล้ว หน้าต่างที่ทึบแสง สีพื้นหลังจะซ่อนบริเวณที่เบลอ
อุปกรณ์ทดสอบไม่รองรับการเบลอหน้าต่าง
- ทดสอบแอปพลิเคชันในโปรแกรมจําลอง Android 12 หากต้องการตั้งค่าโปรแกรมจําลอง Android โปรดดูตั้งค่าโปรแกรมจําลอง Android อุปกรณ์เสมือนของ Android ที่คุณสร้างด้วยโปรแกรมจำลองจะรองรับหน้าต่าง เบลอ
ไม่มีมุมโค้งมน
- ตั้งค่าพื้นหลังของหน้าต่างที่ถอนออกได้ เพื่อกำหนดมุมโค้งมน เนื้อหาที่ถอนออกได้นี้จะกำหนดโครงร่างของ บริเวณที่เบลอ
การอัปเดตตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ไม่ได้เปิดใช้การเบลอ
- ตรวจสอบว่าอุปกรณ์อยู่ในโหมดประหยัดแบตเตอรี่หรือกำลังใช้ การสร้างอุโมงค์มัลติมีเดีย การเบลอหน้าต่างในอุปกรณ์ทีวีบางรุ่นอาจปิดใช้ในระหว่างการเล่นวิดีโอด้วย
เบลอพื้นหลังที่วาดเต็มหน้าจอ ไม่ใช่ภายในขอบเขตของหน้าต่าง
ตรวจสอบ android:windowIsFloating เพื่อให้แน่ใจว่าหน้าต่างของคุณ มีการทำเครื่องหมายเป็นแบบลอย
ตรวจสอบว่าได้ตั้งค่าพื้นหลังหน้าต่างที่ถอนออกได้ การตั้งค่านี้จะเป็นตัวกำหนด โครงร่างของพื้นที่เบลอ
ไม่มีการอัปเดตจากผู้ฟังบนหน้าจอ
- ระบบอาจนำการอัปเดต Listener ไปใช้กับอินสแตนซ์หน้าต่างเก่า ตรวจสอบว่าหน้าต่างถูกทำลายและสร้างอีกครั้งด้วยสิทธิ์ที่ถูกต้องหรือไม่ อัปเดต Listener