国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android CoordinatorLayout高級用法之自定義Behavior

2019-10-22 18:15:51
字體:
來源:轉載
供稿:網友

上次簡單的說了一下CoordinatorLayout的基本用法(android特性之CoordinatorLayout用法探析實例)。其中CoordinatorLayout給我們提供了一種新的事件的處理方式,Behavior。還記得那一串字符串嗎?

app:layout_behavior="@string/appbar_scrolling_view_behavior" 

其實它并不是一個字符串資源,而它代表的是一個類,就是一個Behavior,這玩意其實還可以自定義的。

首先,來讓我見識一下它的真面目:

public static abstract class Behavior<V extends View> { ... } 

Behavior是CoordinatorLayout的一個內部泛型抽象類。內部類中指定的view類型規定了哪種類型的view的可以使用才Behavior。因此,如果沒有特殊需求,直接指定view為View就行了。

1.某個view需要根據監聽另一個的行為來控制自己的行為,這個時候我們需要重寫2個方法:

public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) {       return false;     } 
public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) {       return false;     } 

2.我們的view需要根據監聽CoordinatorLayout中的子view的滾動行為來改變自己的狀態,現在我們就需要重寫下面的方法了:

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 } 

下面我們先來看一下情況1,讓一個view跟隨另一個view的行為而實現狀態的改變。我們定義一個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;   } } 

我們在自定義的Behavior中,帶有參數的這個構造必須要重載,因為在CoordinatorLayout里利用反射去獲取這個Behavior的時候就是拿的這個構造。

在layoutDependsOn中,我們設置讓View的狀態來跟隨AppBarLayout,也就是說只有AppBarLayout的狀態發生變化才會影響到View。

接下來就是在onDependentViewChanged中對View做出相應的狀態改變。在代碼中,我們做的改變是,跟隨dependedcy一起在Y軸方向移動,來達到顯示和隱藏的目的。先布局如下:

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="你是誰?你從哪里來?你到哪里去?"/> </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中我們設置了

app:layout_behavior="com.lingyun.coordinatorlayoutdemo.FooterBehavior" 

這正好就是我們自定義的FooterBehavior的絕對路徑。下面我們來看一下效果圖:

Android,CoordinatorLayout,Behavior

在效果圖上我們看到,當我們上下滑動屏幕的時候,底部footer布局和標題Toolbar一起移動,實現了顯示和隱藏的效果。

學會了第一張簡單的自定義Behavior之后,接下來我們再來看一下第二種情況,滑動。因為這個是根據CoordinatorLayout里子view的滾動行為來改變我們的狀態的,所以情況1中的2個方法我們就不需要重寫了。下面,我們用情況2來實現上面的效果。
先來看一下下面幾個參數:

child:簡單點說,就是用到當前CoordinatorLayout的子View,響應此Behavior。

target:CoordinatorLayout的子View,引起滾動的view,其實child的狀態改變是根據target來實現的。

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軸上滾動。
方法onNestPreScroll中,就是時時根據target距離屏幕頂端的距離計算出滾動的距離,然后根據比例計算出child移動的距離。
截圖和上面比較沒啥區別:

Android,CoordinatorLayout,Behavior

基本的自定義Behavior就是這樣了,以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宜宾县| 囊谦县| 应城市| 东海县| 华坪县| 神池县| 沙坪坝区| 元阳县| 定日县| 淳安县| 龙里县| 建阳市| 上林县| 绵阳市| 太湖县| 获嘉县| 济宁市| 阜南县| 扎鲁特旗| 新干县| 宜川县| 龙岩市| 岑巩县| 山西省| 水城县| 包头市| 都昌县| 霍山县| 分宜县| 凤台县| 鄢陵县| 阳山县| 南城县| 临西县| 青铜峡市| 廉江市| 吉木萨尔县| 济阳县| 泾源县| 子长县| 宁国市|