自定义View入门——NO.1

自定义View实例

学习自定义TextView,熟悉流程。

晓注意:
系统有的属性,我们不能重新定义,比如TextViewbackground.
sp2px:TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,sp,getResources().getDisplayMetrics());

自定义View基线计算

基线的计算方式:

	top是个负值,bottom是个正值   baseline到文字顶部或底部的距离
    Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
    int dy = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
    int baseLine = getHeight/2 +dy;

基线示意图

源码课堂:
Q:如果自定义View继承LinearLayout,还能出效果吗?
A:画的方法其实是draw(Canvas canvas)
if(!dirtyOpaque) onDraw(canvas)
dispatchDraw(canvas)
dirtyOpaquefalse时,才会出现。 其实dirtyOpaquemPrivateFlags决定。
mPrivateFlags是在View的构造函数中调用computeOpaqueFlags方法赋值
参考链接:https://www.jianshu.com/p/473185d29218
S:自定义View中实现dispatchDraw方法;
可以设置一个透明背景(前提是没有使用background)
在构造方法中调用setWillNotDraw(false);

自定义View课堂

源码课堂1:
为什么要调用invalidate()源码分析?
1>invalidateInternal();
2>ViewParent p = mParent; p.invalidateChild(this,damage);
3>进入ViewGroup类,搜索invalidateChild方法,此时ViewParentViewGroup
4>parent = parent.invalidateChildInParent(location,dirty);
…测量,布局,绘制等方法…
最后,调用mView.draw(canvas);该方法中调用onDraw(canvas),dispatchDraw(canvas)等
源码课堂2:
为什么子线程不能更新UI?
获取到请求结果后,开启线程,更新UI,一般会调用setText(),setImageView()等,此时都会调用ViewRootImpl中的checkThread(),用来检测线程if(mThread != Thread.currentThread())。其中Thread.currentThread()是子线程,mThead在构造函数中通过Thread.currentThead来初始化(可以认为是主线程),不是同一个线程。

自定义View过度渲染

为什么会出现过度渲染?
获取数据后,调用setText(),setImageView()会调用invalidate(),牵扯到过多的布局。

如何像Wx朋友圈一样优化过度渲染?
首先,打开手机开发者选项中的调试GPU过度绘制,红色代表过度绘制。
1.网上的解决方案
尽量不要嵌套
不要设置背景
2.最好的解决方案
不管是文字还是图片,自己去画,不要用系统的嵌套布局。这样运行效率高,但实现功能的效率低,需要公司以及个人去抉择。

备注:第二篇笔记,参考辉哥视频。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值