Be simple

”当たり前”が誰かのためになる

Groupieことはじめ #3 { ExpandableItemを使ってみる }

はじめに

こんばんは!

 

最近、お部屋探し中の@zukkeyです!

そろそろ一人暮らしをしたいと思い、港区から中野あたりを探しているのですが高くて高くてどうしようかと。。

技術書展もあるのに悩みつつ探しております。。住みやすい場所などあったら教えていただけると嬉しいです。一人暮らしビギナーなのです。

 

今日は、前回に引き続きGroupieのExpandableItemを使っていこうという記事になります。

 

前回の記事はこちら↓

rozkey.hatenablog.com

 

今回作るのは下記のようなものになります!

f:id:rozkey59:20180317230909g:plain

 

タップすると開いて開かれてコンテンツが表示されて、閉じるときはコンテンツが非表示になるやつです。

それを今回は作っていく過程についてメモを残していきます。

 

まずはレイアウトを作る

今回はあらかじめDataBindingを使えることと、Groupieの導入も終わっている前提で書いています。

分からない場合は「はじめに」で紹介してある前回の記事を読んでください。

 

例によってres > layoutで右クリックをすることでNew > Layout resource fileから好きな名前を付けて新しく作成してください。

 

今回、僕は拡大縮小するのでitem_expandable_headerという名前を付けました。

まんまですね。

 

実際に作成したレイアウトは以下になります。

<?xml version="1.0" encoding="utf-8"?>
<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">

<RelativeLayout
android:id="@+id/item_expandable_header_root"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/item_expandable_header_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="2dp"
android:layout_marginTop="2dp"
android:textSize="24sp"
android:textColor="?attr/colorAccent"
android:textStyle="bold"
tools:text="Group 1" />

<ImageView
android:id="@+id/item_expandable_header_icon"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginLeft="4dp"
android:layout_toEndOf="@+id/item_expandable_header_title"
android:tint="@color/colorAccent"
app:srcCompat="@drawable/ic_keyboard_arrow_up_black_24dp" />

</RelativeLayout>
</layout>

 

Previewで見ると下記のような感じです

f:id:rozkey59:20180317231749p:plain

 

TextViewとその右隣にImageViewを用意したHeaderを作ります。

ImageVIewで用意している画像は、res > drawable で右クリックをした後にNew > Vector Asset から追加していきます。

 

以下のような画面でandroidのアイコンをクリックしてください。

f:id:rozkey59:20180317232049p:plain

 

androidアイコンをクリックすると次のような画面が出てきます。

 

f:id:rozkey59:20180317232124p:plain

今回は下矢印のようなアイコンがほしいので検索部分でarrowと検索することで出てきます。

AndroidStudioにはデフォルトで用意されているアイコンがあるので特段こだわりが無ければ今の流れで新しく追加していくのがいいと思います。

 

これで取り合えず、レイアウトファイル自体は完成しました。

 

次にExpandableItemを継承したItemクラスを作成する

Groupieに用意されているExpandableItemを継承した新しいクラスを作成します。

継承が分からない人は、以下の書籍を参考にするとよいです。

 

僕が大学一年の時に読んでいた本で、Javaですが分かりやすく書かれています。

 

 

Java入門

 多分、多くの情報系の学生は読んでいるやつだと思います。

 

 

 で、もどりますがExpandableItemを継承したクラスを作成します。

実際に作成したクラスは以下になります。

 

class ExpandableHeaderItem(private val title: String) : Item(), ExpandableItem {

private lateinit var expandableGroup: ExpandableGroup

override fun bind(viewHolder: ViewHolder, position: Int) {
viewHolder.item_expandable_header_title.text = title
viewHolder.item_expandable_header_icon.setImageResource(getRotatedIconResId())
viewHolder.item_expandable_header_root.setOnClickListener {
expandableGroup.onToggleExpanded()
viewHolder.item_expandable_header_icon.setImageResource(getRotatedIconResId())
}
}

override fun getLayout(): Int = R.layout.item_expandable_header

override fun setExpandableGroup(onToggleListener: ExpandableGroup) {
expandableGroup = onToggleListener
}

private fun getRotatedIconResId() =
if (expandableGroup.isExpanded)
R.drawable.ic_keyboard_arrow_up_black_24dp
else
R.drawable.ic_keyboard_arrow_down_black_24dp
}

 

getLayoutで先ほど作成したヘッダーのレイアウトファイルを指定しています。

getRotatedIconResIdでは拡大したときと縮小したときで表示するアイコンの画像を指定しています。

さきほどの例によって好きなアイコンを追加して表示してください。さっきと同じ手順で自分は上矢印のようなアイコンを拡大したときは表示するようにしています。

 

ExpandableGroupのなかにonToggleExpandedという関数がすでにあり、これをクリックリスナーの中で呼び出すことで拡大と縮小に合わせてコンテンツの表示非表示が行えます。

 

onToggleExpandedの中の関数を見てみると以下のようになっています

public void onToggleExpanded() {
int oldSize = getItemCount();
isExpanded = !isExpanded;
int newSize = getItemCount();
if (oldSize > newSize) {
notifyItemRangeRemoved(newSize, oldSize - newSize);
} else {
notifyItemRangeInserted(oldSize, newSize - oldSize);
}
}

adapterのnotify系のメソッドではadapterの中身のデータの更新があったときに呼び出す関数なのですが、このメソッドでは拡大する前のサイズと後のサイズで比較してコンテンツを削除および挿入を行っているようです。

 

今回はアイコンの挙動も拡大縮小に合わせて変更したいので先ほど作成したgetRotatedIconResId関数で画像のセットもクリックリスナーの中で行っています。

 

これによって拡大縮小の動作を実現できるExpandableHeaderItemクラスを作成することができました!

 

Itemが作成出来たらGroupに追加してみよう

前回に引き続いて追加していきましょう!

 

MainActivityの中で下記のようにコードを追加します

 

ExpandableGroup(ExpandableHeaderItem("Expandable Group"), true).apply {
add(Section(cardItem))
groupAdapter.add(this)
}

たったこれだけで追加できます。

ExpandableHeaderItemではヘッダーの名前を設定できるように引数を持たせていたので任意の文字を設定してapplyの中で、ExpandableGroupの中にaddしてください。

 

さらに、大本のrecyclerviewのアダプターであるgroupAdapterに追加しましょう。

これでようやく最初に見せた挙動を行うサンプルが作成できます!

 

さいごに 

今回は、サンプルの中でも紹介されているExpandableなヘッダーを持ったitemの作成方法の紹介でした。

次はカルーセル表示なども紹介していきます。

技術書展の準備や普段の仕事もあってなかなか時間が取れず更新ができてなくて申し訳なかったです。

 

最後まで見ていただいてありがとうございました!!

遅れてしまわぬように引き続き三日に一回ぐらいのペースでやっていこうと思います。

 

ちなみに、今回作成したサンプルは以下のリポジトリで公開しています。

良かったらクローンしてビルドして試してみてくださいー

GitHub - yutaro6547/GroupieSampleOfMaster: learning Groupie sample