12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Android】RecyclerViewでEmptyViewをCustomViewで実装した時の思い出【Kotlin】

Last updated at Posted at 2017-06-01

RecyclerViewにはListViewなどと異なりsetEmptyViewが用意されていないため、自分で実装する必要がある。
使うたびにActivityなどでgetItemCountを取得して切り替えてもいいんだけど
めんどくさいじゃん!何回も使うようならどこかで絶対忘れるじゃん!
という理由でCustomViewを作ることにしました。

紆余曲折の軌跡をここに記す・・・

最終的に書いたコード

RecyclerViewを継承したCustomViewの作成

SupportEmptyRecyclerView.kt
class SupportEmptyRecyclerView : RecyclerView {
 @JvmOverloads public constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
  : super(context, attrs, defStyleAttr) {
}
  var emptyView: View? = null

  private val emptyObserver = object : RecyclerView.AdapterDataObserver() {

    override fun onChanged() {
      if (adapter != null && emptyView != null) {
         val isEmpty = adapter.itemCount == 0
          emptyView!!.visibility = if (isEmpty) View.VISIBLE else View.GONE
          visibility = if (isEmpty) View.GONE else View.VISIBLE
      }
    }
  }

  override fun setAdapter(adapter: RecyclerView.Adapter<*>?) {
    super.setAdapter(adapter)

    adapter?.registerAdapterDataObserver(emptyObserver)
    emptyObserver.onChanged()
  }
}

RecyclerViewの状態が変わった時に描画を変更するよう、Observerを登録。
このへんのstackoverflow参考にした。
RecyclerViewの要素数に応じて表示を切り替える。
visibilityかよ〜と思ったけどListViewに生えてるsetEmptyViewの内部実装もそうらしい。
setAdapterをoverrideしているので、ActivityやFragmentでsetAdapterをするだけで設定される。

emptyView用のXMLの作成

view_empty.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    >
  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:gravity="center"
      android:orientation="vertical"
      >
    <ImageView
        android:id="@+id/empty_image"
        android:layout_width="@dimen/empty_image_size"
        android:layout_height="@dimen/empty_image_size"
        android:layout_gravity="center"
        android:layout_margin="@dimen/spacing"
        android:src="@drawable/no_item"
        />

    <TextView
        android:id="@+id/empty_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="表示する内容がありません"
        android:textColor="@color/black_alpha_54"
        android:textSize="@dimen/text_large"
        />
  </LinearLayout>
</layout>

RecyclerViewを乗せたいレイアウトファイルに追加する

sample_fragment.xml

〜略〜

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
      <me.rm_rf.view.widget.SupportEmptyRecyclerView
          android:id="@+id/recycler_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:padding="@dimen/spacing_xsmall"
          />
      <include
          layout="@layout/view_empty"
          android:id="@+id/included_empty_view"
          />
    </RelativeLayout>

ここでポイントなのはEmptyViewをRecyclerViewと同じファイルに書くこと。
RecylerViewとEmptyViewをRelativeLayoutで括ること。
同じ階層に置いていないと、RecyclerViewの範囲内でEmptyViewを
android:gravity="center"
したいのに効かなかったり、なんかうまいこと表示されなかったりする。

setAdaptersするだけでitem=0のときにEmptyViewが表示されるの便利だな〜

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?