[Android] Sunflower 클론코딩 (22.07.10)

유재민·2022년 7월 10일
0

Sunflower

목록 보기
12/12
post-thumbnail

Filter

PlantListFragment에서 필터기능을 추가해보자.
사실 어떤 부분을 필터하는지는 정확하게 파악을 못했는데,
일단 구현을 해보자.

먼저 툴바에서 사용 할 메뉴를 만들어준다.

<!-- menu_plant_list.xml -->
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/filter_zone"
        android:icon="@drawable/ic_filter_list_24dp"
        app:showAsAction="always"
        android:title="@string/menu_filter_by_grow_zone"/>

</menu>

Fragment에서 메뉴 사용 시 추가해야 될 함수를 선언해준다.

// in onCreateView
setHasOptionsMenu(true)

다음으로 PlantListFragment 에서 메뉴를 정의해준다.

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.menu_plant_list, menu)
}

메뉴 클릭 시 ListData를 Update한다.

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.filter_zone -> {
            updateData()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

정확하게 어떤 역할을 수행하는지 모르겠다.

private fun updateData() {
    with(viewModel) {
        if (isFiltered()) {
            clearGrowZoneNumber()
        } else {
            setGrowZoneNumber(9)
        }
    }
}

PlantDetailFragment

Plant List 아이템 클릭 시 상세 페이지로 이동하는 화면을 구성해보자.

<!-- fragment_plant_detail.xml -->
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="com.jaemin.sunflower_clone.data.Plant" />
        <variable
            name="viewModel"
            type="com.jaemin.sunflower_clone.viewmodels.PlantDetailViewModel" />
        <variable
            name="callback"
            type="com.jaemin.sunflower_clone.PlantDetailFragment.Callback" />
    </data>
  
  	...

</layout>

먼저 data를 정의해준다.
여기서 callback 변수는 Callback interface에 매핑된다.

// PlantDetailFragment.kt

fun interface Callback {
    fun add(plant: Plant?)
}

최상위 레이아웃으로는 CoordinatorLayout으로 선언해준다.
그 다음 AppBarLayout을 확인해보자.

AppBaraLayout

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/plant_detail_app_bar_height"
    android:fitsSystemWindows="true"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:stateListAnimator="@animator/show_toolbar"
    android:background="?attr/colorSurface"
    android:animateLayoutChanges="true">

    ...

</com.google.android.material.appbar.AppBarLayout>

stateListAnimator 을 지정하여 애니메이션을 추가한다.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_activated="true">

        <objectAnimator
            android:propertyName="translationZ"
            android:valueTo="@dimen/toolbar_elevation"
            android:valueType="floatType" />

    </item>

    <item android:state_activated="false">

        <objectAnimator
            android:propertyName="translationZ"
            android:valueTo="0dp"
            android:valueType="floatType" />

    </item>

</selector>

활성화 됐을 때와 안됐을때를 나눠 애니메이션을 지정해준다.
어떤 애니메이션인지 겉보기엔 큰 차이가 없어서 찾아봤다.

StateListAnimatorMaterial 은 raising up event 에도 feedback 을 줄 수 있다. ( 마치 자석처럼 )이것은 translationZ attribute 를 animating 함으로 할 수 있다. Z = elevation + translationZ.새로운 stateListAnimator 는 touch 에 따라 translationZ 를 animate 할 수 있게 도와준다.
출처: [Android] Material Design

애뮬레이터로 실험해봐도 차이가 전혀없다; 나중에 더 찾아보려한다.

CollapsingToolbarLayout

<com.google.android.material.appbar.CollapsingToolbarLayout
    android:id="@+id/toolbar_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    app:contentScrim="?attr/colorSurface"
    app:statusBarScrim="?attr/colorSurface"
    app:collapsedTitleGravity="center"
    app:collapsedTitleTextAppearance="@style/TextAppearance.Sunflower.Toolbar.Text"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:title="@{viewModel.plant.name}"
    app:titleEnabled="false"
    app:toolbarId="@id/toolbar">

	...

</com.google.android.material.appbar.CollapsingToolbarLayout>

contentScrimstatusBarScrim 은 특정 위치까지 스크롤 됐을 때 표시되는 색상 및 이미지이다.

contentScrim : 특정 위치까지 스크롤 됐을 때 툴바 색상 및 이미지가 변함
statusBarScrim : 특정 위치까지 스크롤 됐을 때 상태바 색상이 변함

app:layout_scrollFlags="scroll|exitUntilCollapsed"
scroll 속성은 스크롤하면 이 뷰가 사라질 수 있는 속성이고, exitUntilCollapsed는 아래로 스크롤하면 툴바만 남기게 되고, 위쪽으로 스크롤 하면 다시 CollapsingToolbarLayout이 보이게 된다. (툴바가 남게 되면서 title 또한 보이게 된다.)


이제 안에 ImageView 와 Toolbar를 넣어주도록 하겠다.

<ImageView
    android:layout_width="match_parent"
    android:layout_height="@dimen/plant_detail_app_bar_height"
    android:contentDescription="@string/plant_detail_image_content_description"
    android:fitsSystemWindows="true"
    android:scaleType="centerCrop"
    app:imageFromUrl="@{viewModel.plant.imageUrl}"
    app:layout_collapseMode="parallax" />

<com.google.android.material.appbar.MaterialToolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@android:color/transparent"
    app:titleTextColor="?attr/colorOnSurface"
    app:layout_collapseMode="pin"
    app:contentInsetStartWithNavigation="0dp"
    app:navigationIcon="@drawable/ic_detail_back"
    app:menu="@menu/menu_plant_list" />

layout_collapseMode
parallax : 스크롤 시 점점 작아지게 된다.
pin : 스크롤 시 최상단에 고정된다.

app:contentInsetStartWithNavigation="0dp" : 왼쪽에 여백이 없도록 한다.


다음에는 밑에 해당 식물의 설명이 들어가는 부분은 추후에 구현하고, 먼저 viewModel과 Repository를 구현하여 연동해 화면을 띄워보도록 하겠다.

profile
유잼코딩

0개의 댓글