Di Android 12, API publik tersedia untuk mengimplementasikan efek blur jendela, seperti blur latar belakang dan blur di belakang.
Blur jendela, atau blur lintas jendela, digunakan untuk memburamkan layar di belakang jendela tertentu. Ada dua jenis blur jendela, yang dapat digunakan untuk mendapatkan efek visual yang berbeda:
Buram latar belakang memungkinkan Anda membuat jendela dengan latar belakang buram, sehingga menciptakan efek kaca buram.
Blur di belakang memungkinkan Anda memburamkan seluruh layar di belakang jendela (dialog), sehingga menciptakan efek depth of field.
Kedua efek ini dapat digunakan secara terpisah atau digabungkan, seperti yang ditunjukkan pada gambar berikut:
a |
b |
![]() c |
Gambar 1. Blur latar belakang saja (a), blur di belakang saja (b), blur latar belakang dan blur di belakang (c)
Fitur blur jendela berfungsi di seluruh jendela, yang berarti fitur ini juga berfungsi saat ada aplikasi lain di belakang jendela Anda. Efek ini tidak sama dengan efek render blur, yang memburamkan konten di dalam jendela yang sama. Buram jendela berguna untuk dialog, panel bawah, dan jendela mengambang lainnya.
Penerapan
Developer aplikasi
Developer aplikasi harus menyediakan radius blur untuk membuat efek blur. Radius blur mengontrol seberapa padat blur, yaitu, makin tinggi radius, makin padat blur. Blur 0 px berarti tidak ada blur. Untuk blur di belakang, radius 20 px menciptakan efek depth of field yang baik, sedangkan radius blur latar belakang 80 px menciptakan efek kaca buram yang baik. Hindari radius blur yang lebih tinggi dari 150 px, karena hal ini akan berdampak signifikan pada performa.
Untuk mencapai efek blur yang diinginkan dan meningkatkan keterbacaan, pilih nilai radius blur yang dilengkapi dengan lapisan warna transparan.
Blur latar belakang
Gunakan blur latar belakang pada jendela mengambang untuk membuat efek latar belakang jendela yang merupakan gambar buram dari konten di bawahnya. Untuk menambahkan latar belakang buram untuk jendela Anda, lakukan tindakan berikut:
Panggil Window#setBackgroundBlurRadius(int) untuk menetapkan radius blur latar belakang. Atau, di tema jendela, tetapkan R.attr.windowBackgroundBlurRadius.
Tetapkan R.attr.windowIsTranslucent ke true untuk membuat jendela menjadi transparan. Blur digambar di bawah permukaan jendela, sehingga jendela harus tembus cahaya agar blur terlihat.
Secara opsional, panggil Window#setBackgroundDrawableResource(int) untuk menambahkan drawable latar belakang jendela persegi panjang dengan warna transparan. Atau, di tema jendela, tetapkan R.attr.windowBackground.
Untuk jendela dengan sudut membulat, tentukan sudut membulat untuk area buram dengan menetapkan ShapeDrawable dengan sudut membulat sebagai drawable latar belakang jendela.
Menangani status blur diaktifkan dan dinonaktifkan. Lihat bagian Panduan untuk menggunakan blur jendela di aplikasi untuk mengetahui informasi selengkapnya.
Blur di belakang
Blur di belakang akan memburamkan seluruh layar di belakang jendela. Efek ini digunakan untuk mengarahkan perhatian pengguna ke konten jendela dengan memburamkan apa pun di layar di belakang jendela.
Untuk memburamkan konten di balik jendela, ikuti langkah-langkah berikut:
Tambahkan
FLAG_BLUR_BEHINDke flag jendela, untuk mengaktifkan blur di belakang. Atau, di tema jendela, tetapkan R.attr.windowBlurBehindEnabled.Panggil
WindowManager.LayoutParams#setBlurBehindRadiusuntuk menetapkan radius blur di belakang. Atau, di tema jendela, tetapkan R.attr.windowBlurBehindRadius.Jika perlu, pilih jumlah redup pelengkap.
Menangani status blur diaktifkan dan dinonaktifkan. Lihat bagian Panduan untuk menggunakan blur jendela di aplikasi untuk mengetahui informasi selengkapnya.
Panduan untuk menggunakan blur jendela di aplikasi
Dukungan untuk blur jendela bergantung pada hal berikut:
Versi Android: API blur jendela hanya tersedia di Android 12 dan yang lebih tinggi. Periksa SDK perangkat untuk mengetahui versi Android.
Performa grafis: Perangkat dengan GPU yang kurang berperforma mungkin memilih untuk tidak mendukung blur jendela.
Status sistem: Server sistem mungkin menonaktifkan sementara blur jendela saat runtime, misalnya, selama mode penghemat baterai, saat memutar jenis konten video tertentu, atau karena penggantian developer.
Agar aplikasi Anda kompatibel di berbagai versi Android, perangkat, dan status sistem, ikuti panduan berikut:
Tambahkan pemroses melalui WindowManager#addCrossWindowBlurEnabledListener, untuk memberi tahu Anda saat blur jendela diaktifkan atau dinonaktifkan. Selain itu, gunakan
WindowManager#isCrossWindowBlurEnableduntuk mengkueri apakah blur jendela saat ini diaktifkan.Terapkan dua versi untuk latar belakang jendela, untuk mengakomodasi status blur jendela yang diaktifkan atau dinonaktifkan.
Jika blur diaktifkan, latar belakang jendela harus transparan agar blur terlihat. Dalam status ini, saat blur dinonaktifkan, konten jendela langsung tumpang-tindih dengan konten jendela di bawahnya, sehingga jendela yang tumpang-tindih menjadi kurang terbaca. Untuk menghindari efek tersebut, saat blur jendela dinonaktifkan, sesuaikan UI aplikasi sebagai berikut:
Untuk blur latar belakang, tingkatkan alfa drawable latar belakang jendela, sehingga membuatnya lebih buram.
Untuk blur di belakang, tambahkan lapisan redup dengan jumlah redup yang lebih tinggi.
Contoh pemburaman di belakang dan pemburaman latar belakang
Bagian ini memberikan contoh kerja aktivitas yang menggunakan blur di belakang dan blur latar belakang.
Contoh MainActivity.java berikut adalah dialog dengan radius blur di belakang sebesar 20 px dan radius blur latar belakang sebesar 80 px. Dialog ini memiliki
sudut membulat, yang ditentukan dalam xml di drawable latar belakang jendela. Library ini menangani
berbagai versi Android, berbagai perangkat (yang berpotensi tidak
mendukung blur jendela), dan perubahan pengaktifan atau penonaktifan blur runtime dengan benar. Hal ini memastikan
bahwa konten dialog dapat dibaca dalam kondisi apa pun dengan menyesuaikan
alfa drawable latar belakang jendela dan jumlah peredupan jendela.
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;
}
}
Untuk membuat sudut lengkung pada jendela, kita menentukan latar belakang jendela di
res/drawable/window_background.xml sebagai ShapeDrawable dengan sudut lengkung
dengan radius 20 dp sebagai berikut:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners android:radius="20dp"/>
<solid android:color="#AAAAAA"/>
</shape>
Blur jendela memburamkan konten jendela di bawah aktivitas. Gambar buram digambar di bawah jendela aktivitas ini, sehingga jendela aktivitas harus transparan agar efek buram dapat terlihat. Untuk membuat jendela menjadi transparan, kita menetapkan R.attr.windowIsTranslucent dalam tema aktivitas sebagai berikut:
<style name="Theme.BlurryDialog" parent="Theme.MaterialComponents.Dialog">
<item name="android:windowIsTranslucent">true</item>
</style>
OEM dan partner
Agar memiliki pengaburan jendela di perangkat, OEM harus menyatakan bahwa perangkat mendukung pengaburan jendela.
Untuk memeriksa apakah perangkat Anda dapat mendukung blur jendela, lakukan hal berikut:
Pastikan perangkat dapat menangani beban GPU tambahan. Perangkat kelas bawah mungkin tidak dapat menangani beban tambahan, yang dapat menyebabkan frame yang dilewati. Hanya aktifkan blur jendela pada perangkat yang diuji dengan daya GPU yang memadai.
Jika Anda memiliki mesin rendering kustom, pastikan mesin rendering Anda menerapkan logika pemburaman. Mesin render Android 12 default mengimplementasikan logika pemburaman di
BlurFilter.cpp.
Setelah memastikan bahwa perangkat Anda dapat mendukung blur jendela, tetapkan
surface flinger sysprop berikut:
PRODUCT_VENDOR_PROPERTIES += \
ro.surface_flinger.supports_background_blur=1
Validasi
Untuk memvalidasi bahwa jendela aplikasi Anda memiliki penanganan yang tepat saat beralih antara status blur diaktifkan dan blur dinonaktifkan, ikuti langkah-langkah berikut:
Buka UI yang memiliki blur.
Aktifkan atau nonaktifkan blur jendela dengan mengaktifkan dan menonaktifkan blur jendela.
Pastikan UI jendela berubah ke dan dari status buram seperti yang diharapkan.
Mengaktifkan dan menonaktifkan blur jendela
Untuk menguji cara UI jendela dirender dengan efek blur jendela, aktifkan atau nonaktifkan blur menggunakan salah satu metode berikut:
Dari Opsi Developer:
Setelan -> Sistem -> Opsi developer -> Rendering yang dipercepat hardware -> Izinkan blur tingkat jendela
Dari terminal di perangkat yang telah di-root:
adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them
Untuk memeriksa apakah perangkat Android 12+ Anda mendukung blur
jendela dan apakah blur jendela saat ini diaktifkan, jalankan
adb shell wm disable-blur di perangkat yang telah di-root.
Pemecahan masalah
Gunakan panduan berikut untuk memecahkan masalah selama validasi.
Tidak ada blur yang digambar
Pastikan efek blur saat ini diaktifkan dan hardware Anda mendukungnya. Lihat Mengaktifkan dan menonaktifkan blur jendela.
Pastikan Anda menyetel warna latar belakang jendela yang transparan. Warna latar belakang jendela yang buram menyembunyikan area yang diburamkan.
Perangkat pengujian tidak mendukung blur jendela
- Menguji aplikasi Anda di emulator Android 12. Untuk menyiapkan Android Emulator, lihat Menyiapkan Android Emulator. Setiap perangkat virtual Android yang Anda buat dengan emulator mendukung blur jendela.
Tidak ada sudut membulat
- Tetapkan drawable latar belakang jendela untuk menentukan sudut membulat. Drawable ini menentukan garis luar area yang diburamkan.
Memperbarui opsi developer tidak mengaktifkan blur
- Periksa apakah perangkat dalam mode hemat baterai atau apakah perangkat menggunakan tunneling multimedia. Di beberapa perangkat TV, blur jendela juga mungkin dinonaktifkan selama pemutaran video.
Blur latar belakang digambar dalam layar penuh, bukan dalam batas jendela
Periksa android:windowIsFloating untuk memastikan bahwa jendela Anda ditandai sebagai mengambang.
Pastikan drawable latar belakang jendela telah ditetapkan. Setelan ini menentukan garis batas area blur.
Pembaruan dari pemroses tidak diterapkan di layar
- Update pemroses mungkin diterapkan ke instance jendela lama. Periksa apakah jendela dihancurkan dan dibuat ulang dengan update pemroses yang tepat.
