文系プログラマの勉強ノート

スマホアプリ開発やデザインなどについて勉強したことをまとめています

【Android】SwipeRefreshLayoutの中に入れたListViewのEmptyViewが表示されない

次のようなLayoutを作り、コード上でEmptyViewを設定します。
(例:(ListView) findViewById(R.id.listView).setEmptyView(findViewById(R.id.emptyView))
すると、ListViewに項目がない場合もemptyViewは表示されません。

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <LinearLayout
        android:id="@+id/emptyView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/empty_view_text"/>
    </LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>

これを下記のように修正すると表示されるようになります。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </android.support.v4.widget.SwipeRefreshLayout>

    <LinearLayout
        android:id="@+id/emptyView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/empty_view_text"/>
    </LinearLayout>
</RelativeLayout>

ただ、今度はEmptyView表示中に下にひっぱったときのインジケータが表示されません。
これは、EmptyViewを使用していると
項目の有無によってListViewのVisibilityが自動で変わる影響だそうです。

そこで次のようなカスタムListViewクラスを作成し、Layoutを修正します。

package com.example;

import ...(省略)

public class ForSwipeRefreshListView extends ListView {
    public ForSwipeRefreshListView(Context context) {
        super(context);
    }

    public ForSwipeRefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ForSwipeRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setVisibility(int visibility) {
        if (visibility != View.GONE || getCount() != 0) {
            // EmptyView非表示時のみVisibilityの変更を有効にする
            super.setVisibility(visibility);
        }
    }
}
// ListView部分のみ抜粋
<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.ForSwipeRefreshListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</android.support.v4.widget.SwipeRefreshLayout>

これでRefreshインジケータも表示されるようになったと思います。

下記の記事を参考にさせていただきました。
increment.hatenablog.com