SwipeRefreshLayout
Support Library revision 19.1.0からSwipeRefreshLayoutという新しいViewGroupが追加された。
これはいままで引っ張って更新とかPullToRefreshとか呼ばれていた機能を実装できるものになる。
以後長々と書くが、公式サンプルのほうがわかりやすくてタメになるのでそっちを見たほうがいい。
実装
まず、Support Library revision 19.1.0が使える状態にしておく。
次に、利用したい画面のレイアウトファイルにSwipeRefreshLayout
を配置する。
この時、SwipeRefreshLayout
の直接の子はひとつだけになるようにする。
<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色も渡さないといけないので大変だ。
ちなみに渡さないとインジケータが真っ黒になる。
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()
によってプログレスインジケータの表示/非表示を切り替えることができる。
これにより、プログレスインジケータを表示するだけのレイアウトとして利用することもできるようだ。
便利な場面もあるかもしれない。