はじめに
リスト表示を行うTwitterクライアントのようなアプリでは、リストの一番上にスクロールする機能が必須ですよね。
今回はTwitterの公式Androidアプリで採用されている以下のような方法のスクロールを実装してみます。
- 選択済みTabをタップしたタイミングでリストの一番上までスクロールさせる
- 現在位置からリストの一番上までどれだけ離れているかで、一瞬で移動するのかスムーズに移動するのかを変える
この記事では以下の構成前提でコードを記載しています。
- MainActivityにTabLayoutとViewPagerを配置してタブ切り替える
- タブ選択で、RecyclerViewをメンバで持つFragmentを切り換える
選択済みのTabがタップされたことを検知する
選択済みTabを再選択した際の処理は、OnTabSelectedListenerのonTabReselectedで実装して
TabLayoutに設定してあげればOKです。
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
(省略)
mTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
// 選択済みTabが再選択された際の処理はここに記載
// リストを一番上にスクロールする処理を呼び出す
Fragment fragment = mPagerAdapter.getItem(tab.getPosition());
((TestFragment) fragment).scrollToFirstPosition();
}
});
(省略)
}
##リスト最上段までスクロールする
RecyclerViewの表示位置取得には、RecyclerViewにセットしているLayoutManagerを使うのがコツです。
現在の表示位置が一定の閾値を超えているか判定し、閾値より離れている場合は一瞬でいちばん上まで移動させ、
そこまで離れていない場合はスムーズに一番上までスクロールさせます。
TestFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
(省略)
mLinearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
(省略)
}
public void scrollToFirstPosition() {
if (mRecyclerView != null) {
// 表示されているポジションが閾値(ここでは20)より後ろであれば一瞬でスクロール。閾値以下ならスムーズスクロール
int position = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
if (position > 20) {
mRecyclerView.scrollToPosition(0);
return;
}
mRecyclerView.smoothScrollToPosition(0);
}
}
以上でTwitter公式アプリ風のリストスクロールが実装できます。
ぜひご自分のアプリに取り入れてみてくださいね。