上次簡(jiǎn)單的說(shuō)了一下CoordinatorLayout的基本用法(android特性之CoordinatorLayout用法探析實(shí)例)。其中CoordinatorLayout給我們提供了一種新的事件的處理方式,Behavior。還記得那一串字符串嗎?
成都創(chuàng)新互聯(lián)主要從事成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)莒南,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):18980820575
app:layout_behavior="@string/appbar_scrolling_view_behavior"
其實(shí)它并不是一個(gè)字符串資源,而它代表的是一個(gè)類(lèi),就是一個(gè)Behavior,這玩意其實(shí)還可以自定義的。
首先,來(lái)讓我見(jiàn)識(shí)一下它的真面目:
public static abstract class Behavior<V extends View> { ... }
Behavior是CoordinatorLayout的一個(gè)內(nèi)部泛型抽象類(lèi)。內(nèi)部類(lèi)中指定的view類(lèi)型規(guī)定了哪種類(lèi)型的view的可以使用才Behavior。因此,如果沒(méi)有特殊需求,直接指定view為View就行了。
1.某個(gè)view需要根據(jù)監(jiān)聽(tīng)另一個(gè)的行為來(lái)控制自己的行為,這個(gè)時(shí)候我們需要重寫(xiě)2個(gè)方法:
public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) { return false; }
public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) { return false; }
2.我們的view需要根據(jù)監(jiān)聽(tīng)CoordinatorLayout中的子view的滾動(dòng)行為來(lái)改變自己的狀態(tài),現(xiàn)在我們就需要重寫(xiě)下面的方法了:
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) { return false; }
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) { // Do nothing }
下面我們先來(lái)看一下情況1,讓一個(gè)view跟隨另一個(gè)view的行為而實(shí)現(xiàn)狀態(tài)的改變。我們定義一個(gè)Behavior,名字叫:FooterBehavior,代碼如下:
package com.lingyun.coordinatorlayoutdemo; import android.content.Context; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.util.AttributeSet; import android.view.View; /** * Created by dandy on 2016/7/4. */ public class FooterBehavior extends CoordinatorLayout.Behavior<View>{ public FooterBehavior(Context context,AttributeSet attributeSet){ super(context,attributeSet); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { float scaleY = Math.abs(dependency.getY()) / dependency.getHeight(); child.setTranslationY(child.getHeight() * scaleY); return true; } }
我們?cè)谧远x的Behavior中,帶有參數(shù)的這個(gè)構(gòu)造必須要重載,因?yàn)樵贑oordinatorLayout里利用反射去獲取這個(gè)Behavior的時(shí)候就是拿的這個(gè)構(gòu)造。
在layoutDependsOn中,我們?cè)O(shè)置讓View的狀態(tài)來(lái)跟隨AppBarLayout,也就是說(shuō)只有AppBarLayout的狀態(tài)發(fā)生變化才會(huì)影響到View。
接下來(lái)就是在onDependentViewChanged中對(duì)View做出相應(yīng)的狀態(tài)改變。在代碼中,我們做的改變是,跟隨dependedcy一起在Y軸方向移動(dòng),來(lái)達(dá)到顯示和隱藏的目的。先布局如下:
activity_main.xml布局:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/appbar_main"/> <include layout="@layout/content_main" /> <include layout="@layout/footer_main"/> </android.support.design.widget.CoordinatorLayout>
appbar_main.xml布局如下:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways"/> </android.support.design.widget.AppBarLayout>
content_main.xml布局如下:
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="你是誰(shuí)?你從哪里來(lái)?你到哪里去?"/> </android.support.v4.widget.NestedScrollView>
footer_main.xml布局如下:
<?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" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="60dp" android:layout_gravity="bottom" android:background="?attr/colorPrimary" app:layout_behavior="com.lingyun.coordinatorlayoutdemo.FooterBehavior"> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:text="Tab1" android:layout_weight="1" android:gravity="center" android:textColor="@android:color/white"/> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:text="Tab2" android:layout_weight="1" android:gravity="center" android:textColor="@android:color/white"/> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:text="Tab3" android:layout_weight="1" android:gravity="center" android:textColor="@android:color/white"/> </LinearLayout>
注意看,在footer_main.xml中我們?cè)O(shè)置了
app:layout_behavior="com.lingyun.coordinatorlayoutdemo.FooterBehavior"
這正好就是我們自定義的FooterBehavior的絕對(duì)路徑。下面我們來(lái)看一下效果圖:
在效果圖上我們看到,當(dāng)我們上下滑動(dòng)屏幕的時(shí)候,底部footer布局和標(biāo)題Toolbar一起移動(dòng),實(shí)現(xiàn)了顯示和隱藏的效果。
學(xué)會(huì)了第一張簡(jiǎn)單的自定義Behavior之后,接下來(lái)我們?cè)賮?lái)看一下第二種情況,滑動(dòng)。因?yàn)檫@個(gè)是根據(jù)CoordinatorLayout里子view的滾動(dòng)行為來(lái)改變我們的狀態(tài)的,所以情況1中的2個(gè)方法我們就不需要重寫(xiě)了。下面,我們用情況2來(lái)實(shí)現(xiàn)上面的效果。
先來(lái)看一下下面幾個(gè)參數(shù):
child:簡(jiǎn)單點(diǎn)說(shuō),就是用到當(dāng)前CoordinatorLayout的子View,響應(yīng)此Behavior。
target:CoordinatorLayout的子View,引起滾動(dòng)的view,其實(shí)child的狀態(tài)改變是根據(jù)target來(lái)實(shí)現(xiàn)的。
package com.lingyun.coordinatorlayoutdemo; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; /** * Created by dandy on 2016/7/4. */ public class FooterBehavior extends CoordinatorLayout.Behavior<View>{ private float targetY = -1; private static final String TAG = "FooterBehavior"; public FooterBehavior(Context context,AttributeSet attributeSet){ super(context, attributeSet); } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) { if(targetY == -1){ targetY = target.getY(); } return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0; } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); float scrooY = targetY - Math.abs(target.getY()); float scaleY = scrooY / targetY; child.setTranslationY(child.getHeight() * scaleY); } }
在方法onStartNestedScroll中,首先獲取target在Y軸上距離屏幕頂端的距離,然后判斷是否是在Y軸上滾動(dòng)。
方法onNestPreScroll中,就是時(shí)時(shí)根據(jù)target距離屏幕頂端的距離計(jì)算出滾動(dòng)的距離,然后根據(jù)比例計(jì)算出child移動(dòng)的距離。
截圖和上面比較沒(méi)啥區(qū)別:
基本的自定義Behavior就是這樣了,以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
文章名稱(chēng):AndroidCoordinatorLayout高級(jí)用法之自定義Behavior
分享網(wǎng)址:http://www.chinadenli.net/article28/jcosjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶(hù)體驗(yàn)、品牌網(wǎng)站設(shè)計(jì)、微信小程序、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站導(dǎo)航、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
網(wǎng)頁(yè)設(shè)計(jì)公司知識(shí)