本篇文章已經授權微信公共號guolin_blog(郭霖)獨家發佈
轉載請註明作者AndroidMsky和出處
http://blog.csdn.net/AndroidMsky/article/details/53784984
本文github:
https://github.com/AndroidMsky/linkScrollMsky
先看知乎的效果:
再看我們實現的效果:
網上也有很多嵌套滑動的例子,先說說我這個的優點。
1.頭部可以參與滑動
2.下面可以加viewpager
3.支持RecyclerView和ScrollView
4.基於Behavior可以獲取事實滾動距離可做更多聯動
5.不必重寫過多的滑動事件處理,幾乎只是玩xml
實現思路:
CoordinatorLayout做最上層佈局,上方伸縮處AppBarLayout,下面viewpager裏面放NestedScrollView。
觀察知乎主頁的效果:
1.下面多item處向上滑動首先伸縮上面的head頭部,頭部收縮後下面則進入滑動,
2.反之向下拉先回把多item出拉到最上方,之後伸展頭部。
3.下面多item處支持左右滑動。
4.頭像名字漸隱效果。
5.兩個title可以點擊(title是在head中而不是下面)
1。2
下面我們來各個擊破:
1和2其實最容易只要實現系統的CoordinatorLayout
自從谷歌推出CoordinatorLayout後嵌套滑動玩起就沒那麼難了,
12實現其實十分簡單就是系統自帶的CoordinatorLayout即可實現,不用書寫java代碼。結構如下
CoordinatorLayout—– AppBarLayout—–CollapsingToolbarLayout——Toolbar。
CoordinatorLayout—–viewPager。
父佈局CoordinatorLayout兩個節點AppBarLayout和viewPager
AppBarLayout中的節點ollapsingToolbarLayout它的節點又是Toolbar
如此佈局嵌套聯動伸縮toolsbar效果就實現了。下面是佈局嵌套結構的簡略代碼。
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:fitsSystemWindows="true">
<android.support.v4.view.ViewPager
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
</android.support.v4.view.ViewPager>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar">
<android.support.design.widget.CollapsingToolbarLayout
>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
3
接下來就是3下方的viewpager首先viewpager必須加上這行代碼,否則滑動事件不會分發給他,
app:layout_behavior="@string/appbar_scrolling_view_behavior"
另外注意viewpager的高度必須是match——parent否則也不會有聯動效果。
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
</android.support.v4.view.ViewPager>
4頭像名字漸隱效果。
頭像漸隱,我們需要在CoordinatorLayout中找到一個直接子view並且指定:
app:layout_behavior="com.example.liangmutian.linkscrollmsky.RelativelayoutBehavior"
接下來看RelativelayoutBehavior這個類本demo也就這個類中進行了一些簡單的座標處理,
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, RelativeLayout child, View dependency) {
float maxL = DensityUtil.dip2px(mContext, 150) + DensityUtil.getZhuangtai(mContext);
Message message = new Message();
if (dependency.getY() > 0) {
float a = ((dependency.getY() - maxL) / (DensityUtil.dip2px(mContext, 356) - maxL));
message.what = (int) (a * 100f);
if (MyActivity.mHandler != null)
MyActivity.mHandler.sendMessage(message);
}
return super.layoutDependsOn(parent, child, dependency);
}
RelativeLayout child就是剛剛的直接子view,View dependency就是產生滑動的view。通過view滑動距離的控制,我們就可以計算當前滑動幅度,從而實現頭像漸隱。356dp就是整個AppBarLayout的高度,150dp是Toolbar的高度。可被滑動的總距離就是,
AppBarLayout的高度-Toolbar的高度-狀態欄的高度。那可被滑動的總距離做分母,滑動距離做分子,也就計算出了滑動服務,用過Handler去更新Activity中的控件透明度,就可以了。
super.handleMessage(msg);
float alpha = ((float) msg.what) / 100f;
Log.e("alpha", msg.what + ":" + alpha);
overRe.setAlpha(alpha);
5.兩個title可以點擊(title是在head中而不是下面)
兩個title可點擊並跟隨頭部滑動,這裏有坑高危請注意。
我一開始,是直接寫到AppBarLayout裏,發現不錯,可以跟隨滑動,也能點,但是如果畫上去也就是完全縮進去的時候,就不能點了,原來我們只是把toolsbar設置成透明色,來實現實時透AppBarLayout中的視圖,當完全伸縮,Toolsbar就出現在前面了,後面的東西也就不能點了。
解決思路:
類似於懸停的解決思路吧,其實就在Toolsbar中也放置這樣一個佈局石頭,在頭部展開的時候收縮,在不展開的時候顯示,動態去控制兩個一樣的佈局的顯隱藏就ok了。
然後,挖槽還是有坑,如果把AppBarLayout中的佈局放在最底下,然後讓頭部完全縮進去,兩個佈局不能完全重疊,這樣在控制,顯示隱藏的時候就會有輕微的跳躍。於是機智如我,發現他們倆只是一個狀態的距離好吧一行代碼,拉近你我的距離:
RelativeLayout backRe;
backRe.setPadding(0, 0, 0, DensityUtil.getZhuangtai(this));
就這樣效果完全實現,只是在RelativelayoutBehavior中進行了一點的座標運算,其他地方基本不需要,比較容易上手。
感覺還有需優化的地方也希望大家多提意見。
本文github:
https://github.com/AndroidMsky/linkScrollMsky
歡迎關注作者。歡迎評論討論。歡迎拍磚。
如果覺得這篇文章對你有幫助,歡迎打賞, 歡迎star,Fork我的github。 喜歡作者的也可以Follow。
歡迎加作者自營安卓開發交流羣:308372687
參考了Chris Banes的內容,
https://github.com/chrisbanes