일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 주택가 잠실새내
- 주엽역 생활맥주
- 막내의막무가내 플러터
- 막내의막무가내 코틀린 안드로이드
- 막내의 막무가내
- 막내의막무가내 알고리즘
- 막내의막무가내 플러터 flutter
- 막내의막무가내
- 막내의막무가내 코틀린
- 막내의막무가내 프로그래밍
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 안드로이드 에러 해결
- 막내의 막무가내 알고리즘
- 안드로이드
- 프로그래머스 알고리즘
- 막내의막무가내 목표 및 회고
- flutter network call
- 막무가내
- 2022년 6월 일상
- 안드로이드 Sunflower 스터디
- 막내의막무가내 SQL
- 막내의막무가내 안드로이드 코틀린
- 막내의막무가내 rxjava
- 부스트코스
- 막내의막무가내 안드로이드
- 안드로이드 sunflower
- 부스트코스에이스
- 막내의막무가내 일상
- 프래그먼트
- Fragment
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] 안드로이드 Collapsing Toolbar Layout with Constraint Layout, NestedScroll 구현 본문
[안드로이드] 안드로이드 Collapsing Toolbar Layout with Constraint Layout, NestedScroll 구현
막무가내막내 2020. 8. 2. 03:42
[2021-04-14 업데이트]
Collapsing Toolbar Layout 를 적용하기전에 샘플로 구현해보았습니다.
CoordinatorLayout
-AppBarLayout
[이 레이아웃의 바로 밑 계층은 일반적인 레이아웃이랑 비슷하다. CollapsingToolbarLayout 을 위해 사용]
--CollapsingToolbarLayout
[접히는(스크롤에) 모션에 반응하여 나타나거나 사라질 레이아웃]
---ImageView, Toolbar
[접히는(스크롤에) 모션에도 계속 남아 있을 툴바, 즉 CollapsingToolbarLayout 안에서 Toolbar안에 있는 것은 접혀도 뷰를 보존시킴]
-NestedScrollView
--ConstraintLayout
[일반적인 레이아웃]
-FloatingActionButton
구조입니다. constraint 로 되어있는 예제는 안보여서 다른 종류의 예제들을 참고하여 만들었습니다. 구현 코드와 함께 원리도 간략하게 살펴보겠습니다 ㅎㅎ
[Activity] 툴바 세팅
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById<View>(R.id.toolbar) as Toolbar
toolbar.title = "HELLO EXAMPLE"
setSupportActionBar(toolbar)
if (supportActionBar != null) supportActionBar!!.setDisplayHomeAsUpEnabled(false) //툴바에 백키(<-) 보이게할거면 이거 사용
[XML]
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="350dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleTextAppearance="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.AppCompatImageView
app:layout_collapseMode="parallax"
android:src="@drawable/example"
android:contentDescription="@string/hello_example"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="350dp" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/hello_example2"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:animateLayoutChanges="true"
android:layout_marginBottom="?attr/actionBarSize">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginTop="16dp"
android:text="HELLO!!"
android:textColor="#000000"
android:textSize="70dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_hello2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginTop="16dp"
android:text="HELLO2!!"
android:textColor="#000000"
android:textSize="70dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_hello" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_hello3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginTop="16dp"
android:text="HELLO3!!"
android:textColor="#000000"
android:textSize="70dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_hello2" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_hello4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginTop="16dp"
android:text="HELLO4!!"
android:textColor="#000000"
android:textSize="70dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_hello3" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_hello5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginTop="16dp"
android:text="HELLO45!!"
android:textColor="#000000"
android:textSize="70dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_hello4" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:src="@drawable/ic_add_black_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:elevation="6dp"
app:pressedTranslationZ="12dp"
app:layout_anchor="@id/app_bar_layout"
app:layout_anchorGravity="bottom|right|end"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="350dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleTextAppearance="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
에서 scollFalgs 에는 5가지 종류가 있습니다.
scroll, expandAlways, expandAlwaysCollapsed, snap, exitUntilCollapsed.
이 scollFalgs 를 사용해서 NestedScrollView에서 스크롤 상태라고 CollapsingToolbarLayout 에 알려줄 수 있습니다.
만약 NestedScrollView 가 스크롤업할 때 CollapsingToolbar 를 접혀서 사라지게하고 스크롤 다운할 때는 CollapsingToolbar를 펼칠 수 있습니다.
예를들어 scroll | enterAlwaysCollapsed 속성은 아래로 스크롤하는 동안 CollapsingToolbar가 확장되는 시간에 대해 lazy한 접근 방식을 사용합니다. 아래로 스크롤되는 순간, CollapsingToolbar는 NestedScrollView가 콘텐의 맨 위로 스크롤 된 후에만 확장됩니다. 즉 만약 엄청 긴 스크롤이 있고 맨아래까지 스크롤한 후 스크롤다운할 때 툴바위치(꼭대기겠죠) 까지 스크롤을 해야 그떄서야 툴바가 펴지기 시작한다는 뜻입니다.
이와 반대의 속성으로는 scroll|enterAlways 가 있겠습니다. 이거는 스크롤이 얼마나 아래에 있든 상관없이 스크롤 다운시 바로 CollapsingToolbar 펴지기 시작합니다.
저는 scroll|exitUntilCollapsed 속성을 사용하였는데 이 플래그가 툴바가 상단에 유지되고 스크롤시 사라지지 않도록하는 유일한 스크롤 플래그입니다. 이 플래그는 NestedScrollView가 해당 콘텐츠의 맨 위에 도달하면 CollapsingToolbar 만 확장하므로 enterAlwaysCollapsed 플래그와 유사하게 작동합니다.
그 밖의 다른 속성들에 대한 설명과 예시는 다음 사이트에 잘 나와있으니 참고하시면 됩니다. !!
https://medium.com/martinomburajr/android-design-collapsing-toolbar-scrollflags-e1d8a05dcb02
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
AppBarLayout 은 Theme 를 설정하여 툴바의 타이틀 색상 등을 바꿔줄 수 있습니다.
android:fitsSystemWindows 는 뷰가 차지할 수 있는 영역을 상태바 및 소프트키 영역을 제외한 영역까지 확장해주는 역할 수 있습니다. (출처: https://androidhuman.tistory.com/560 [커니의 안드로이드 이야기])
그래서 상태바까지 앱바 레이아웃의 이미지가 꽉 차게 만들려면 Toolbar 를 제외한 CoordinatorLayout - AppBarLayout - CollapsingToolbarLayout - ImageView 에 이 속성을 주면 된다고 합니다. (https://black-jin0427.tistory.com/16)
<androidx.appcompat.widget.AppCompatImageView
app:layout_collapseMode="parallax"
android:src="@drawable/example"
android:contentDescription="@string/hello_example"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="350dp" />
앱바레이아웃안에 이미지뷰를 넣었는데요 layout_collapseMode 속성은 스크롤 될때마다 parallax 효과가 적용된다고 합니다. 즉 스크롤 app:layout_collapseParallaxMultiplier (0.0~1.0) 와 조합해서 쓸 수 있으며 기본값은 0.5입니다.
(자세한 내용은 https://developer.android.com/reference/androidx/leanback/widget/Parallax참고해주세요)
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/hello_example2"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
layout_collapseMode = "pin" 의 경우 스크롤을 할때 Toolbar가 최상단까지 위로 올라가면서 가장 최상단에 올라간 경우 고정 시켜주는 역할을 합니다.
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
app:layout_behavior="@string/appbar_scrolling_view_behavior" 속성을 설정함으로써 NestedScrollView의 반응에 따라 AppBarLayout이 반응됩니다.
CoordinatorLayout는 NestedScrollView가 스크롤시 layout_behavior에 정의된 레이아웃으로 스크롤 정보를 전달 하는 역할을 합니다. 그럼 AppBarLayout의 ScrollingViewBehavior가 정보를 받아서 AppBarLayout 자신을 변형하도록 하는 구조입니다. (https://blog.kmshack.kr/CoordinatorLayout%EA%B3%BC-Behavior%EC%9D%98-%EA%B4%80%EA%B3%84/)
fillViewport 의 경우는 다음을 참고하면 됩니다. https://m.blog.naver.com/PostView.nhn?blogId=snowheeee&logNo=220958929516&proxyReferer=https:%2F%2Fwww.google.com%2F
https://jootc.com/p/201908173053
[P.S]
app:expandedTitleMarginStart
app:expandedTitleGravity
app:expandedTitleMarginBottom
app:expandedTitleTextAppearance
app:collapsedTitleTextAppearance
app:collapsedTitleGravity
등의 속성을 이용해서 툴바의 텍스트를 펼침, 접힘 상태의 모양을 구현해줄 수 있습니다.
Appearance에는 style로 모듈화해서 세팅하면됩니다. (Ex. testSize, testColor, fontFamily등)
그리고 뭐든 마찬가지지만 자주쓸 가능성이 있는 Collapsing Toolbar 는
AppBarLayout~CollapsingToolbarLayout~Toolbar로 모듈화해서
사용할 XML에 최상단 부모레이아웃을 CoordinatorLayout 로 한후 모듈화 한거를 <include> 해서 사용하면 좋습니다 :)
참고 : 예전에 했던거라 여러군데서 참고했는데 생각이 안나네요.
https://black-jin0427.tistory.com/16
추가 포스팅 자료
youngest-programming.tistory.com/380
댓글과 공감은 큰 힘이됩니다. 감사합니다!!
'안드로이드 > 코틀린 & 아키텍처 & Recent' 카테고리의 다른 글
[안드로이드] DI Dagger2 @Singleton vs @Resuable 차이점 정리 (0) | 2020.08.08 |
---|---|
[안드로이드] Lottie Animation 사용법 (0) | 2020.08.02 |
[안드로이드] Android Kotlin Convert timestamp to Date , Date to timestamp Test (코틀린 타임스탬프 날짜 변환 테스트) , Android DatePickerDialog disable past date (2) | 2020.07.31 |
[안드로이드] DI 대거(Dagger2) 공부자료 및 적용해보기 (Koin -> Dagger) (0) | 2020.07.19 |
[안드로이드] 안드로이드 BottomSheetDialog 콜백 구현 (10) | 2020.07.11 |