该笔记适合准备入手Android自定义View学习的小伙伴,对于大神的话,建议去其他地方逛逛哈,在此博主声明一下:我不是尚硅谷的什么托,只是一个菜鸟,现在在补着Java基础,搞了一套尚硅谷的Java视频以及Android视频,所以笔记可能会常出现这些字眼,请言语讽刺我是托的麻烦你闭嘴哈
- 尚硅谷事件机制以及自定义控件的绘制基础 (最需要下载的:15天安卓视频->视频->06_事件机制.zip以及07_四大应用组件之Service)
尚硅谷Android自定义控件视频(实战),记得下载上面的链接视频,因为其涉及了基础(如果是小白)
视频格式转gif-Video to animated GIF converter
备用下载链接: https://pan.baidu.com/s/1jIytuCY 密码: ggty
- youlookwhat/CustomViewStudy: 自定义View从入门到进阶(集合Hongyang大神)).
- Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent() - 张兴业的博客 - 博客频道 - CSDN.NET
- Android_CustomSwitch at master · IamXiaRui/Android_Demo_View
- View 的事件分发机制 | 一个写代码的地方
- MotionEvent : 触屏事件
int ACTION_DOWN=0 : 代表down
Int ACTION_MOVE=2 ; 代表move
Int ACTION_UP=1 : 代表up
getAction() : 得到事件类型值
getX() : 得到事件发生的x轴坐标(相对于当前视图)
getRawX() :得到事件发生的x轴坐标(相对于屏幕左顶点)
getY() : 得到事件发生的y轴坐标(相对于当前视图)
getRawY() :得到事件发生的y轴坐标(相对于屏幕左顶点)- Activity
boolean dispatchTouchEvent(MotionEvent event) : 分发事件
boolean onTouchEvent(MotionEvent event) : 处理事件的回调- View
boolean dispatchTouchEvent(MotionEvent event) : 分发事件
boolean onTouchEvent(MotionEvent event) : 处理事件的回调方法
void setOnTouchListener(OnTouchListener l) : 设置事件监听器
void setOnClickListener(OnClickListener l) : 设置点击监听
void setOnLongClickListener(OnLongClickListener l) : 设置长按监听
void setOnCreateContextMenuListener(OnCreateContextMenuListener l) : 用于创建菜单- ViewGroup
boolean dispatchTouchEvent(MotionEvent ev) : 分发事件
boolean onInterceptTouchEvent(MotionEvent ev) : 拦截事件的回调方法
注意:其中View跟ViewGroup中都有dispatchTouchEvent方法,但View这个方法更多倾向于分发给自身的onTouchEvent跟setOnTouchListener方法,而ViewGroup中的这个方法是将事件分发给子View
优秀博客:Android事件分发机制完全解析,带你从源码的角度彻底理解(上) - 郭霖的专栏 - 博客频道 - CSDN.NET
down : 手指按下
up : 手指从按键上离开
* 按键操作的顺序: down->down->down->…->up
* 对按键的任何一个操作, 系统都会创建一个KeyEvent对象来对应这个操作
* 按键的长按监听: down之后一定时间还没有up时会触发长按监听回调
KeyEvent
int ACTION_DOWN = 0 : 标识down的常量
int ACTION_UP = 1 : 标识up的常量
int getAction() : 得到事件类型
int getKeyCode() : 得到按键的keycode(唯一标识)
startTracking() : 追踪事件, 用于长按监听 (在keyDown那里设置,event.startTracking()方法,这样onKeyLongPress方法才会有效,但特殊的是back键已经那只了这个方法)
Activity
boolean dispatchKeyEvent(KeyEvent event) : 分发事件
boolean onKeyDown(int keyCode, KeyEvent event) : 按下按键的回调
boolean onKeyUp(int keyCode, KeyEvent event) : 松开按键的回调
boolean onKeyLongPress(int keyCode, KeyEvent event) : 长按按键的回调
先看以前的笔记:尚硅谷15天Android基础(复习笔记) - it菜鸟的飞行梦 - 博客频道 - CSDN.NET
生命周期:创建对象(Activity的onResume()执行之后才会进入后面的流程)、显示(测量onMeasure、布局onLayout、绘制onDraw)、事件处理、死亡
创建对象
测量
布局
绘制
事件处理
这里特别指出,ImageView是布局具有图片效果的UI常用的类,SurfaceView是用来进行游戏开发的与一般View相比较为特殊的非常重要的类,而AbsoluteLayout、 FrameLayout,LinearLayout, RelativeLayout这几个ViewGroup的直接子类是Android UI布局中最基本的布局元素。
View Animation(补间动画):
基于View的渐变动画,她只改变了View的绘制效果,而实际属性值未变。比如动画移动一个按钮位置,但按钮点击的实际位置仍未改变。在代码中定义动画,可以参考AnimationSet类和Animation的子类;而如果使用XML,可以在res/anim/文件夹中定义XML文件。
Drawable Animation(帧动画):
加载一系列Drawable资源来创建动画,这种传统动画某种程度上就是创建不同图片序列,顺序播放,就像电影胶片。在代码中定义动画帧,使用AnimationDrawable类;XML文件能更简单的组成动画帧,在res/drawable文件夹,使用采用来定义不同的帧。感觉只能设置的属性是动画间隔时间。
Property Animation(属性动画):
动画的对象除了传统的View对象,还可以是Object对象,动画之后,Object对象的属性值被实实在在的改变了。Property animation能够通过改变View对象的实际属性来实现View动画。任何时候View属性的改变,View能自动调用invalidate()来试试刷新。
参考博客:
1. Android应用开发之所有动画使用详解 - 工匠若水 - 博客频道 - CSDN.NET
2. Android属性动画完全解析(上),初识属性动画的基本用法 - 郭霖的专栏 - 博客频道 - CSDN.NET
3. Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法 - 郭霖的专栏 - 博客频道 - CSDN.NET
4. Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法 - 郭霖的专栏 - 博客频道 - CSDN.NET
5.
源码下载:simplebam/custom_view
* 广告条效果
- 用到的控件:ViewPager
- ViewPager详解(一)简单介绍和使用 - 简书
- ViewPager详解(二)广告轮播图 - 简书
- Android之——史上最简单图片轮播广告效果实现 - 博客频道 - CSDN.NET
- 自己造轮子–一款实用的Android广告栏实现过程(一) - 简书
- 最终效果
- Android自定义带动画无限自动轮播的Banner控件 - 简书
- 可以考虑的第三方开源库:
- Android-ConvenientBanner: 通用的广告栏控件,让你轻松实现广告头效果。
- 首页垂直滚动TextView广告效果,使用TextSwicher+animation实现 - 门徒07的博客 - 博客频道 - CSDN.NET
- 更好的实现:
- Android之——自定义下拉菜单的实现 - 刘亚壮的专栏 - 博客频道 - CSDN.NET
- Android 自定义View修炼-如何打造Android自定义的下拉列表框控件 - Jamy Cai - 博客园
- 一个视图从创建到显示过程中的主要方法
- 1.构造方法实例化类
- 2.测量-measure(int,int)–>onMeasure();
如果当前View是一个ViewGroup,还有义务测量孩子
孩子有建议权- 3.指定位置-layout()–>onLayout();
指定控件的位置,一般View不用写这个方法,ViewGroup的时候才需要,一般View不需要重写该方法- 4.绘制视图–draw()–>onDraw(canvas)
根据上面两个方法参数,进入绘制
参考博客:
- Android自定义控件系列二:自定义开关按钮(一) - 苦咖啡的自留地 - 博客频道 - CSDN.NET
- Android自定义控件系列三:自定义开关按钮(二) - 苦咖啡的自留地 - 博客频道 - CSDN.NET
参考博客:
1. Android5.0水波纹效果ripple实现 - wansho - 博客园
2. Android 自定义view实现水波纹效果 - 享受技术带来的快乐 - 博客频道 - CSDN.NET
3. Android 水波纹点击效果(Ripple Effect) - wingyip - 博客园
4. Android L中水波纹点击效果的实现 - 任玉刚 - 博客频道 - CSDN.NET
自定义属性
引用博客:
- Android自定义View(二、深入解析自定义属性) - openXu的专栏 - 博客频道 - CSDN.NET
- Android 自定义VIEW属性用法详解(attrs、TypedArray)_Windows Phone_IThao123
- Android:自定义控件 — 自定义属性 枚举值(固定属性值) - 博客频道 - CSDN.NET
- Android 中 Bitmap 和 Drawable 相互转换的方法 - 哦? - 博客频道 - CSDN.NET
面试题:Android Bitmap 和 BitmapDrawable的区别
参考博客:
- android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明 - 未来之路 的专栏 - 博客频道 - CSDN.NET
- 实现3D翻转效果的仿ViewPager - KevinsCSDN的博客 - 博客频道 - CSDN.NET
- 让你的动画不再生硬 Android插值器Interpolator使用秘籍 - 旋转 跳跃 然后 团灭 - 博客频道 - CSDN.NET
- android动画插值器Interpolator使用demo - 下载频道 - CSDN.NET
- 插补器Interpolator配图详解 - pengkv的专栏 - 博客频道 - CSDN.NET
- Android-通过自定义ViewPager来高仿土巴兔选择装修风格效果(中间放大效果) - 泡在网上的日子
- Android 自定义View修炼-自定义HorizontalScrollView视图实现仿ViewPager效果 - Jamy Cai - 博客园
- Android开发-自定义View-AndroidStudio(十三)仿ViewPager(3) - iwanghang(一个播音与主持艺术专业、干过网游打金工作室,做过海鲜小吃排挡的新手程序员) - 博客频道 - CSDN.NET
关于自定义ViewGroup的问题
1. Android自定义View(三、深入解析控件测量onMeasure) - openXu的专栏 - 博客频道 - CSDN.NET
2.自定义View 1:关于View,ViewGroup的测量和绘制流程 - Android开发社区 | CTOLib码库
3.Activtiy完全解析(三、View的显示过程measure、layout、draw) - openXu的专栏 - 博客频道 - CSDN.NET
参考博客:
- Android 联系人列表界面(仿iphone、A~Z字母排列、过滤搜索) - 白雨-博客 - 博客频道 - CSDN.NET
- Android自定义View——实现联系人列表字母索引 - 阿钟的博客 - 博客频道 - CSDN.NET
- android中getWidth()和getMeasuredWidth()之间的区别 - 豌豆豆 - 博客园
- 发现一个写法更简洁的实现方式-gjiazhe/WaveSideBar: An Index Side Bar With Wave Effect
- 更为绚丽的联系人列表-kongnanlive/bubble-scroll: An animating scroll bar
参考博客:
1. 【android自定义控件】android ListView添加侧滑删除 - ___leng的专栏 - 博客频道 - CSDN.NET
更为优秀的做法:
1. ListView 侧滑菜单的实现 – 大道至简的SwipeMenuLayout - 简书
2. Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 - Hongyang - 博客频道 - CSDN.NET
3. RecyclerView侧滑菜单,滑动删除,长按拖拽,下拉刷新上拉加载 - 严振杰 - 博客频道 - CSDN.NET
- 教你10行代码写侧滑菜单-黑马程序员IT技术论坛 - 黑马程序员快速入学必看论坛
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 - Hongyang - 博客频道 - CSDN.NET
以当前控件左上方原点坐标,getX()距离X轴上的距离,getY()距离Y轴上的距离
MotionEvent.getX();
MotionEvent.getY();
以屏幕左上方原点坐标,getRawX()距离x轴心上的距离,getRawY()距离Y轴上的距离
MotionEvent.getRawX();
MotionEvent.getRawY();
- 图解MotionEvent中getRawX、getRawY与getX、getY以及View中的getScrollX、getScrollY - 残阳破晓 - 博客园
- 图解Android View的scrollTo(),scrollBy(),getScrollX(), getScrollY() - bigconvience的专栏 - 博客频道 - CSDN.NET
- Android中View中的scrollTo(),scrollBy(),getScrollX(), getScrollY()详解 - 博客频道 - CSDN.NET
- Android getScrollX()详解 - znouy的博客 - 博客频道 - CSDN.NET
个人小理解:
1.getScrollX() 就是当前view的左上角相对于母视图的左上角的X轴偏移量
如果是从左到右移动得到的值是负数,负数代表内容距离左边的偏移量;从右到左移动是正值
比如button里面的内容对于button而言的偏移量
...>
...>
幽默解析版:比如Button里面的内容text移动了,但对于Button的老爸LinearLayout以及爷爷RelativeLayout(一般都是爷爷管爸爸,爸爸管儿子的,所以这里不谈RelativeLayout),老爸LinearLayout从看到儿子Button位置没有改变,就认为他没事(此时Button的getScrollX()的偏移量是0),但是Button看到自己的内容text位置改变了,他认为text有事(此时text的getScrollX()的偏移量不是0了)
整体局部版:把Button当做一个整体,从Button外部看,Button的位置的确没有改变,至于他内部怎么改变(比如他内容text位置改变了),那是他自己的事情,所以Button的getScrollX是0;但仅仅看Button的时候,它内部的text的确位置改变了,那么text的getScrollX不是0(重点理解这句话:getScrollX() 就是当前view的左上角相对于母视图的左上角的X轴偏移量,其实就是一个位移值)
PS:儿子的位置是由父亲作为坐标系确定的
- 图解Android View的scrollTo(),scrollBy(),getScrollX(), getScrollY() - bigconvience的专栏 - 博客频道 - CSDN.NET
- android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明 - 未来之路 的专栏 - 博客频道 - CSDN.NET
/**
* Call this when you want to know the new location. If it returns true,
* the animation is not yet finished.
*/
public boolean computeScrollOffset() {
if (mFinished) {
return false;
}