Help us understand the problem. What is going on with this article?

SwipeRefreshLayout覚え書き

More than 5 years have passed since last update.

SwipeRefreshLayout

Support Library revision 19.1.0からSwipeRefreshLayoutという新しいViewGroupが追加された。
これはいままで引っ張って更新とかPullToRefreshとか呼ばれていた機能を実装できるものになる。
以後長々と書くが、公式サンプルのほうがわかりやすくてタメになるのでそっちを見たほうがいい。

実装

まず、Support Library revision 19.1.0が使える状態にしておく。

次に、利用したい画面のレイアウトファイルにSwipeRefreshLayoutを配置する。
この時、SwipeRefreshLayoutの直接の子はひとつだけになるようにする。

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

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

</android.support.v4.widget.SwipeRefreshLayout>

ソースコード側ではSwipeRefreshLayout.OnRefreshListenerの実装を行う。
このインターフェイスにはジェスチャ操作が発生したときに呼び出されるonRefresh()というメソッドしかない。
大半のアプリはここから通信などの非同期処理を呼び出すことになるはずだ。
また、ローディング中インジケータの色設定も画面側で行う。
SwipeRefreshLayout#setColorScheme()に4色も渡さないといけないので大変だ。
ちなみに渡さないとインジケータが真っ黒になる。

RefreshFragment.java
public class RefreshFragment extends Fragment implements 
        SwipeRefreshLayout.OnRefreshListener {

    private SwipeRefreshLayout mSwipeRefreshLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.refreshlayout, null);
        mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipelayout);

        // 色設定
        mSwipeRefreshLayout.setColorSchemeResources(R.color.red,
                R.color.green, R.color.blue,
                R.color.orange);
        // Listenerをセット
        mSwipeRefreshLayout.setOnRefreshListener(this);
        return view;
    }

    @Override
    public void onRefresh() {
        // 更新処理を実装する
        // ここでは単純に2秒後にインジケータ非表示
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // 更新が終了したらインジケータ非表示
                mSwipeRefreshLayout.setRefreshing(false);
            }
        }, 2000);
    }
}

追記:SwipeRefreshLayout.setOnRefreshListenerをしていないとプルダウン時にNullPointerExceptionが発生するので注意!

ListFragmentでは

ListFragmentの場合、レイアウトファイルを直接触りたくない。
そこで、onCreateViewの中でListViewの親レイアウトとしてコード内で挿入を行う。
しかもAndroidのバージョンによってcanChildScrollUpの処理を変えなくてはいけないため、SwipeRefreshLayoutも継承が必要…。
結構無理矢理感があるが、公式のサンプルでもそうなっているので、多分これでいいんだろう。

おまけ

SwipeRefreshLayout.setEnabled(false)でジェスチャと表示中のプログレスインジケータが無効化される。
ただし、無効化されたあとにSwipeRefreshLayout.setRefreshing()によってプログレスインジケータの表示/非表示を切り替えることができる。
これにより、プログレスインジケータを表示するだけのレイアウトとして利用することもできるようだ。
便利な場面もあるかもしれない。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away