Android高级UI开发(二十三)自定义behavior(2)监听控件滑动

举报
yd_57386892 发表于 2020/12/28 23:50:06 2020/12/28
3.9k+ 0 0
【摘要】 上一篇我们讲了自定义behavior监听控件的状态变化:例如垂直方向位移的变化。今天我们要谈的是如何监听控件的滑动事件。就是说当布局文件里有一个可滑动的控件(如RecyclerView、NestedScrollView、Viewpager页面里的NestedScrollView)滑动时,我们自定义的behavior可以帮观察者监听到该类事件,同时做相应的处理。我们还是从布局文...

上一篇我们讲了自定义behavior监听控件的状态变化:例如垂直方向位移的变化。今天我们要谈的是如何监听控件的滑动事件。就是说当布局文件里有一个可滑动的控件(如RecyclerView、NestedScrollView、Viewpager页面里的NestedScrollView)滑动时,我们自定义的behavior可以帮观察者监听到该类事件,同时做相应的处理。我们还是从布局文件讲起,在此之前先看以下运行效果:

1. 布局文件


      <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.support.v4.widget.NestedScrollView
      android:id="@+id/nestedScroll"
      android:layout_width="200dp"
      android:layout_height="wrap_content"
      android:layout_gravity="left">
      <LinearLayout
      android:id="@+id/nestedScrollLayout"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical">
      <ImageView
      android:id="@+id/bt2"
      android:layout_margin="50dp"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_gravity="left|top"
      android:background="@drawable/d1"
      android:textColor="@color/white" />
      <ImageView
      android:layout_margin="50dp"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_gravity="left|top"
      android:background="@drawable/d2"
      android:textColor="@color/white" />
      <ImageView
      android:layout_margin="50dp"
      android:id="@+id/bt1"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_gravity="left|top"
      android:background="@drawable/d2"
      android:textColor="@color/white" />
      <ImageView
      android:layout_margin="50dp"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_gravity="left|top"
      android:background="@drawable/d2"
      android:textColor="@color/white" />
      <ImageView
      android:layout_margin="50dp"
      android:id="@+id/bt21"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_gravity="left|top"
      android:background="@drawable/d2"
      android:tag="tv1"
      android:textColor="@color/white" />
      <ImageView
      android:layout_margin="50dp"
      android:id="@+id/bt23"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_gravity="left|top"
      android:background="@drawable/d2"
      android:tag="tv1"
      android:textColor="@color/white" />
      </LinearLayout>
      </android.support.v4.widget.NestedScrollView>
      <ImageView
      android:background="@drawable/d1"
      android:id="@+id/obeserver"
      android:layout_marginRight="20dp"
      android:layout_width="72dp"
      android:layout_height="72dp"
      android:layout_gravity="right|center_vertical"
      android:text="观察者"
      app:layout_behavior="com.example.custombehavior.ListenerScrollBehavior" />
      </android.support.design.widget.CoordinatorLayout>
  
 

在这里我们声明一个被观测者NestedScrollView,再声明一个观察者NestedScrollView,同时为观察者配置一个自定义behavior:layout_behavior="com.example.custombehavior.ListenerScrollBehavior". 我们看到这个布局的根布局仍然是CoordinatorLayout,这与我们之前的一样,CoordinatorLayout布局捕捉到事件及控件状态变化后,分发给我们自定义的behavior。接下来我们就来看一下这个自定义behavior的实现,看它是如何来监听控件的滑动事件。

2. 自定义Behavior实现


      package com.example.custombehavior;
      import android.content.Context;
      import android.support.design.widget.CoordinatorLayout;
      import android.support.design.widget.CoordinatorLayout.Behavior;
      import android.support.v4.view.ViewCompat;
      import android.support.v4.widget.NestedScrollView;
      import android.util.AttributeSet;
      import android.util.Log;
      import android.view.View;
      import java.util.Random;
      public class ListenerScrollBehavior extends Behavior<View> {
     	public ListenerScrollBehavior(Context arg0, AttributeSet arg1) {
     		super(arg0, arg1);
     		// TODO Auto-generated constructor stub
      	}
     	/**
       * 用来决定谁是观察者,谁是被观察者
       * @param coordinatorLayout ,父容器
       * @param child, 观察者
       @param directTargetChild,被观察者
       @param target: 与directTargetChild指的是同一个控件NestedScrollView
       */
     	@Override
     	public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
       View child, View directTargetChild, View target,
       int nestedScrollAxes) {
     		// TODO Auto-generated method stub
     		//监听垂直滚动
     		return (nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL)||super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
       target, nestedScrollAxes);
      	}
     	@Override
     	public void onNestedPreScroll(CoordinatorLayout coordinatorLayout,
       View child, View target, int dx, int dy, int[] consumed) {
     		// TODO Auto-generated method stub
      		child.animate().rotation( dy* 360);
     		super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
      	}
     	@Override
     	public boolean onNestedFling(CoordinatorLayout coordinatorLayout,
       View child, View target, float velocityX, float velocityY,
       boolean consumed) {
     		return super.onNestedFling(coordinatorLayout, child, target, velocityX,
       velocityY, consumed);
      	}
      }
  
 

这里和上一篇类似,只是重写的函数不一样,我们来介绍以下几个函数“

1.onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes);

CoordinatorLayout :根布局

child:观察者

directTargetChild:被观察者

target:还是被观察者,在这里与directTargetChild指向的控件是同一个

nestedScrollAxes:将要监听的滚动方向,垂直还是水平。

child是观察者,对应布局里的id为observer控件 ;directTargetChild是被观察者,对应布局里的id为NestedScrollView控件。

nestedScrollAxes表示滚动的方向。在此我们return (nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL)表示我们只监听NestedScrollView的垂直滑动事件。

2.onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed)

当滑动时执行。

CoordinatorLayout :根布局

child:观察者

target:被观察者,在这里与directTargetChild指向的控件是同一个

nestedScrollAxes:将要监听的滚动方向,垂直还是水平。

dx:每次滚动的水平距离

dy:每次滚动的垂直距离

这里我们让观察者child执行动画:child.animate().rotation( dy* 360); 这样就实现了观察者监听到滑动事件并作出相应的处理。

3. onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed)

滚动的惯性。在这里我们没有用到,用于监听滚动的惯性,就是当人手指松开后列表还会滑动一段距离,我们可以检测到velocityX与velocityY两个惯性值,运用场景可以是:当滑动一个列表时,让另一个列表 跟着滑动,而且另一个列表的惯性值要与列表1的惯性值一样,才能真正保持同步滑动。

CoordinatorLayout :根布局

child:观察者

target:被观察者

velocityX  轴滚动的惯性值,就是人手指松开后列表还会滑动一段距离

velocityY  轴滚动的惯性值,就是人手指松开后列表还会滑动一段距离

consumed: 这个还不理解,望请指教。

OK,至此自定义Behavior监听滑动事件就讲到这里,最后附上源码地址:https://download.csdn.net/download/gaoxiaoweiandy/11009736

 
 

文章来源: blog.csdn.net,作者:冉航--小虾米,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/gaoxiaoweiandy/article/details/88375509

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。