高级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 ...
随机推荐
- 【JS】知识笔记
一.JS文件位置 多个.JS文件最好合并到一个文件中,减少加载页面时发送的请求数量. 某个单独页面需要的js,最好放在HTML文档的最后,</body>之前,这样能使浏览器更快地加载页面. ...
- source insight parse link
source insight parse link \([a-zA-Z_]*\.[chCH]\) ([^)]*) line \([0-9][0-9]*\)
- 数码管一些列功能的verilog实现
将数码管各段发光元件的正极连在一起称为共阳数码管,且该共点击链接电路电源的正极,而各段的负极连接驱动电路.它适用于低电平有效的驱动电路,当某段的驱动电平为低电平时,该段发亮:将数码管各段发光元件的负极 ...
- fhq treap ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : LibreOJ #104. 普通平衡树 #include <cstdio> #include <iostream> #include <algorithm ...
- 1054 The Dominant Color (20)(20 分)
Behind the scenes in the computer's memory, color is always talked about as a series of 24 bits of i ...
- JavaWeb之Tomcat(1) —— Tomcat的目录结构
1. bin 文件夹 存放Tomcat的可执行文件 (1) startup.bat 文件,启动Tomcat服务的批处理文件. (2) shutdown.bat 文件,结束Tomcat服务的批处理文件. ...
- Python中单引号和双引号的作用
一.单引号和双引号 在Python中我们都知道单引号和双引号都可以用来表示一个字符串,比如 str1 = 'python' str2 = "python" str1和str2是没有 ...
- html中a标签的常见用法
html中a标签的常见用法 一.总结 一句话总结: a.页面跳转 b.使用锚点定位 c.下载文件 二.html中<a>标签的用法 转自或参考:html中<a>标签的用法http ...
- Oracle备份的几种方式
这里使用Oracle 12C来大概演示说明一下rman的基本用法,这里不会深入讨论,因为本人也只是刚刚才接触,只是结合了网上的一些文章以及自己的实践来总结并拿出来大家学习,谢谢 目录 一.关于备份与恢 ...
- php中函数 isset(), empty(), is_null() 的区别
NULL:当你在你的脚本中写下这样一行代码 $myvariable; //此处你想定义一个变量,但未赋值.会有Notice: Undefined variable echo $myvariable + ...