Android CoordinatorLayout高级用法之自定义Behavior

 更新时间:2018年02月01日 09:21:46   作者:FightSeeker  
这篇文章主要介绍了Android CoordinatorLayout高级用法之自定义Behavior,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

上次简单的说了一下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的绝对路径。下面我们来看一下效果图:

在效果图上我们看到,当我们上下滑动屏幕的时候,底部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移动的距离。
截图和上面比较没啥区别:

基本的自定义Behavior就是这样了,以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android自制精彩弹幕效果

    Android自制精彩弹幕效果

    这篇文章主要为大家详细介绍了Android自制精彩弹幕效果,弹幕垂直方向可固定随机,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • android自定义view用path画长方形

    android自定义view用path画长方形

    这篇文章主要为大家详细介绍了android自定义view用path画长方形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • Android Binder进程间通信工具AIDL使用示例深入分析

    Android Binder进程间通信工具AIDL使用示例深入分析

    Binder作为Android 众多的IPC通讯手段之一,在Framework的数据传输中起到极为关键的作用。Binder机制可谓是Android 知识体系里的重中之重,作为偏底层的基础组件,平时我们很少关注它,而它却是无处不在,也是Android 面试易考察的点之一
    2022-11-11
  • Flutter开发实现底部留言板

    Flutter开发实现底部留言板

    这篇文章主要为大家详细介绍了Flutter开发实现底部留言板,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Android入门之实现自定义Adapter

    Android入门之实现自定义Adapter

    这篇文章主要为大家详细介绍了Android如何实现自定义Adapter,文中的示例代码讲解详细,对我们学习Android有一定的帮助,需要的可以参考一下
    2022-11-11
  • Android仿高德首页三段式滑动效果的示例代码

    Android仿高德首页三段式滑动效果的示例代码

    很多app都会使用三段式滑动,比如说高德的首页和某宝等物流信息都是使用的三段式滑动方式。本文将介绍如何实现这一效果,感兴趣的可以学习一下
    2022-01-01
  • android利用消息机制获取网络图片

    android利用消息机制获取网络图片

    这篇文章主要为大家详细介绍了android利用消息机制获取网络图片的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Android实现签名涂鸦手写板

    Android实现签名涂鸦手写板

    这篇文章主要为大家详细介绍了Android实现签名涂鸦手写板,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • Android使用注解代替枚举节省系统内存开销的方法

    Android使用注解代替枚举节省系统内存开销的方法

    在本篇文章里小编给大家整理的是关于Android使用注解代替枚举节省系统内存开销的方法和实例,需要的朋友们参考下。
    2020-01-01
  • android实现注册登录程序

    android实现注册登录程序

    这篇文章主要为大家详细介绍了android实现注册登录程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04

最新评论