您的位置:首页 > 移动开发 > Android开发

Android关于小米相册悬浮标题栏、冻结标题栏的实现方式(嵌套型RecycleView)

2016-02-16 12:10 483 查看
本文原创自selfreeyuan,转载请注明出处:

http://blog.csdn.net/selfreeyuan/article/details/50674009

效果图如下:



网上完全查找不到关于冻结标题栏的实现方式,经过几天的摸索尝试,终于实现了这种效果;当然在过程中遇到了很多问题拖延了进度,关键是没有摸清思路。

本文的实现方式已经尽了本人最大的能力进行简化,并解决了快速滑动造成的错乱问题,具体思路如下:

1.设置一个顶层的FrameLayout,用于装载目标的标题栏TextView

2.设置两个锚点,分别是uperPoint(0,0)和lowerPoint(0,textView.getHeight())通过getChildViewUnder()方法来判断两个点的view变化(getChildViewUnder()方法的介绍在本人的另一篇文章 关于 RecycleView 的findChildViewUnder()方法

3.针对滚动方向来对每个事件进行判断,分别对标题栏TextView在顶层FrameLayout中进行移入移除的处理,就实现了标题栏冻结的效果

具体代码如下:

主视图的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yuanh.fronzentitle.MainActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/topRecycleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>


item项的布局文件:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:background="@color/colorPrimary"
android:textSize="20sp"
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="30dp" />
<com.example.yuanh.fronzentitle.MyRecycleView
//注意这个paddingTop一定要和上面的标题栏的高度一致,为的是留出空白区
android:paddingTop="30dp"
android:id="@+id/itemGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"/>
</FrameLayout>


MainActivity的关键代码部分:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDate();
final RecyclerView topView = (RecyclerView) findViewById(R.id.topRecycleView);
topView.setLayoutManager(new LinearLayoutManager(this));
topView.setAdapter(new TopAdapter(this));
//        选择在滚动事件中判断是否悬浮标题栏
topView.addOnScrollListener(new RecyclerView.OnScrollListener() {
FrameLayout topContainer = (FrameLayout) findViewById(R.id.topContainer);
int currentY;
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 60);
FrameLayout preView = null;

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
//                分别设置两个锚点
FrameLayout currentUpView = (FrameLayout) recyclerView.findChildViewUnder(0, 0);
FrameLayout currentLowView = (FrameLayout) recyclerView.findChildViewUnder(0, 60);
//                初始化preView
if (dy == 0) {
preView = currentUpView;
}

//                当下移到临街点的时候,标题栏从原view中移到topContainer中
if(currentLowView!=preView||dy>0){
TextView tv = (TextView)topContainer.getChildAt(0);
if (null!=tv) {
topContainer.removeView(tv);
params.gravity = Gravity.BOTTOM;
tv.setLayoutParams(params);
preView.addView(tv);
//                        将preView替换成现有的currentLowView
preView = currentLowView;
}
}
//                当上移到临界点时
if (currentUpView!=preView||dy<0){
//                    上标题栏置底
TextView upTv = (TextView)currentUpView.findViewById(R.id.item_text);
if (null!=upTv){
params.gravity = Gravity.BOTTOM;
upTv.setLayoutParams(params);
}

//                    下标题栏置顶
TextView lowTv = (TextView)topContainer.getChildAt(0);
if (null!=lowTv){
topContainer.removeView(lowTv);
params.gravity = Gravity.TOP;
lowTv.setLayoutParams(params);
preView.addView(lowTv);
}

//                    将preView替换成现有的currentUpView
preView = currentUpView;
}

//                只有一种情况会让标题栏上浮,就是两个锚点下的view相同的时候
if (currentUpView.equals(currentLowView)){
TextView tv = (TextView)currentLowView.findViewById(R.id.item_text);
if (null!=tv){
currentUpView.removeView(tv);
params.gravity = Gravity.TOP;
tv.setLayoutParams(params);
topContainer.addView(tv);
}
}
}
});
}


好了,现在基本实现了小米相册的冻结标题栏功能,要知道RecycleView的强大之处在于一个RecycleView就做出一个这样的相册,但实现悬浮标题栏可就不那么简单。接下来我会尝试解决该问题,如果解决出来之后会下下一篇共享方法。如果各位大神有更好的方法,请赐教,感谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息