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)
}
}
}
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을 확인해보자.
<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
애뮬레이터로 실험해봐도 차이가 전혀없다; 나중에 더 찾아보려한다.
<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>
contentScrim
과 statusBarScrim
은 특정 위치까지 스크롤 됐을 때 표시되는 색상 및 이미지이다.
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를 구현하여 연동해 화면을 띄워보도록 하겠다.