More Related Content
Similar to Android - Motion Layout (20)
Android - Motion Layout
- 2. MotionLayout
๏ถ ์ ๋๋ฉ์ด์
์ค์ ์ ์ํ ConstraintLayout ์ ์์ํ ๋ ์ด์์
๏ถ ConstraintLayout ์ ๋๋ฉ์ด์
๊ณผ ๋ฌ๋ฆฌ ์ฌ์ฉ์์ ์
๋ ฅ์ ๋ฐ๋ฅธ ์ํธ์์ฉ ๊ฐ๋ฅ
๏ถ XML ์ ํตํด ์ ๋๋ฉ์ด์
์ ๋ณ๋์ ์ฝ๋ ์์ด ์ ์ ๊ฐ๋ฅ
๏ถ ์ ๋๋ฉ์ด์
๋์์ ์ํ MotionScene ํ์ผ ํ์
๏ถ ์ง๊ณ Child View ์๋ง ์ ์ฉํ ์ ์๋ ํ๊ณ์
๏ถ Android Support Library ๋๋ Android X Library ๋ฅผ ํตํด ์ฌ์ฉ ๊ฐ๋ฅ
Android Support Library Android X Library
Min SDK 18โ 14โ
Dependency
implementation 'com.android.support.constraint:constraint-
layout:2.0.0-beta1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-
beta1'
Refenece
https://developer.android.com/reference/android/support/constraint/
motion/MotionLayout?hl=en
https://developer.android.com/reference/androidx/constraintlayout/m
otion/widget/MotionLayout?hl=en
- 3. MotionScene
๏ถ ๋ ์ด์์์ ๋ชจ์
์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํ XML ํ์ผ
๏ถ res/xml ๊ฒฝ๋ก์ ์ ์ฅ
๏ถ ConstraintSet, Transition ๋ฑ์ ํฌํจ
๏ถ Alpha, Visibility, Rotation ๋ฑ์ ๊ฐ์ ์ค์ ํ ์ ๋๋ฉ์ด์
๊ฐ๋ฅ
๏ถ CustomAttribute ๋ฅผ ์ด์ฉํ์ฌ ์ฌ์ฉ์ ์ ์๊ฐ ์ถ๊ฐ ๊ฐ๋ฅ
๏ถ MotionLayout ์ app:layoutDescription ์์ฑ์ ์ง์ ํ์ฌ ๋ ์ด์์๊ณผ ์ฐ๊ฒฐ
๏ถ MotionScene ์ ์ ์๋ ๋ด์ฉ์ MotionLayout ์ ์ ์๋ ์ ์ฌํ ๋ด์ฉ๋ณด๋ค ์ฐ์ ์ ๋จ
- 4. Ex01. ๊ธฐ๋ณธ์ ์ธ ์ ๋๋ฉ์ด์
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/ex01_basic_motion"
app:showPaths="true"
tools:context=".ex01basic.Ex01BasicActivity">
<View
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryRed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.motion.MotionLayout>
[ activity_ex01_basic.xml ]
- 5. Ex01. ๊ธฐ๋ณธ์ ์ธ ์ ๋๋ฉ์ด์
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/ex01_basic_motion"
app:showPaths="true"
tools:context=".ex01basic.Ex01BasicActivity">
<View
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/colorPrimaryRed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.motion.MotionLayout>
[ activity_ex01_basic.xml ]
์ ๋๋ฉ์ด์
๋ด์ฉ์ ๊ธฐ์ฌํ ํ์ผ ์ฐ๊ฒฐ
- 6. <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@+id/view"
app:touchAnchorSide="bottom" />
</Transition>
<ConstraintSet android:id='@+id/start'>
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
</MotionScene>
Ex01. ๊ธฐ๋ณธ์ ์ธ ์ ๋๋ฉ์ด์
[ ex01_basic_motion.xml ]
- 7. <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@+id/view"
app:touchAnchorSide="bottom" />
</Transition>
<ConstraintSet android:id='@+id/start'>
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
</MotionScene>
Ex01. ๊ธฐ๋ณธ์ ์ธ ์ ๋๋ฉ์ด์
[ ex01_basic_motion.xml ]
์ ๋๋ฉ์ด์
์์/๋ ์ํ๋ฅผ ํฌํจํ
ConstraintSet ์ ๋ช
์
- 8. <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@+id/view"
app:touchAnchorSide="bottom" />
</Transition>
<ConstraintSet android:id='@+id/start'>
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
</MotionScene>
Ex01. ๊ธฐ๋ณธ์ ์ธ ์ ๋๋ฉ์ด์
[ ex01_basic_motion.xml ]
Swipe ์ ์ถ์ ํ๋ ค๋ ๋์ Id,
์ถ์ ํ๋ ค๋ ๋ชจ์
๋ฐฉํฅ,
์ถ์ ํ๋ ค๋ ๋์์ ์ธก๋ฉด ์ ์
- 9. <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@+id/view"
app:touchAnchorSide="bottom" />
</Transition>
<ConstraintSet android:id='@+id/start'>
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/view"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
</MotionScene>
Ex01. ๊ธฐ๋ณธ์ ์ธ ์ ๋๋ฉ์ด์
[ ex01_basic_motion.xml ]
์ ๋๋ฉ์ด์
์์/๋ ์ํ๋ฅผ ๋ช
์
Layout ํ์ผ์ ๊ธฐ์ฌ๋ ๋ด์ฉ๋ณด๋ค ์ฐ์ ๋์ด ์ ์ฉ
- 20. <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe />
<KeyFrameSet>
<KeyPosition
app:framePosition="20"
app:keyPositionType="parentRelative"
app:motionTarget="@+id/view"
app:percentX="0.1" />
<KeyPosition
app:framePosition="60"
app:keyPositionType="parentRelative"
app:motionTarget="@+id/view"
app:percentX="0.9" />
<KeyAttribute
android:rotation="360"
android:scaleX="2"
android:scaleY="2"
app:framePosition="50"
app:motionTarget="@+id/view" />
</KeyFrameSet>
</Transition>
โฆโฆ
</MotionScene>
Ex05. ํคํ๋ ์ ์ ๋๋ฉ์ด์
_2
[ ex05_keyframe2_motion.xml ]
- 21. <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe />
<KeyFrameSet>
<KeyPosition
app:framePosition="20"
app:keyPositionType="parentRelative"
app:motionTarget="@+id/view"
app:percentX="0.1" />
<KeyPosition
app:framePosition="60"
app:keyPositionType="parentRelative"
app:motionTarget="@+id/view"
app:percentX="0.9" />
<KeyAttribute
android:rotation="360"
android:scaleX="2"
android:scaleY="2"
app:framePosition="50"
app:motionTarget="@+id/view" />
</KeyFrameSet>
</Transition>
โฆโฆ
</MotionScene>
Ex05. ํคํ๋ ์ ์ ๋๋ฉ์ด์
_2
[ ex05_keyframe2_motion.xml ]
20, 60ํ๋ ์์ ๋ถ๋ชจ ๋ทฐ๋ฅผ ๊ธฐ์ค์ผ๋ก 10%, 90% ์ง์ ์ผ๋ก ์ด๋
50ํ๋ ์์ ๋ทฐ์ ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋ก ๋๋ฆฌ๊ณ , ํ์ ํ๋ ์ ๋๋ฉ์ด์
- 23. package com.mdlicht.zb.motionlayoutexample.ex06collapsingtoolbar
import android.content.Context
import android.support.constraint.motion.MotionLayout
import android.support.design.widget.AppBarLayout
import android.util.AttributeSet
class CollapsibleToolbar
@JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0)
: MotionLayout(context, attrs, defStyleAttr),
AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
progress = -verticalOffset / appBarLayout?.totalScrollRange?.toFloat()!!
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
(parent as? AppBarLayout)?.addOnOffsetChangedListener(this)
}
}
Ex06. Collapsing Toolbar
[ CollapsingToolbar.kt ]