Di Android 12, API publik tersedia untuk mengimplementasikan efek pemburaman jendela, seperti pemburaman latar belakang dan pemburaman.
Blur jendela, atau blur lintas jendela, digunakan untuk memburamkan layar di belakang jendela tertentu. Ada dua jenis jendela blur yang dapat digunakan untuk mencapai berbagai efek visual:
Blur latar belakang memungkinkan Anda membuat jendela dengan latar belakang yang diburamkan, sehingga menciptakan efek kaca buram.
Blur di belakang memungkinkan Anda membuat blur seluruh layar di belakang jendela (dialog), sehingga menciptakan efek depth of field.
Kedua efek tersebut dapat digunakan secara terpisah atau digabungkan, seperti yang ditunjukkan pada gambar berikut:
a |
b |
k |
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. Jendela blur berguna untuk dialog, sheet bawah, dan jendela mengambang lainnya.
Implementasi
Developer aplikasi
Developer aplikasi harus menyediakan radius blur untuk membuat efek buram. Radius blur mengontrol seberapa rapat blur, yaitu, semakin tinggi radius, semakin padat blur. Blur 0 px berarti tidak ada blur. Untuk blur latar belakang, radius 20 px menciptakan efek kedalaman bidang yang baik, sedangkan radius blur latar belakang 80 px membuat efek kaca buram yang baik. Hindari radius buram yang lebih tinggi dari 150 px, karena akan memengaruhi performa secara signifikan.
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 hal berikut:
Panggil Window#setBackgroundBlurRadius(int) untuk menetapkan radius pemburaman latar belakang. Atau, di tema jendela, tetapkan R.attr.windowBackgroundBlurRadius.
Tetapkan R.attr.windowIsTranslucent ke true 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 aktif dan nonaktif. Lihat bagian Panduan menggunakan pemburaman jendela di aplikasi untuk informasi selengkapnya.
Buramkan 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 pada 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 redup yang saling melengkapi.
Menangani status blur aktif dan nonaktif. Lihat bagian Panduan menggunakan pemburaman jendela di aplikasi untuk informasi selengkapnya.
Panduan untuk menggunakan pemburaman jendela di aplikasi
Dukungan untuk window blur 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 berperforma 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 mengkueri apakah jendela blur saat ini diaktifkan.Implementasikan dua versi untuk latar belakang jendela, untuk mengakomodasi status pemburaman jendela yang diaktifkan atau dinonaktifkan.
Saat pemburaman diaktifkan, latar belakang jendela harus transparan agar blur terlihat. Dalam status ini, saat pemburaman dinonaktifkan, konten jendela langsung tumpang-tindih dengan konten jendela yang mendasarinya, sehingga jendela yang tumpang-tindih menjadi kurang jelas. Untuk menghindari efek ini, saat pemburaman jendela dinonaktifkan, sesuaikan UI aplikasi sebagai berikut:
Untuk pemburaman latar belakang, tingkatkan alfa drawable latar belakang jendela, sehingga lebih buram.
Untuk bagian belakang yang buram, tambahkan lapisan redup dengan tingkat 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 buram
di belakang layar 20 px dan radius blur latar belakang 80 px. Drawable ini memiliki sudut membulat, yang ditentukan dalam xml di drawable latar belakang jendela. Alat ini
menangani versi Android yang berbeda, perangkat yang berbeda (yang berpotensi tidak
mendukung pemburaman jendela), dan pemburaman runtime yang diaktifkan atau dinonaktifkan. Ini memastikan
bahwa konten dialog dapat dibaca dalam salah satu kondisi tersebut 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 membulat bagi jendela, kita tentukan latar belakang jendela di
res/drawable/window_background.xml
sebagai ShapeDrawable dengan sudut membulat
dengan radius 20 dp seperti berikut:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners android:radius="20dp"/>
<solid android:color="#AAAAAA"/>
</shape>
Jendela memburamkan konten jendela di bawah aktivitas. Gambar yang menjadi blur digambar di bawah jendela aktivitas ini, sehingga jendela aktivitas harus transparan agar pemburaman terlihat. Untuk membuat jendela transparan, kita tetapkan 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 jendela menjadi blur 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 kustom, pastikan mesin render Anda mengimplementasikan logika pemburaman. Mesin render Android 12 default mengimplementasikan logika pemburaman di
BlurFilter.cpp
.
Setelah memastikan bahwa perangkat dapat mendukung pemburaman jendela, tetapkan
surface flinger berikut sysprop
:
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, 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 blur jendela, aktifkan atau nonaktifkan blur 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 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 menyetel 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 akan mendukung blur 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 dalam mode hemat baterai atau menggunakan multimedia tunneling. 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. Pengaturan ini menentukan garis batas area yang diburamkan.
Update 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.