ConstraintLayout
2.1 버전에는 SharedValues
, ReactiveGuide
및 MotionLayout
의 향상된 애니메이션 지원 등 폴더블 기기를 관리하는 데 도움이 되는 여러 기능이 추가되었습니다.
공유 값
ConstraintLayout
에 런타임 값을 삽입하는 새로운 메커니즘을 추가했습니다. 이는 ConstraintLayout
의 모든 인스턴스가 값에 액세스할 수 있으므로 시스템 전체 값에 사용하기 위한 것입니다.
폴더블 기기의 컨텍스트에서는 이 메커니즘을 사용하여 런타임에 접힘 위치를 삽입할 수 있습니다.
Kotlin
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
Java
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
맞춤 도우미에서는 모든 변경사항에 관한 리스너를 추가하여 공유된 값에 액세스할 수 있습니다.
Kotlin
val sharedValues: SharedValues = ConstraintLayout.getSharedValues() sharedValues.addListener(mAttributeId, this)
Java
SharedValues sharedValues = ConstraintLayout.getSharedValues(); sharedValues.addListener(mAttributeId, this);
FoldableExperimentals 예에서 Jetpack WindowManager 라이브러리를 사용하여 접힘의 위치를 캡처하고 위치를 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()
는 값을 첫 번째 매개변수로 나타내고 두 번째 매개변수로 삽입할 값을 나타내는 ID를 사용합니다.
ReactiveGuide
코드를 작성하지 않고도 레이아웃에서 SharedValue
를 활용하는 한 가지 방법은 ReactiveGuide
도우미를 사용하는 것입니다. 이렇게 하면 링크된 SharedValue
에 따라 가로 또는 세로 안내선이 배치됩니다.
<androidx.constraintlayout.widget.ReactiveGuide
android:id="@+id/fold"
app:reactiveGuide_valueId="@id/fold"
android:orientation="horizontal" />
그런 다음 일반 가이드라인과 마찬가지로 사용할 수 있습니다.
MotionLayout
(폴더블용)
2.1의 MotionLayout
에는 상태를 모핑하는 데 도움이 되는 몇 가지 기능이 추가되었습니다. 이 기능은 일반적으로 가능한 여러 레이아웃 간에 애니메이션을 처리해야 하므로 폴더블에 특히 유용한 기능입니다.
폴더블에 사용할 수 있는 접근 방식에는 두 가지가 있습니다.
- 런타임 시 현재 레이아웃 (
ConstraintSet
)을 업데이트하여 접힘 부분을 표시하거나 숨깁니다. - 지원하려는 폴더블 상태 (
closed
,folded
,fully open
)마다 별도의ConstraintSet
를 사용합니다.
ConstraintSet
에 애니메이션 적용
MotionLayout
의 updateStateAnimate()
함수가 2.1 출시에 추가되었습니다.
Kotlin
fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)
Java
void updateStateAnimate(int stateId, ConstraintSet set, int duration);
이 함수는 즉시 업데이트를 실행하는 대신 지정된 ConstraintSet
를 업데이트할 때 변경사항을 자동으로 애니메이션으로 보여줍니다 (updateState(stateId, constraintset)
로 실행 가능). 이렇게 하면 현재 폴더블 상태와 같은 변경사항에 따라 UI를 즉시 업데이트할 수 있습니다.
MotionLayout
내 ReactiveGuide
ReactiveGuide
는 MotionLayout
내에서 사용할 때 유용한 두 속성도 지원합니다.
app:reactiveGuide_animateChange="true|false"
app:reactiveGuide_applyToAllConstraintSets="true|false"
첫 번째 요소는 현재 ConstraintSet
를 수정하고 변경사항에 자동으로 애니메이션을 적용합니다. 두 번째는 ReactiveGuide
위치의 새 값을 MotionLayout
의 모든 ConstraintSet
에 적용합니다. 폴더블의 일반적인 접근 방식은 접힘 위치를 나타내는 ReactiveGuide
를 사용하여 ReactiveGuide
을 기준으로 레이아웃 요소를 설정하는 것입니다.
여러 ConstraintSet
를 사용하여 폴더블 상태 표현
현재 MotionLayout
상태를 업데이트하는 대신 폴더블을 지원하도록 UI를 설계하는 또 다른 방법은 특정 상태 (closed
, folded
, fully open
)를 별도로 만드는 것입니다.
이 시나리오에서도 ReactiveGuide
를 사용하여 접힘을 표시할 수 있지만, 각 상태가 다른 상태로 전환되는 방식을 (현재 ConstraintSet
를 업데이트할 때의 자동 애니메이션에 비해) 훨씬 더 세밀하게 제어할 수 있습니다.
이 접근 방식을 사용하면 DeviceState
리스너에서 MotionLayout.transitionToState(stateId)
메서드를 통해 MotionLayout
가 특정 상태로 전환되도록 간단히 지시할 수 있습니다.