1.Android中实现view的更新?
2.重新绘制某个View,或绘制整个layout?
> View.add(); View.remove(); View.update()
动态添加和删除View,然后会走onMeasure(),onLayout(),onDraw()哪些方法?
> 适配器adapter的notifyDataSetChanged和notifyDataSetInvalidated的区别:
notifyDataSetInvalidated(),会重绘整个控件(还原到初始状态);
notifyDataSetChanged(),重绘当前可见区域。
> Android中绘图时渐变着色需要使用android.graphics.Shader类,该类有几个子类:
LinearGradient 线性梯度渐变;
RadialGradient 环形梯度渐变或者灯光渲染;
SweepGradient 扫描梯度渐变;
BitmapShader 图片渲染;
ComposeShader 组合渲染;
> requestLayout() invalidate()和postInvalidate()
invalidate()和postInvalidate()的使用与区别- http://blog.csdn.net/molu_chase/article/details/52572796
Android视图状态及重绘流程分析,带你一步步深入了解View(三)- http://blog.csdn.net/guolin_blog/article/details/17045157
Invalidate和postInvalidate,android界面刷新- http://blog.csdn.net/vincent_czz/article/details/7018725
requestLayout()方法会调用measure过程和layout过程,不会调用draw过程,也不会重新绘制任何View包括该调用者本身。
- View#invalidate()和View#requestLayout()
View#invalidate()-》 onDraw;
View#requestLayout()-》View#onMeasure()、View#onLayout()、View#onDraw()
invalidate()方法只会执行performDraw()方法;而requestLayout()方法会执行performMeasure()、performLayout()、performDraw()。在对应的应用场景,如果只是View的显示内容发生变化且不改变View的大小和位置,则使用invalidate(),如果大小、位置、内容都发生改变则调用requestLayout()。
View.requestLayout(),请求重新布局,重新调用onMeasure(),onLayout(),onDraw()(不一定调用onDraw);
View.invalidate(),刷新视图,相当于调用onDraw(),调用onDraw方法,View本身调用迫使view重画;
1.requestLayout()
To initiate a layout, call requestLayout(). This method is typically called by a view on itself when it believes that it can no longer fit within its current bounds.—当View的边界,也可以理解为View的宽高,发生了变化,不再适合现在的区域,可以调用requestLayout方法重新对View布局。
View执行requestLayout方法,会向上递归到顶级父View中,再执行这个顶级父View的requestLayout,所以其他View的onMeasure,onLayout也可能会被调用。
调用invalidate方法只会执行onDraw方法;调用requestLayout方法只会执行onMeasure方法和onLayout方法,并不会执行onDraw方法。
当我们进行View更新时,若仅View的显示内容发生改变且新显示内容不影响View的大小、位置,则只需调用invalidate方法;若View宽高、位置发生改变且显示内容不变,只需调用requestLayout方法;若两者均发生改变,则需调用两者,按照View的绘制流程,推荐先调用requestLayout方法再调用invalidate方法。
如果你希望视图的绘制流程可以完完整整地重新走一遍,就不能使用invalidate()方法,而应该调用requestLayout()了。
当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view(父类的视图)重新调用他的onMeasure、onLayout来重新设置自己位置。特别是当view的layoutParameter发生改变,并且它的值还没能应用到view上时,这时候适合调用这个方法。
2.invalidate(),在主线程中更新UI
UI线程自身中使用,利用invalidate()刷新界面,实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中通过sendMessage发送界面更新消息。invalidate()方法虽然最终会调用到performTraversals()方法中,但这时measure和layout流程是不会重新执行的,因为视图没有强制重新测量的标志位,而且大小也没有发生过变化,所以这时只有draw流程可以得到执行。
View有两个很重要的方法:invalidate和requestLayout,常用于View重绘和更新。
Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
可以使用invalidate()去更新控件,如ImageView.invalidate() 实时绘制控件和动态更新控件.
To farce a view to draw,call invalidate().-invalidate方法会执行draw过程,重绘View树。
View(非容器类)调用invalidate方法只会重绘自身,ViewGroup调用则会重绘整个View树。
View的重绘,在Activity1中 使用invalidate()方法来重绘, 然后我跳到了Activity2这时候Activity1已经finash()掉 可是Activity1中 的invalidate() 的线程还在程序中,Android的虚拟机不可能主动杀死正在运行中的线程所以这样操作是非常危险的。因为它是在UI线程中被动掉用的所以很不安全。
invalidate() 更新整个屏幕区域
invalidate(Rect rect) 更新Rect区域
invalidate(l, t, r, b) 更新指定矩形区域
3.postInvalidate(),在子线程中更新UI
在非UI线程中使用(工作者线程中被调用)。使用postInvalidate()方法来刷新屏幕,调用后它会用handler通知UI线程重绘屏幕。
postInvalidate(left, top, right, bottom) 方法 通过UI线程来刷新规定矩形区域。
-- UI刷新重绘 :invalidate() 、postInvalidate()、requestLayout() 总结:
① invalidate() :
请求重绘View树,即draw()过程。把例子中他是整个刷新着UI,并且从头到尾并不会触发onMeasure()方法(控制大小用)。如果是View就重绘View;如果是ViewGroup就全部重绘。(Android在 onDraw 事件处理绘图,而 invalidate() 函数可以再一次触发onDraw事件,然后再一次进行绘图动作)
一般引起invalidate()操作的函数如下:
1、直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身。
2、setSelection()方法 :请求重新draw(),但只会绘制调用者本身。
3、setVisibility()方法 : 当View可视状态在INVISIBLE转换VISIBLE时,会间接调用invalidate()方法,继而绘制该View。
4、setEnabled()方法 : 请求重新draw(),但不会重新绘制任何视图包括该调用者本身。
②postInvalidate(); 与invalidate()方法区别就是,postInvalidate()方法可以在UI线程执行,也可以在工作线程执行
而invalidate()只能在UI线程操作。但是从重绘速率讲:invalidate()效率高。
③ requestLayout()
他跟invalidate()相反,requestLayout()只调用measure()和layout()过程,不会调用draw()。
不会重新绘制任何视图包括该调用者本身。
④局部刷新
使用 requestFocus()方法,他只刷新你要刷新的地方。
他是让我们的某一部分获取焦点,获取焦点的会导致view的重绘。