Gaiax Advent Calendar 6日目のエントリーです。1枠余っているということで急遽書くことになったので小ネタで失礼します。
はじめに
AndroidではPull to RefreshのUIを実現するために、SwipeRefreshLayoutというViewコンポーネントが準備されています。
基本的な使い方については、こちらの記事が参考になります。
SwipeRefreshLayout覚え書き
SwipeRefreshLayoutはシンプルな機能ですが、配置によっては不可解な動きをするので、2点ほど注意点を紹介したいと思います。
1. SwipeRefreshLayoutの子要素を1つにする
以下のように SwipeRefreshLayout に複数の要素を入れた場合、2つめ以降の要素は表示されなくなります。
特にエラーも表示されないので、注意が必要です。
<SwipeRefreshLayout>
<RecyclerView></RecyclerView>
<TextView/> <--- 表示されない
</SwipeRefreshLayout>
そこで、LinearLayoutで囲って、SwipeRefreshLayoutの子要素が1つになるようにしてみます。
<SwipeRefreshLayout>
<LinearLayout>
<RecyclerView></RecyclerView>
<TextView/>
</LinearLayout>
</SwipeRefreshLayout>
一見これで動作するのですが、実は問題が発生します。リストをスクロールダウンして、元に戻るためにスクロールアップした時に誤ってリフレッシュされてしまいます。
2. スクロールするViewは極力SwipeRefreshLayoutの子要素にする
この問題が発生しないようにするためには、RecyclerViewをSwipeRefreshLayoutの直接の子要素になるように配置して、入れ子を組み替えます。
<LinearLayout>
<SwipeRefreshLayout>
<RecyclerView></RecyclerView>
</SwipeRefreshLayout>
<TextView/>
</LinearLayout>
こうすることで、スクロールアップしても最上部までいかないとリフレッシュされません。RecyclerViewがListViewやScrollViewの場合も同様です。
SwipeRefreshLayoutのサンプルではSwipeRefreshLayoutがルート要素にされていることが多いですが、確認した範囲ではSwipeRefreshLayoutに親要素があっても、兄弟要素があっても問題なく動作していました。
どうしてもレイアウトの要件上入れ子の組み換えで対応できない場合は、canChildScrollUpをオーバーライドして対応しましょう。
SwipeRefreshLayout を上方向にスクロールできない