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特性之CoordinatorLayout用法探析实例
  • Android中关于CoordinatorLayout的一些实用布局技巧
  • Android 使用CoordinatorLayout实现滚动标题栏效果的实例
  • Android CoordinatorLayout详解及实例代码
  • Android 5.0中CoordinatorLayout的使用技巧
  • CoordinatorLayout的使用如此简单(Android)
(0)

相关推荐

  • 详解android特性之CoordinatorLayout用法探析实例

    当我在AS上新建一个module时,系统默认的最外层布局不再是我们熟悉的五大布局中的一种,而是一个全新的布局:CoordinatorLayout.它是Material风格的重要组件, 作为布局的顶层控件,协调(Coordinate)其他组件, 实现联动. 下面来看一个最简单的例子,CoordinatorLayout与FloatingActionButton的使用,它可以使浮动按钮上下移动,为Snackbar流出空间来展示. 定义的布局文件如下: <?xml version="1.0&quo

  • Android 5.0中CoordinatorLayout的使用技巧

    CoordinatorLayout 实现了多种Material Design中提到的滚动效果.目前这个框架提供了几种不用写动画代码就能工作的方法,这些效果包括: *让浮动操作按钮上下滑动,为Snackbar留出空间. *扩展或者缩小Toolbar或者头部,让主内容区域有更多的空间. *控制哪个view应该扩展还是收缩,以及其显示大小比例,包括视差滚动效果动画. 浮动操作按钮与Snackbar CoordinatorLayout可以用来配合浮动操作按钮的 layout_anchor 和 layou

  • Android 使用CoordinatorLayout实现滚动标题栏效果的实例

    在Material Design里,CoordinatorLayout通常用来作为顶层视图,来协调处理各个子View之间的动作,从而实现各种动画效果,如Snackbar与FloatingActionButton的配合显示效果,就是以CoordinatorLayout作为根布局来实现的 CoordinatorLayout提供Behaviors接口,子View通过实现Behaviors接口来协调和其它View之间的显示效果,可以这么理解: CoordinatorLayout让其子View之间互相知道

  • Android中关于CoordinatorLayout的一些实用布局技巧

    介绍 CoordinatorLayout是一个"加强版"的 FrameLayout,它主要有两个用途: (1) 用作应用的顶层布局管理器 (2) 通过为子View指定 behavior 实现自定义的交互行为. 在我们做 Material Design 风格的app时通常都使用 CoordinatorLayout 作为布局的根节点,以便实现特定的UI交互行为. 那么现在我们来看看如何用已有的一些控件实现一些常见的布局. Toolbar + TabLayout 实现 TabLayout 置

  • Android CoordinatorLayout详解及实例代码

    Android CoordinatorLayout详解 一.CoordinatorLayout有什么作用 CoordinatorLayout作为"super-powered FrameLayout"基本实现两个功能: 1.作为顶层布局 2.调度协调子布局 CoordinatorLayout使用新的思路通过协调调度子布局的形式实现触摸影响布局的形式产生动画效果.CoordinatorLayout通过设置子View的 Behaviors来调度子View.系统(Support V7)提供了A

  • CoordinatorLayout的使用如此简单(Android)

    曾在网上找了一些关于CoordinatorLayout的教程,大部分文章都是把CoordinatorLayout.AppbarLayout.CollapsingToolbarLayout 以及Toolbar等一起使用来介绍,这让我不知不觉在心中认为把这几个布局要一起使用,而且只是用于那种场景中.其实CoordinatorLayout的功能并不是局限于与AppBarLayout一起使用,它的功能强大着呢,本文主要对CoordinatorLayout的使用进行介绍,后面再写一篇文章将AppBarLa

  • Android CoordinatorLayout高级用法之自定义Behavior

    上次简单的说了一下CoordinatorLayout的基本用法(android特性之CoordinatorLayout用法探析实例).其中CoordinatorLayout给我们提供了一种新的事件的处理方式,Behavior.还记得那一串字符串吗? app:layout_behavior="@string/appbar_scrolling_view_behavior" 其实它并不是一个字符串资源,而它代表的是一个类,就是一个Behavior,这玩意其实还可以自定义的. 首先,来让我见识

  • Android自定义view Path 的高级用法之搜索按钮动画

    关于Path之前写的也很多了,例如path绘制线,path绘制一阶,二阶和三阶贝塞尔路径,这些都是path的基本用法.今天我要带大家看的是Path 的高级用法,先上图,再吹. 效果大致是这样的.看着是不是挺好.话不多说,切入正题: 既然今天要谈Path的高级用法,那就先来讲一讲(Path -- 中文 )就是"路径"既然是路径,从我们面向对象的想法的话,我们就容易想到 路径 的长度,路径的某一点等.想到这里我们就引出今天 的主要 类--------PathMeasure,字面意思很容易理

  • Android开发高级组件之自动完成文本框(AutoCompleteTextView)用法示例【附源码下载】

    本文实例讲述了Android开发高级组件之自动完成文本框(AutoCompleteTextView)用法.分享给大家供大家参考,具体如下: 通常来说自动完成文本框(AutoCompleteTextView)从EditText派生而出,实际上他也是一个编辑框,但他比普通的编辑框多了一个功能:当用户输入一定字符后,自动完成文本框会显示一个下拉菜单,供用户从中选择,当用户选择了某个菜单项过后,AutoCompleteTextView就会按用户选择自动填写该文本框. 自动完成文本框(AutoComple

  • Android TextView高级显示技巧实例小结

    本文实例总结了Android TextView高级显示技巧.分享给大家供大家参考,具体如下: 1. 自定义字体 可以使用setTypeface(Typeface)方法来设置文本框内文本的字体,而Android的 Typeface又使用TTF字体文件来设置字体 所以,我们可以在程序中放入TTF字体文件,在程序中使用Typeface来设置字体:第一步,在assets目录下新建fonts目录,把TTF字体文件放到这里.第二步,程序中调用: TextViewtv = (TextView)findView

  • Material Design系列之自定义Behavior支持所有View

    本文实例为大家分享了Android自定义Behavior支持所有View ,供大家参考,具体内容如下 一.实现效果图 这个右下角的FAB,动画当然可以多种多样,可以放在界面的任何地方,我们这里只举个例子.但是v7包中提供的Behavior目前只能是FloatingActionButton来用,所以今天我们实现的这个Behavior是支持所有的View的,可以用在ImageView.Button.Layout,只要是继承View的类都可以用. 二.自定义Behavior和动画的封装 我们知道Beh

  • asp.net core标签助手的高级用法TagHelper+Form

    上一篇博客我讲解了TagHelper的基本用法和自定义标签的生成,那么我就趁热打铁,和大家分享一下TagHelper的高级用法~~,大家也可以在我的博客下随意留言. 对于初步接触asp.net core的骚年可以看看我对TagHelper的了解和看法: <asp.net core新特性(1):TagHelper> 之后,我也会继续撰写博文,继续分享asp.net core的一些新特性,比如DI,ViewComponent以及bower等asp.net mvc中没有的新东西. ok,咱们就开始吧

  • yii2高级应用之自定义组件实现全局使用图片上传功能的方法

    本文讲述了yii2高级应用之自定义组件实现全局使用图片上传功能的方法.分享给大家供大家参考,具体如下: 此例为yii2高组应用,这里只提供一个简单的事例 在yii2中,在使用到上传图片时有自带的一个上传图片类,但不太好用. 其中有一种方式,把自己写的一个上传图片类文件,注册成一个组件,在全局中使用.(我记得我在里面有写过一篇小物件的使用) 这里,我只作一个简单的自定义组件介绍 1.在backend(或frontend)定义一个 upload.php(注意路径: backend/component

  • Android中Notification用法实例总结

    本文实例总结了 Android中Notification用法.分享给大家供大家参考,具体如下: 我们在用手机的时候,如果来了短信,而我们没有点击查看的话,是不是在手机的最上边的状态栏里有一个短信的小图标提示啊?你是不是也想实现这种功能呢?今天的Notification就是解决这个问题的. 我们也知道Android系统也是在不断升级的,有关Notification的用法也就有很多种,有的方法已经被android抛弃了,现在我实现了三种不同的方法,并适应不同的android版本.现在我就把代码公布出

  • Android Toast通知用法实例详解

    本文实例讲述了Android Toast通知用法.分享给大家供大家参考,具体如下: Toast在手机屏幕上向用户显示一条信息,一段时间后信息会自动消失. 1.默认用法 复制代码 代码如下: Toast.makeText(getApplicationContext(), "默认Toast样式",Toast.LENGTH_SHORT).show(); 2.Fragment中的用法 复制代码 代码如下: Toast.makeText(getActivity(),"网络连接错误,请检

随机推荐