در نسخه ConstraintLayout
2.1، چندین ویژگی برای کمک به مدیریت دستگاه های تاشو اضافه شد، از جمله SharedValues
، ReactiveGuide
، و پشتیبانی پیشرفته از انیمیشن با MotionLayout
.
ارزش های مشترک
ما یک مکانیسم جدید برای تزریق مقادیر زمان اجرا در ConstraintLayout
اضافه کردیم - این در نظر گرفته شده است که برای مقادیر در سراسر سیستم استفاده شود، زیرا تمام نمونه های ConstraintLayout
قادر به دسترسی به مقدار هستند.
در زمینه دستگاه های تاشو، می توانیم از این مکانیسم برای تزریق موقعیت تا در زمان اجرا استفاده کنیم:
کاتلین
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
جاوا
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
در یک Helper سفارشی، میتوانید با افزودن یک شنونده برای هر گونه تغییر، به مقادیر مشترک دسترسی داشته باشید:
کاتلین
val sharedValues: SharedValues = ConstraintLayout.getSharedValues() sharedValues.addListener(mAttributeId, this)
جاوا
SharedValues sharedValues = ConstraintLayout.getSharedValues(); sharedValues.addListener(mAttributeId, this);
میتوانید به مثال FoldableExperiments نگاه کنید تا ببینید که چگونه با استفاده از کتابخانه Jetpack WindowManager موقعیت فولد را ضبط کرده و موقعیت را به ConstraintLayout
تزریق میکنیم.
کاتلین
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); } } } } }
جاوا
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()
شناسه ای می گیرد که مقدار را به عنوان پارامتر اول و مقداری را که باید به عنوان پارامتر دوم تزریق می کند، نشان دهد.
ReactiveGuide
یکی از راههای استفاده از SharedValue
در طرحبندی، بدون نیاز به نوشتن کد، استفاده از راهنما ReactiveGuide
است. این یک دستورالعمل افقی یا عمودی را مطابق با SharedValue
پیوند داده شده قرار می دهد.
<androidx.constraintlayout.widget.ReactiveGuide
android:id="@+id/fold"
app:reactiveGuide_valueId="@id/fold"
android:orientation="horizontal" />
سپس می توان آن را به عنوان یک دستورالعمل معمولی استفاده کرد.
MotionLayout
برای تاشوها
ما چندین ویژگی را در MotionLayout
در نسخه 2.1 اضافه کردیم که به شکلگیری حالت کمک میکند – چیزی که مخصوصاً برای تاشوها مفید است، زیرا ما معمولاً باید انیمیشن بین طرحبندیهای مختلف ممکن را مدیریت کنیم.
دو روش برای تاشوها وجود دارد:
- در زمان اجرا، طرحبندی فعلی خود (
ConstraintSet
) را بهروزرسانی کنید تا صفحه نمایش داده یا پنهان شود. - از یک
ConstraintSet
جداگانه برای هر یک از حالت های تاشو که می خواهید پشتیبانی کنید (closed
،folded
یاfully open
) استفاده کنید.
متحرک سازی یک ConstraintSet
تابع updateStateAnimate()
در MotionLayout
در نسخه 2.1 اضافه شد:
کاتلین
fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)
جاوا
void updateStateAnimate(int stateId, ConstraintSet set, int duration);
این تابع بهجای انجام بهروزرسانی فوری (که میتوانید با updateState(stateId, constraintset)
انجام دهید، هنگام بهروزرسانی یک ConstraintSet
، بهطور خودکار تغییرات را متحرک میکند. این به شما این امکان را می دهد که بسته به تغییرات، مانند حالت تاشو که در آن هستید، رابط کاربری خود را به سرعت به روز کنید.
ReactiveGuide
در داخل MotionLayout
ReactiveGuide
همچنین هنگام استفاده در MotionLayout
از دو ویژگی مفید پشتیبانی می کند:
app:reactiveGuide_animateChange="true|false"
app:reactiveGuide_applyToAllConstraintSets="true|false"
اولین مورد ConstraintSet
فعلی را تغییر می دهد و تغییر را به طور خودکار متحرک می کند. مورد دوم مقدار جدید موقعیت ReactiveGuide
را برای همه ConstraintSet
در MotionLayout
اعمال می کند. یک رویکرد معمولی برای تاشوها استفاده از ReactiveGuide
است که موقعیت تاشو را نشان میدهد و عناصر چیدمان را نسبت به ReactiveGuide
تنظیم میکند.
استفاده از چندین ConstraintSet
برای نمایش وضعیت تاشو
به جای بهروزرسانی وضعیت MotionLayout
فعلی، راه دیگری برای معماری رابط کاربری خود برای پشتیبانی از تاشوها، ایجاد حالتهای جداگانه خاص (از جمله closed
، folded
و fully open
) است.
در این سناریو، ممکن است همچنان بخواهید از یک ReactiveGuide
برای نمایش فولد استفاده کنید، اما کنترل بسیار بیشتری (در مقایسه با انیمیشن خودکار هنگام بهروزرسانی ConstraintSet
فعلی) در مورد نحوه انتقال هر حالت به حالت دیگر خواهید داشت.
با این رویکرد، در شنونده DeviceState
، شما به سادگی MotionLayout
برای انتقال به حالت های خاص از طریق متد MotionLayout.transitionToState(stateId)
هدایت می کنید.