上一次学习了通过RecyclerView实现列表的自动加载与刷新,本次学习RecyclerView怎样实现上拉时使分组的头部固定在页面顶部,具体效果看图:
实现思路
仔细观察就会发现这个效果就是FrameLayout的效果,一个FrameLayout里按顺序有列表,悬浮条两个View,悬浮条覆盖在列表的上方,当时机合适时更新自己的位置,使其看上去就是一个悬浮的效果。所以我们只需要确定什么时候让炫富条更新自己的位置就可以了,当第二个列表项的头部距离列表顶端一个悬浮条的距离时,悬浮条随着列表的滑动改变自身的位置,从而看起来像是一个分组标题悬浮的效果。也就是是在悬浮条恰好替换的时候,更新自己的数据,并移动到列表顶部。
实现代码
使用RecyclerView来实现列表,RecyclerView的列表布局是由LayoutManager来确定的,我们一般会使用LinearLayoutManager
布局:framelayout
<framelayout android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.recyclerview android:id="@+id/feed_list" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:scrollbars="vertical">
<your-head-layout>
……
</your-head-layout>
</android.support.v7.widget.recyclerview></framelayout>
通过LinearLayoutManager,我们可以很方便的获取到RecyclerView中相应位置的View,然后获取当前悬浮条数据来源的View和其下一个数据来源的View。悬浮条显示的信息是来自第一个可见View的,而其下方的View正是第二个列表项,我们可以获取到它的top值。我们只要给RecyclerView加一个ScrollListener,并在相应的回调里做之前我们想好的事就ok了
mFeedList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
mSuspensionHeight = mSuspensionBar.getHeight();
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
View view = linearLayoutManager.findViewByPosition(mCurrentPosition + 1);
if (view != null) {
if (view.getTop() <= mSuspensionHeight) {
mSuspensionBar.setY(-(mSuspensionHeight - view.getTop()));
} else {
mSuspensionBar.setY(0);
}
}
if (mCurrentPosition != linearLayoutManager.findFirstVisibleItemPosition()) {
mCurrentPosition = linearLayoutManager.findFirstVisibleItemPosition();
mSuspensionBar.setY(0);
updateSuspensionBar();
}
}
});