首页 >> 大全

Android 自定义Behavior

2023-10-03 大全 22 作者:考证青年

一、的介绍 1、什么是

上篇文章我们讲到 配合、out实现了的隐藏和折叠,但他们之间能够进行交互,其实就是通过一个介质. 实现的。是用来和各个子View通信用的代理类,用来协调的Child Views之间的交互行为,但使用的前提是只有是的直接子View才有意义。

2、引用的两种方式 二、 的两种机制 1、 机制 1.1 介绍

这种机制主要是用来描述 两个Child View 之间的绑定依赖关系,设置 属性的Child View 跟随依赖对象 View 的大小位置改变而发生改变,因此它用于一个View 监听另一个View 的状态变化。我们需要通过两个方法,来实现绑定:

    /*** 确定要依赖的对象*/@Overridepublic boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {return super.layoutDependsOn(parent, child, dependency);}/*** 当依赖的对象发生变化时会自动回调这个方法*/@Overridepublic boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {return super.onDependentViewChanged(parent, child, dependency);}

1.2、举例说明 机制

定义域__定义域怎么求

可以看到,我对红色方块 进行拖动的时候,绿色的方块也发生了位置变化。

先自定义一个,代码如下:

public class DependentBehavior extends CoordinatorLayout.Behavior<View> {/*** 构造方法** @param context* @param attrs*/public DependentBehavior(Context context, AttributeSet attrs) {super(context, attrs);}/*** 确定要依赖的对象** @param parent* @param child* @param dependency* @return*/@Overridepublic boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {return dependency.getId() == R.id.btn_first;}/*** 当依赖的对象发生变化时会自动回调这个方法** @param parent* @param child* @param dependency* @return*/@Overridepublic boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {// 根据要依赖的x坐标,更改当前控件的X坐标child.setX(parent.getWidth() - dependency.getX() - dependency.getWidth());child.setY(dependency.getY());return super.onDependentViewChanged(parent, child, dependency);}
}

.xml 代码:


<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/coordinator"android:layout_width="match_parent"android:layout_height="match_parent"><Button
        android:id="@+id/btn_first"android:layout_width="100dp"android:layout_height="100dp"android:layout_marginLeft="20dp"android:layout_marginTop="100dp"android:background="@android:color/holo_red_light" /><Button
        android:id="@+id/btn_two"android:layout_width="100dp"android:layout_height="100dp"android:layout_gravity="right"android:layout_marginRight="20dp"android:layout_marginTop="100dp"android:background="@android:color/holo_green_light"app:layout_behavior=".DependentBehavior" />
android.support.design.widget.CoordinatorLayout>

主界面代码:

public class DependentActivity extends AppCompatActivity implements View.OnTouchListener {private Button mbtnFirst;private int lastX, lastY;    //保存手指点下的点的坐标private int mWidth, mHeight;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_dependent);mbtnFirst = (Button) findViewById(R.id.btn_first);//设置屏幕触摸事件mbtnFirst.setOnTouchListener(this);}/*** 当activity 的焦点发生改变时(View 已经绘制完成,可以获得宽高)** @param hasFocus*/@Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);mWidth = mbtnFirst.getWidth();mHeight = mbtnFirst.getHeight();}/*** 触屏事件处理** @param view* @param event* @return*/@Overridepublic boolean onTouch(View view, MotionEvent event) {// 处理多点触摸的ACTION_POINTER_DOWN和ACTION_POINTER_UP事件switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN://将点下的点的坐标保存lastX = (int) event.getRawX();lastY = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE://计算出需要移动的距离int dx = (int) event.getRawX() - lastX;int dy = (int) event.getRawY() - lastY;//将移动距离加上,现在本身距离边框的位置int left = view.getLeft() + dx;int top = view.getTop() + dy;//获取到layoutParams然后改变属性,在设置回去CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) view.getLayoutParams();layoutParams.height = mHeight;layoutParams.width = mWidth;layoutParams.leftMargin = left;layoutParams.topMargin = top;view.setLayoutParams(layoutParams);//记录最后一次移动的位置lastX = (int) event.getRawX();lastY = (int) event.getRawY();break;}return true;}
}

2、机制 2.1 介绍

机制要求包含了一个实现了接口的滚动视图控件,比如v7包中的,设置属性的Child View会随着这个控件的滚动而发生变化,涉及到的方法有:

(View child, View , int )

(View , int dx, int dy, int[] )

(View , float , float )

(View , int , int , int , int )

(View , float , float , )

(View )

下面我将简单描述下四个方法:

    /***  会遍历每一个 子View,询问它们是否对滚动列表的滚动事件感兴趣,若 Behavior.onStartNestedScroll 方法返回 true,*  则表示感兴趣,那么滚动列表后续的滚动事件都会分发到该 子View的Behavior*/@Overridepublic boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int axes, int type) {return true;}/***  处理 子View 的滚动事件*/@Overridepublic void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed, int type) {super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);}/*** 检测滚动距离的最终消费情况,可以继续处理 滚动事件*/@Overridepublic void onNestedScroll( CoordinatorLayout coordinatorLayout,  View child,  View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);}/*** 检测到滚动事件的结束*/@Overridepublic void onStopNestedScroll( CoordinatorLayout coordinatorLayout,  View child,  View target, int type) {super.onStopNestedScroll(coordinatorLayout, child, target, type);}

2.2、举例说明 机制

定义域_定义域怎么求_

可以看到,当下拉列表时,红色布局就会消失,向上滑动时,红色布局就会出现。

先创建一个,代码如下:

public class NestedBehavior extends CoordinatorLayout.Behavior<View> {int offsetTotal = 0;public NestedBehavior(Context context, AttributeSet attrs) {super(context, attrs);}/***  会遍历每一个 子View,询问它们是否对滚动列表的滚动事件感兴趣,若 Behavior.onStartNestedScroll 方法返回 true,*  则表示感兴趣,那么滚动列表后续的滚动事件都会分发到该 子View的Behavior*/@Overridepublic boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int axes, int type) {return true;}/***  处理 子View 的滚动事件*/@Overridepublic void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed, int type) {super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);offset(child, dy);}public void offset(View child, int dy) {// 上次保存的位置int old = offsetTotal;// 当前的位置int curr = offsetTotal - dy;// 保证子控件的位置一直在 0-控件高度之间curr = Math.max(curr, -child.getHeight());curr = Math.min(curr, 0);offsetTotal = curr;if (old == offsetTotal) {return;}// 原来的位置 - 当前的位置 = 要移动的位置int delta = old - offsetTotal;child.offsetTopAndBottom(delta);}}

.xml 代码:

"1.0" encoding="utf-8"?>
.support.design.widget.CoordinatorLayout 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">.support.v7.widget.RecyclerViewandroid:id="@+id/recyclerview"android:layout_width="match_parent"android:layout_height="match_parent">.support.v7.widget.RecyclerView>"match_parent"android:layout_height="60dp"android:layout_gravity="bottom"android:background="@android:color/holo_red_light"android:gravity="center"app:layout_behavior=".NestedBehavior">"wrap_content"android:layout_height="wrap_content"android:text="自定义Behavior"android:textColor="@android:color/white"android:textSize="20sp" />
.support.design.widget.CoordinatorLayout>

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了