Android Kotlin基礎講座 08.3:フィルタリングとインターネットデータの詳細ビュー
目次
タスク:”販売用”の画像を概要ページに追加する
今まで火星物件データのうち、使っていたのは物件画像のURLだけでした。しかし、MarsPropertyクラスに定義した物件データには、ID、価格、タイプ(rent / buy)というデータも含まれています。思い出すために、ウェブサービスから取得したJSONデータの一部を載せておきます。
{
"price":8000000,
"id":"424908",
"type":"rent",
"img_src": "http://mars.jpl.nasa.gov/msl-raw-images/msss/01000/mcam/1000ML0044631290305226E03_DXXX.jpg"
},
このタスクでは、ドルアイコンの画像を概要ページの販売用の物件に対して追加するために、物件のタイプから作業していきます。
ステップ1:MarsPropertyにタイプを含ませるようにアップデートする
marsPropertyクラスはウェブサービスから提供されたそれぞれの物件用のデータ構造を定義しています。以前の記事では、Moshiライブラリを使ってMarsウェブサービスからの生のJSONデータを、個々のMarsPropertyデータオブジェクトにパースしました。
このステップでは、MarsPropertyクラスにいくつかのロジックを追加し、物件が貸し出し用なのか、販売用なのかがわかるようにします。(タイプが”rent”か”buy”かを判断させる)
このロジックは他の場所でも使うことになるので、都度複製するよりも、ここでデータクラスに作成するほうがふさわしいでしょう。
- 前回の記事で作成したMarsRealEstateアプリを開いてください。(アプリを持っていない場合は、MarsRealEstateGridをダウンロードしてください)
- network/MarsProperty.ktを開いてください。MarsPropertyクラス定義にボディを追加し、オブジェクトのタイプが”rent”の場合はtrueを返すisRental用のカスタムゲッターを追加してください。
data class MarsProperty(
val id: String,
@Json(name = "img_src") val imgSrcUrl: String,
val type: String,
val price: Double) {
val isRental
get() = type == "rent"
}
ステップ2:グリッドアイテムレイアウトをアップデートする
販売用の物件画像の上にだけドルアイコンを表示するために、画像のグリッドのアイテムレイアウトをアップデートしていきます。
データバインディング式を使うことで、貸し出し用か販売用かを調べるテスト全体をグリッドアイテムのXMLレイアウト内で行うことができます。
- res/layout/grid_view_item.xmlを開いてください。これはRecyclerView用のグリッドレイアウト内の個々のセルを表すためのレイアウトファイルです。現在ファイルには物件画像用の<ImageView>要素のみが含まれています。
- <data>要素の中に、Viewクラス用の<import>要素を追加してください。インポートはレイアウトファイルでデータバインディング式中でクラスのコンポーネントを使いたいときに使用します。今回の場合は、View.GONE、View.VISIBLE定数を使う予定なので、Viewクラスにアクセスする必要があります。
<import type="android.view.View"/>
- ドルアイコンを物件画像の上に重ねて表示できるようにするために、ImageView全体をFragmeLayoutで囲んでください。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="170dp">
<ImageView
android:id="@+id/mars_image"
...
</FrameLayout>
- ImageViewのandroid:layout_height属性をmatch_parentに変更して、新しい親要素であるFrameLayoutを満たすようにしてください。
android:layout_height="match_parent"
- FrameLayout内に、二つ目の<ImageView>要素を最初の<ImageView>のすぐ下に追加してください。以下の定義を使ってください。この画像はグリッドアイテムの右下に表示されます。またドルアイコン用にres/drawable/ic_for_sale_outline.xmlに定義された画像を使っています。
<ImageView
android:id="@+id/mars_property_type"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_gravity="bottom|end"
android:adjustViewBounds="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_for_sale_outline"
tools:src="@drawable/ic_for_sale_outline"/>
- mars_property_typeイメージビューにandroid:visibility属性を追加してください。バインディング式を使って物件のタイプをテストし、貸し出し用の場合にはView.GONEを、販売用の場合にはView.VISIBLEを代入してください。
android:visibility="@{property.rental ? View.GONE : View.VISIBLE}"
ここまでは<data>要素に定義された個々の変数を使ったバインディング式のみを見てきました。バインディング式は非常に便利で、完全にXMLレイアウト内のみでテストや数値計算といった操作を行うことができます。今回の場合は、三項演算子(?:)を使ってテスト(このオブジェクトが貸し出し用かどうか)を行っています。tureの場合の結果(View.GONEでドルアイコンを非表示にする)とfalseの場合の結果(View.VISIBLEでアイコンを表示する)をそれぞれ代入させています。
新しいgrid_view_item.xmlは以下のようになります。
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<variable
name="property"
type="com.example.android.marsrealestate.network.MarsProperty" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="170dp">
<ImageView
android:id="@+id/mars_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:padding="2dp"
app:imageUrl="@{property.imgSrcUrl}"
tools:src="@tools:sample/backgrounds/scenic"/>
<ImageView
android:id="@+id/mars_property_type"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_gravity="bottom|end"
android:adjustViewBounds="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_for_sale_outline"
android:visibility="@{property.rental ? View.GONE : View.VISIBLE}"
tools:src="@drawable/ic_for_sale_outline"/>
</FrameLayout>
</layout>
- コンパイルしてアプリを起動してください。貸し出し用でない物件の上にはドルアイコンが表示されていることを確認してください。