Di Android 12, API publik tersedia untuk menerapkan 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 pemburaman jendela, yang dapat digunakan untuk mendapatkan efek visual yang berbeda:
Blur latar belakang memungkinkan Anda membuat jendela dengan latar belakang yang diburamkan, sehingga menciptakan efek kaca buram.
Blur behind memungkinkan Anda memburamkan seluruh layar di belakang jendela (dialog), sehingga menciptakan efek kedalaman bidang.
Kedua efek tersebut dapat digunakan secara terpisah atau digabungkan, seperti yang ditunjukkan pada gambar berikut:
![]() a |
![]() b |
![]() c |
Gambar 1. Hanya blur latar belakang (a), hanya blur di belakang (b), blur latar belakang dan blur di belakang (c)
Fitur pemburaman jendela berfungsi di seluruh jendela, yang berarti 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. Blur jendela berguna untuk dialog, sheet bawah, dan jendela mengambang lainnya.
Implementasi
Developer aplikasi
Developer aplikasi harus menyediakan radius pemburaman untuk membuat efek pemburaman. Radius pemburaman mengontrol kepadatan pemburaman, yaitu semakin tinggi radius, makin padat pemburaman. Blur 0 px berarti tidak ada blur. Untuk blur di belakang, jari-jari 20 px akan menghasilkan efek kedalaman bidang yang baik, sedangkan radius blur latar belakang 80 px akan menghasilkan efek kaca buram yang baik. Hindari radius buram yang lebih tinggi dari 150 px, karena hal ini akan berdampak signifikan pada performa.
Untuk mendapatkan efek blur yang diinginkan dan meningkatkan keterbacaan, pilih nilai radius blur yang dilengkapi dengan lapisan warna transparan.
Blur latar belakang
Gunakan pemburaman latar belakang pada jendela mengambang untuk membuat efek latar belakang jendela yang merupakan gambar buram dari konten yang mendasarinya. Untuk menambahkan latar belakang buram untuk jendela, lakukan langkah-langkah berikut:
Panggil Window#setBackgroundBlurRadius(int) untuk menetapkan radius pemburaman latar belakang. Atau, di tema jendela, tetapkan R.attr.windowBackgroundBlurRadius.
Tetapkan R.attr.windowIsTranslucent ke benar untuk membuat jendela menjadi buram. Blur digambar di bawah permukaan jendela, sehingga jendela harus transparan 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 yang diburamkan dengan menetapkan ShapeDrawable dengan sudut membulat sebagai drawable latar belakang jendela.
Menangani status blur yang diaktifkan dan dinonaktifkan. Lihat bagian Panduan untuk menggunakan pemburaman jendela di aplikasi untuk mengetahui informasi selengkapnya.
Blur di belakang
Blur di belakang 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 belakang jendela, ikuti langkah-langkah berikut:
Tambahkan
FLAG_BLUR_BEHIND
ke flag jendela, untuk mengaktifkan pemburaman di belakang. Atau, di tema jendela, tetapkan R.attr.windowBlurBehindEnabled.Panggil
WindowManager.LayoutParams#setBlurBehindRadius
untuk menetapkan blur di belakang radius. Atau, di tema jendela, tetapkan R.attr.windowBlurBehindRadius.Secara opsional, pilih jumlah dimensi pelengkap.
Menangani status blur yang diaktifkan dan dinonaktifkan. Lihat bagian Panduan untuk menggunakan pemburaman jendela di aplikasi untuk mengetahui informasi selengkapnya.
Panduan untuk menggunakan pemburaman jendela di aplikasi
Dukungan untuk pemburaman jendela bergantung pada hal berikut:
Versi Android: API pemburaman jendela hanya tersedia di Android 12 dan yang lebih tinggi. Periksa SDK perangkat untuk mengetahui versi Android.
Performa grafis: Perangkat dengan GPU yang performanya lebih rendah mungkin memilih untuk tidak mendukung pemburaman jendela.
Status sistem: Server sistem mungkin menonaktifkan pemburaman jendela untuk sementara saat runtime, misalnya, selama mode hemat baterai, saat memutar jenis konten video tertentu, atau karena penggantian developer.
Agar aplikasi Anda kompatibel di seluruh versi Android, perangkat, dan status sistem, ikuti panduan berikut:
Tambahkan pemroses melalui WindowManager#addCrossWindowBlurEnabledListener, untuk memberi tahu Anda saat pemburaman jendela diaktifkan atau dinonaktifkan. Selain itu, gunakan
WindowManager#isCrossWindowBlurEnabled
untuk membuat kueri apakah pemburaman jendela saat ini diaktifkan.Terapkan dua versi untuk latar belakang jendela, untuk mengakomodasi status blur jendela yang diaktifkan atau dinonaktifkan.
Saat pemburaman diaktifkan, latar belakang jendela harus transparan agar keburaman terlihat. Dalam status ini, saat pemburaman dinonaktifkan, konten jendela akan langsung tumpang-tindih dengan konten jendela yang mendasarinya, sehingga jendela yang tumpang-tindih menjadi kurang jelas. Untuk menghindari efek tersebut, saat pemburaman jendela dinonaktifkan, sesuaikan UI aplikasi sebagai berikut:
Untuk pemburaman latar belakang, tingkatkan alfa drawable latar belakang jendela, sehingga 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
20 px dan radius blur latar belakang 80 px. Drawable ini memiliki sudut membulat, yang ditentukan dalam xml di drawable latar belakang jendela. Fitur ini menangani
versi Android yang berbeda, perangkat yang berbeda (yang berpotensi tidak
mendukung pemburaman jendela), dan perubahan pemburaman runtime yang diaktifkan atau dinonaktifkan dengan benar. Hal ini memastikan
bahwa konten dialog dapat dibaca dalam kondisi apa pun dengan menyesuaikan
alpha drawable latar belakang jendela dan jumlah redup 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 membulat untuk jendela, kita menentukan latar belakang jendela di
res/drawable/window_background.xml
sebagai ShapeDrawable dengan sudut membulat
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 yang diburamkan digambar di bawah jendela aktivitas ini, sehingga jendela aktivitas harus transparan agar pemburaman dapat terlihat. Untuk membuat jendela menjadi buram, kita menetapkan R.attr.windowIsTranslucent di tema aktivitas sebagai berikut:
<style name="Theme.BlurryDialog" parent="Theme.MaterialComponents.Dialog">
<item name="android:windowIsTranslucent">true</item>
</style>
OEM dan partner
Untuk memiliki pemburaman jendela di perangkat, OEM harus mendeklarasikan bahwa perangkat mendukung pemburaman jendela.
Untuk memeriksa apakah perangkat Anda dapat mendukung pemburaman jendela, lakukan hal berikut:
Pastikan perangkat dapat menangani beban GPU tambahan. Perangkat kelas bawah mungkin tidak dapat menangani beban tambahan, yang dapat menyebabkan frame terputus. Hanya aktifkan pemburaman jendela di perangkat yang diuji dengan daya GPU yang memadai.
Jika Anda memiliki mesin render yang disesuaikan, pastikan mesin render menerapkan logika pemburaman. Mesin render Android 12 default menerapkan logika pemburaman di
BlurFilter.cpp
.
Setelah memastikan bahwa perangkat Anda dapat mendukung pemburaman jendela, tetapkan
sysprop
flinger platform 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 yang diaktifkan dan dinonaktifkan, ikuti langkah-langkah berikut:
Buka UI yang memiliki pemburaman.
Aktifkan atau nonaktifkan pemburaman jendela dengan mengaktifkan dan menonaktifkan pemburaman jendela.
Verifikasi bahwa UI jendela berubah ke dan dari status buram seperti yang diharapkan.
Mengaktifkan dan menonaktifkan blur jendela
Untuk menguji cara UI jendela dirender dengan efek pemburaman jendela, aktifkan atau nonaktifkan pemburaman menggunakan salah satu metode berikut:
Dari Opsi Developer:
Setelan -> Sistem -> Opsi developer -> Rendering dengan akselerasi hardware -> Izinkan pemburaman 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 pemburaman
jendela dan apakah pemburaman jendela saat ini diaktifkan, jalankan
adb shell wm disable-blur
di perangkat yang di-root.
Pemecahan masalah
Gunakan informasi berikut sebagai panduan untuk memecahkan masalah selama validasi.
Tidak ada pemburaman yang digambar
Pastikan pemburaman saat ini diaktifkan dan hardware Anda mendukungnya. Lihat Mengaktifkan dan menonaktifkan pemburaman jendela.
Pastikan Anda menetapkan warna latar belakang jendela yang transparan. Warna latar belakang jendela buram akan menyembunyikan area yang diburamkan.
Perangkat pengujian tidak mendukung pemburaman jendela
- Uji aplikasi Anda di emulator Android 12. Untuk menyiapkan emulator Android, lihat Menyiapkan emulator Android. Setiap perangkat virtual Android yang Anda buat dengan emulator mendukung pemburaman jendela.
Tidak ada sudut membulat
- Menetapkan drawable latar belakang jendela untuk menentukan sudut membulat. Drawable ini menentukan garis batas area yang diburamkan.
Memperbarui opsi developer tidak mengaktifkan pemburaman
- Periksa apakah perangkat berada dalam mode penghemat baterai atau apakah perangkat menggunakan tunneling multimedia. Di beberapa perangkat TV, pemburaman jendela juga dapat dinonaktifkan selama pemutaran video.
Blur latar belakang digambar dalam layar penuh, bukan dalam batas jendela
Periksa android:windowIsFloating untuk memastikan jendela Anda ditandai sebagai mengambang.
Pastikan drawable latar belakang jendela telah ditetapkan. Setelan ini menentukan garis batas area pemburaman.
Update dari pemroses tidak diterapkan di layar
- Pembaruan pemroses mungkin diterapkan ke instance jendela lama. Periksa apakah jendela dihancurkan dan dibuat ulang dengan update pemroses yang tepat.