首先先看看仿制的效果先吸申,如下圖:
是不是很像支付寶的效果呢,我們今天就要通過講解android5.0新出的控件CoordinatorLayout享甸,AppBarLayout截碴,CollapsingToolbarLayout來實(shí)現(xiàn)這個(gè)效果。
在講解之前先看看界面布局文件蛉威,在一個(gè)一個(gè)講講怎么實(shí)現(xiàn)吧:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.jack.coordinatorlayouttest.ScrollingActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="@color/color1984D1"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:title=" ">
<include layout="@layout/shenghuo_head1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_marginBottom="25dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.8"/>
<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:contentInsetLeft="0dp" app:contentInsetStart="0dp"
app:layout_collapseMode="pin">
<include android:id="@+id/toolbar1"
layout="@layout/toolbar_head1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include android:id="@+id/toolbar2"
layout="@layout/toolbar_head2"
android:layout_width="match_parent"
android:layout_height="match_parent" android:visibility="gone"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include
layout="@layout/content_scrolling" />
</android.support.design.widget.CoordinatorLayout>
1.CoordinatorLayout
這就是整個(gè)高仿支付寶界面的核心布局界面的日丹,看看代碼量也不多吧,只要就是用了
CoordinatorLayout蚯嫌,AppBarLayout哲虾,CollapsingToolbarLayou丙躏,Toolbar這四個(gè)控件吧。
在各個(gè)布局文件里束凑,最外圍的是CoordinatorLayout這個(gè)控件晒旅,這個(gè)有什么作用呢,就我的大白話來說就是協(xié)調(diào)子View之間動(dòng)作的一個(gè)父View,通過Behavior來給子view實(shí)現(xiàn)交互的汪诉。這樣好像還是有點(diǎn)說不通废恋,沒關(guān)系同學(xué)們通過看上面的布局文件,可以發(fā)現(xiàn)
這一個(gè)內(nèi)容界面是的布局是
<include layout="@layout/content_scrolling" />
這一句的內(nèi)容是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:showIn="@layout/activity_scrolling"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
沒錯(cuò)就是一個(gè)linearLayout包裹著RecyclerView組成他的內(nèi)容界面扒寄,在這代碼里有這一句app:layout_behavior="@string/appbar_scrolling_view_behavior"
就是這句和CoordinatorLayout控件互動(dòng)實(shí)現(xiàn)滑動(dòng)鱼鼓,總結(jié)就是CoordinatorLayout控件和app:layout_behavior來進(jìn)行互動(dòng),進(jìn)而CoordinatorLayout的子控件和app:layout_behavior互動(dòng)该编。當(dāng)然@string/appbar_scrolling_view_behavior
是系統(tǒng)自帶的迄本,本質(zhì)是一個(gè)類,我們也可以自定義這個(gè)類實(shí)現(xiàn)其他效果上渴,不過這不是我們這一章所講的了岸梨,我們點(diǎn)到即止。
2.AppBarLayout
其次就是AppBarLayout稠氮,去除官方解釋曹阔,簡單來說就是它可以讓你定制當(dāng)某個(gè)可滾動(dòng)View的滾動(dòng)手勢發(fā)生變化時(shí),其內(nèi)部的子View實(shí)現(xiàn)何種動(dòng)作隔披。內(nèi)部的子View通過在布局中加app:layout_scrollFlags
設(shè)置執(zhí)行的動(dòng)作赃份。而layout_srcollFlags的動(dòng)作主要如下:
- scroll:值設(shè)為scroll的View會(huì)跟隨滾動(dòng)事件一起發(fā)生移動(dòng)。
- enterAlways:值設(shè)為enterAlways的View,當(dāng)ScrollView往下滾動(dòng)時(shí)奢米,該View會(huì)直接往下滾動(dòng)抓韩。而不用考慮ScrollView是否在滾動(dòng)。
- exitUntilCollapsed:值設(shè)為exitUntilCollapsed的View鬓长,當(dāng)這個(gè)View要往上逐漸“消逝”時(shí)谒拴,會(huì)一直往上滑動(dòng),直到剩下的的高度達(dá)到它的最小高度后涉波,再響應(yīng)ScrollView的內(nèi)部滑動(dòng)事件英上。
- enterAlwaysCollapsed:是enterAlways的附加選項(xiàng),一般跟enterAlways一起使用啤覆,它是指苍日,View在往下“出現(xiàn)”的時(shí)候,首先是enterAlways效果窗声,當(dāng)View的高度達(dá)到最小高度時(shí)相恃,View就暫時(shí)不去往下滾動(dòng),直到ScrollView滑動(dòng)到頂部不再滑動(dòng)時(shí)笨觅,View再繼續(xù)往下滑動(dòng)拦耐,直到滑到View的頂部結(jié)束耕腾。
這是layout_srcollFlags里可以設(shè)置的各個(gè)屬性的解釋,考慮文章的重點(diǎn)是模仿支付寶所以沒有篇幅和每個(gè)屬性都給個(gè)效果圖杀糯,所以各屬性你們有空還要自己試一試幽邓,這樣子才能掌握更好。我們這里AppBarLayout關(guān)聯(lián)的是CollapsingToolbarLayout火脉,設(shè)置的屬性是app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
里面的scroll讓
這可以滑動(dòng),而exitUntilCollapsed實(shí)現(xiàn)的效果是
3.CollapsingToolbarLayout
是用來對(duì)Toolbar進(jìn)行再次包裝的ViewGroup犯戏,主要是用于實(shí)現(xiàn)折疊的App Bar效果。CollapsingToolbarLayout只要有這方面:
1.title展開時(shí)是最大的拳话,然后隨著收縮會(huì)越來越少先匪,直到屏幕的頂部,通過app:title設(shè)置title,不然就默認(rèn)弃衍。
2.通過setContentScrim(Drawable)來設(shè)置達(dá)到某一個(gè)狀態(tài)之后的出現(xiàn)的效果3.通過setStatusBarScrim(Drawable)來設(shè)置達(dá)到某一個(gè)狀態(tài)之后的狀態(tài)欄出現(xiàn)的效果
4.當(dāng)app:layout_collapseMode設(shè)為parallax
子View可以選擇在當(dāng)前的布局當(dāng)時(shí)是否以“視差”的方式來跟隨滾動(dòng)
5.當(dāng)app:layout_collapseMode設(shè)為pin
Toolbar固定位置而不受移動(dòng)的影響
在我們實(shí)現(xiàn)這里呀非,我們把layout="@layout/shenghuo_head1"
即
設(shè)為
app:layout_collapseMode="parallax"
讓它以“視差”的方式來跟隨滾動(dòng),而toolbar設(shè)為app:layout_collapseMode="pin"
以讓他固定不動(dòng)镜盯。
4.Toolbar動(dòng)態(tài)變化
在此整體布局就已經(jīng)完成岸裙,不過還有一個(gè)效果就是向上移動(dòng)是toolbar的的View是動(dòng)態(tài)變化的,一開始我以為這些控件會(huì)有這個(gè)功能吧速缆,沒想到找了很久都沒找到降允,沒辦法只能自己實(shí)現(xiàn)了。二話不說上代碼:
private AppBarLayout mAppBarLayout=null;
private View mToolbar1=null;
private View mToolbar2=null;
private ImageView mZhangdan=null;
private TextView mZhangdan_txt=null;
private ImageView mTongxunlu=null;
private ImageView mJiahao=null;
private ImageView mZhangdan2=null;
private ImageView mShaoyishao=null;
private ImageView mSearch=null;
private ImageView mZhaoxiang=null;
private RecyclerView myRecyclerView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_scrolling);
myRecyclerView=(RecyclerView)findViewById(R.id.myRecyclerView);
myRecyclerView.setLayoutManager(new LinearLayoutManager(this));
myRecyclerView.setAdapter(new ToolbarAdapter(this));
mAppBarLayout=(AppBarLayout)findViewById(R.id.app_bar);
mToolbar1=(View)findViewById(R.id.toolbar1);
mToolbar2=(View)findViewById(R.id.toolbar2);
mZhangdan=(ImageView)findViewById(R.id.img_zhangdan);
mZhangdan_txt=(TextView)findViewById(R.id.img_zhangdan_txt);
mTongxunlu=(ImageView)findViewById(R.id.tongxunlu);
mJiahao=(ImageView)findViewById(R.id.jiahao);
mZhangdan2=(ImageView)findViewById(R.id.img_shaomiao);
mShaoyishao=(ImageView)findViewById(R.id.img_fukuang);
mSearch=(ImageView)findViewById(R.id.img_search);
mZhaoxiang=(ImageView)findViewById(R.id.img_zhaoxiang);
mAppBarLayout.addOnOffsetChangedListener(
new AppBarLayout.OnOffsetChangedListener() {
@Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (verticalOffset == 0){
//張開
mToolbar1.setVisibility(View.VISIBLE);
mToolbar2.setVisibility(View.GONE);
setToolbar1Alpha(255);
} else if (Math.abs(verticalOffset)>=appBarLayout.getTotalScrollRange()) {
//收縮
mToolbar1.setVisibility(View.GONE);
mToolbar2.setVisibility(View.VISIBLE);
setToolbar2Alpha(255);
} else {
int alpha=255-Math.abs(verticalOffset)-150;
if(alpha<=0){
//收縮
toolbar mToolbar1.setVisibility(View.GONE);
mToolbar2.setVisibility(View.VISIBLE);
setToolbar2Alpha(Math.abs(verticalOffset));
}else{
//張開
toolbar mToolbar1.setVisibility(View.VISIBLE);
mToolbar2.setVisibility(View.GONE); setToolbar1Alpha(alpha);
}
}
}
});
}
//設(shè)置展開時(shí)各控件的透明度
public void setToolbar1Alpha(int alpha){
mZhangdan.getDrawable().setAlpha(alpha);
mZhangdan_txt.setTextColor(Color.argb(alpha,255,255,255));
mTongxunlu.getDrawable().setAlpha(alpha);
mJiahao.getDrawable().setAlpha(alpha);
}
//設(shè)置閉合時(shí)各控件的透明度
public void setToolbar2Alpha(int alpha){
mZhangdan2.getDrawable().setAlpha(alpha);
mShaoyishao.getDrawable().setAlpha(alpha);
mSearch.getDrawable().setAlpha(alpha);
mZhaoxiang.getDrawable().setAlpha(alpha);
}
代碼還是有點(diǎn)多了不過最核心就設(shè)置AppBarLayout 的監(jiān)聽器addOnOffsetChangedListener來進(jìn)行效果的處理艺糜。當(dāng)verticalOffset=0的時(shí)候即使整個(gè)展開的是時(shí)候要做的就是顯示要顯示的剧董,隱藏要隱藏的設(shè)置,在設(shè)置透明度倦踢,同理當(dāng)verticalOffset等于appBarLayout.getTotalScrollRange()即等于最大值的時(shí)候送滞,就是關(guān)閉的時(shí)候,處理的展開相反辱挥。當(dāng)他在中間值的時(shí)候犁嗅,通過`int alpha=255-Math.abs(verticalOffset)-150;得到要設(shè)置的透明度,減去150是為了讓效果更明顯晤碘。當(dāng)alpha小于0的時(shí)候是執(zhí)行展開的toolbar的透明度效果褂微,反之大于0的時(shí)候是閉合時(shí)toolbar的透明圖效果功蜓。
剩下的看源碼吧
如果對(duì)你有幫助就請(qǐng)給我給星星或喜歡吧