高级UI-自定义Behavior
Behavior本身是一个抽象类,可以用于两个view之间的状态监听,也可用于某个view监听CoordinateLayout里面的所有控件滑动状态,实现自定义Behavior则可以实现任意两个view之间的状态变化
简单使用
这里我们自定义一个Behavior,继承自CoordinatorLayout.Behavior,实现观察者随着被观察者的位置改变而变动
需要重写layoutDependsOn()和onDependentViewChanged()两个方法,注意:这里的构造方法必须写上
public class CustomBehavior extends Behavior<View> {
public CustomBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 建立监听控件或容器依赖
*
* @param parent 父容器
* @param child 观察者,监听其他
* @param dependency 被观察者
* @return
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
//我们这里监听的是一个TextView
return dependency instanceof TextView
|| super.layoutDependsOn(parent, child, dependency);
}
/**
* 被监听的View改变时,相应的处理
*
* @param parent
* @param child
* @param dependency
* @return
*/
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
//获取被监听View的状态改变,这里以位置改变为例
//偏移量
int topOffset = dependency.getTop() - child.getTop();
int width = parent.getContext().getResources().getDisplayMetrics().widthPixels;
int leftOffset = dependency.getLeft() - (width - child.getRight());
//平移
ViewCompat.offsetTopAndBottom(child, topOffset);
ViewCompat.offsetLeftAndRight(child, -leftOffset);
return super.onDependentViewChanged(parent, child, dependency);
}
}
记住这里依旧需要导入依赖
implementation 'com.android.support:design:25.4.0'
然后编写主要布局,这里的两个TextView,一个为观察者,一个为被观察者
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="left|top"
android:background="@android:color/holo_orange_light"
android:gravity="center"
android:text="被观察者" />
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="right|top"
android:background="@android:color/holo_green_light"
android:gravity="center"
android:text="观察者"
app:layout_behavior=".CustomBehavior" />
</android.support.design.widget.CoordinatorLayout>
在活动中实现touch方法,使得被观察者可以被拖动
public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
private static final String TAG = "MainActivity";
private TextView textView;
private int rawX;
private int rawY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text_view);
textView.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
case R.id.text_view:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
rawX = (int) event.getRawX();
rawY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int x = (int) event.getRawX();
int y = (int) event.getRawY();
int dx = x - rawX;
int dy = y - rawY;
int l = textView.getLeft();
int r = textView.getRight();
int t = textView.getTop();
int b = textView.getBottom();
textView.layout(l + dx, t + dy, r + dx, b + dy);
rawX = (int) event.getRawX();
rawY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
}
break;
}
return true;
}
}
实现效果如下图

同时可以有多个观察者
实现滑动状态的监听
需要重写onStartNestedScroll()和onNestedScroll()方法,在观察者上做好标记
具体可参见《高级UI之FloatingActionButton》一文
高级UI-自定义Behavior的更多相关文章
- firefox 扩展开发笔记(三):高级ui交互编程
firefox 扩展开发笔记(三):高级ui交互编程 前言 前两篇链接 1:firefox 扩展开发笔记(一):jpm 使用实践以及调试 2:firefox 扩展开发笔记(二):进阶开发之移动设备模拟 ...
- Android 高级UI设计笔记07:RecyclerView 的详解
1. 使用RecyclerView 在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...
- 重要的ui组件——Behavior
v7包下的组件类似CoordinatorLayout推出也有一段时间了,大家使用的时候应该会体会到其中很多的便利,今天这篇文章带大家来了解一个比较重要的ui组件——Behavior.从字面意思上就可以 ...
- 自定义 behavior - 完美仿 QQ 浏览器首页,美团商家详情页
使用CoordinatorLayout打造各种炫酷的效果 自定义Behavior -- 仿知乎,FloatActionButton隐藏与展示 NestedScrolling 机制深入解析 一步步带你读 ...
- 原生HTML5 input type=file按钮UI自定义
原生<input type="file" name="file" />长得太丑 提升一下颜值 实现方案一.设置input[type=file]透明度 ...
- 大数据技术之_09_Flume学习_Flume概述+Flume快速入门+Flume企业开发案例+Flume监控之Ganglia+Flume高级之自定义MySQLSource+Flume企业真实面试题(重点)
第1章 Flume概述1.1 Flume定义1.2 Flume组成架构1.2.1 Agent1.2.2 Source1.2.3 Channel1.2.4 Sink1.2.5 Event1.3 Flum ...
- 自定义Behavior 实现Listbox自动滚动到选中项
原文:自定义Behavior 实现Listbox自动滚动到选中项 blend为我们提供方便的behavior来扩展我们的控件,写好之后就可以在blend中方便的使用了. 下面是自定义的behavior ...
- Nginx 高级配置-自定义json格式日志
Nginx 高级配置-自定义json格式日志 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在大数据运维工作中,我们经常会使用flume,filebeat相关日志收集工具取收集日志 ...
- Customize the Application UI and Behavior 自定义应用程序UI和行为
In XAF, the business model defines the database structure and UI appearance. Changes to your persist ...
随机推荐
- 【数论】P1029 最大公约数和最小公倍数问题
题目链接 P1029 最大公约数和最小公倍数问题 思路 如果有两个数a和b,他们的gcd(a,b)和lcm(a,b)的乘积就等于ab. 也就是: ab=gcd(a,b)*lcm(a,b) 那么,接下来 ...
- 2019暑期金华集训 Day5 树上数据结构
自闭集训 Day5 树上数据结构 前置知识 点分治 边分治 树链剖分 LCT Top Tree LCT时间复杂度 线段树每次查询是严格\(\log n\)的,然而splay维护连续段的时候,如果每次查 ...
- idea使用/***/单行注释格式化后会显示多行,如何能保持单行显示
- SpringCloud:Ribbon负载均衡
1.概述 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具. 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客 ...
- 解决Spring Boot 拦截器注入service为空的问题
问题:在自定义拦截器中,使用了@Autowaire注解注入了封装JPA方法的Service,结果发现无法注入,注入的service为空 0.原因分析 拦截器加载的时间点在springcontext之前 ...
- 三层设备-SHRP详解
步骤:3-sw1enconf tvlan databasevtp domain s2t117vtp servervlan 10vlan 20vlan 30vlan 40exitint r f0/7 - ...
- shell脚本实例,通向shell脚本大师的必经之路
概述 读书百遍其义自见,shell脚本也是,只要例子看得多了,自然就知道怎么写了.这里主要整理了20几个例子,因为内容比较多,所以分了几次来做介绍了.下面的实例最好先自己思考怎么去实现,然后再看下实现 ...
- 【Python 代码】CS231n中Softmax线性分类器、非线性分类器对比举例(含python绘图显示结果)
1 #CS231n中线性.非线性分类器举例(Softmax) #注意其中反向传播的计算 # -*- coding: utf-8 -*- import numpy as np import matplo ...
- 【caffe Layer】代码中文注释
src/caffe/proto/caffe.proto 中LayerParameter部分 // NOTE // Update the next available ID when you add a ...
- go语言中type的几种使用
type是go语法里的重要而且常用的关键字,type绝不只是对应于C/C++中的typedef.搞清楚type的使用,就容易理解go语言中的核心概念struct.interface.函数等的使用.以下 ...