Di ConstraintLayout
2.1, beberapa fitur ditambahkan untuk membantu
mengelola perangkat foldable, termasuk SharedValues
,
ReactiveGuide
, dan dukungan yang disempurnakan untuk animasi dengan MotionLayout
.
Nilai Bersama
Kami menambahkan mekanisme baru untuk memasukkan nilai runtime di ConstraintLayout
–
ini dimaksudkan untuk digunakan untuk nilai
seluruh sistem, karena semua instance
ConstraintLayout
dapat mengakses nilai.
Dalam konteks perangkat foldable, kita bisa menggunakan mekanisme ini untuk memasukkan posisi lipatan saat runtime:
Kotlin
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
Java
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
Pada helper kustom, Anda bisa mengakses nilai yang dibagikan dengan menambahkan pemroses untuk setiap perubahan:
Kotlin
val sharedValues: SharedValues = ConstraintLayout.getSharedValues() sharedValues.addListener(mAttributeId, this)
Java
SharedValues sharedValues = ConstraintLayout.getSharedValues(); sharedValues.addListener(mAttributeId, this);
Anda dapat melihat contoh FoldableExperiments
untuk melihat bagaimana kita menangkap posisi lipatan menggunakan
Library dan memasukkan Jetpack WindowManager
posisi ke dalam ConstraintLayout
.
Kotlin
inner class StateContainer : Consumer<WindowLayoutInfo> { override fun accept(newLayoutInfo: WindowLayoutInfo) { // Add views that represent display features for (displayFeature in newLayoutInfo.displayFeatures) { val foldFeature = displayFeature as? FoldingFeature if (foldFeature != null) { if (foldFeature.isSeparating && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL ) { // The foldable device is in tabletop mode val fold = foldPosition(motionLayout, foldFeature) ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold) } else { ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0); } } } } }
Java
class StateContainer implements Consumer<WindowLayoutInfo> { @Override public void accept(WindowLayoutInfo newLayoutInfo) { // Add views that represent display features for (DisplayFeature displayFeature : newLayoutInfo.getDisplayFeatures()) { if (displayFeature instanceof FoldingFeature) { FoldingFeature foldFeature = (FoldingFeature)displayFeature; if (foldFeature.isSeparating() && foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL ) { // The foldable device is in tabletop mode int fold = foldPosition(motionLayout, foldFeature); ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold); } else { ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0); } } } } }
fireNewValue()
mengambil ID yang mewakili nilai sebagai parameter pertama dan
nilai yang diinjeksikan
sebagai parameter kedua.
ReactiveGuide
Salah satu cara untuk memanfaatkan SharedValue
dalam tata letak, tanpa harus
menulis kode apa pun, adalah dengan menggunakan ReactiveGuide
. Cara ini akan menempatkan garis panduan horizontal atau vertikal sesuai dengan
SharedValue
tertaut.
<androidx.constraintlayout.widget.ReactiveGuide
android:id="@+id/fold"
app:reactiveGuide_valueId="@id/fold"
android:orientation="horizontal" />
Langkah ini dapat digunakan sebagaimana yang Anda lakukan dengan pedoman normal.
MotionLayout
untuk perangkat foldable
Kami menambahkan beberapa fitur di MotionLayout
pada versi 2.1 yang membantu proses morphing
status – sesuatu yang sangat berguna untuk perangkat foldable, seperti yang biasanya
harus menangani animasi di antara
berbagai tata letak yang mungkin.
Ada dua pendekatan yang tersedia untuk perangkat foldable:
- Saat runtime, perbarui tata letak Anda saat ini (
ConstraintSet
) untuk menampilkan atau menyembunyikan lipat. - Gunakan
ConstraintSet
terpisah untuk setiap status perangkat foldable yang ingin Anda mendukung (closed
,folded
, ataufully open
).
Menganimasikan ConstraintSet
Fungsi updateStateAnimate()
di MotionLayout
telah ditambahkan di versi 2.1
rilis:
Kotlin
fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)
Java
void updateStateAnimate(int stateId, ConstraintSet set, int duration);
Fungsi ini akan secara otomatis menganimasikan perubahan saat memperbarui elemen
ConstraintSet
daripada melakukan update langsung (yang dapat Anda lakukan dengan
updateState(stateId, constraintset)
). Hal ini memungkinkan Anda
untuk memperbarui UI pada
dengan cepat, tergantung perubahannya, seperti status perangkat foldable yang Anda gunakan.
ReactiveGuide
di dalam MotionLayout
ReactiveGuide
juga mendukung dua atribut yang berguna saat digunakan di dalam
MotionLayout
:
app:reactiveGuide_animateChange="true|false"
app:reactiveGuide_applyToAllConstraintSets="true|false"
Yang pertama akan memodifikasi ConstraintSet
saat ini dan menganimasikan perubahan
secara otomatis. Yang kedua akan menerapkan nilai baru ReactiveGuide
ke semua ConstraintSet
di MotionLayout
. Pendekatan yang khas untuk
perangkat foldable akan menggunakan ReactiveGuide
yang mewakili posisi lipat,
menyiapkan elemen tata letak yang relatif terhadap ReactiveGuide
.
Menggunakan beberapa ConstraintSet
untuk merepresentasikan status perangkat foldable
Daripada memperbarui status MotionLayout
saat ini, cara lain untuk merancang
UI untuk mendukung perangkat foldable adalah membuat status terpisah tertentu (termasuk
closed
, folded
, dan fully open
).
Dalam skenario ini, Anda mungkin masih perlu menggunakan ReactiveGuide
untuk mewakili
lipat, tetapi Anda akan memiliki lebih banyak kontrol (dibandingkan dengan
animasi saat memperbarui ConstraintSet
saat ini) mengenai bagaimana setiap status akan
untuk beralih ke proyek lain.
Dengan pendekatan ini, dalam pemroses DeviceState
, Anda cukup mengarahkan
MotionLayout
untuk bertransisi ke status tertentu melalui
MotionLayout.transitionToState(stateId)
.