android
2019-04-28 14:40:05 0 举报
AI智能生成
android的一些常用知识点。
作者其他创作
大纲/内容
5.0高新技术
RecycleView
缓存机制
RecycleView滑动场景下的回收复用
<span style="caret-color: rgb(62, 62, 62); color: rgb(62, 62, 62); font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;">mCachedViews </span><br>
默认大小为2
<span style="caret-color: rgb(62, 62, 62); color: rgb(62, 62, 62); font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;"> RecyclerViewPool</span><br>
默认大小为5
回收:<span style="caret-color: rgb(62, 62, 62); color: rgb(62, 62, 62); font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;">mCachedViews 优先级高于 RecyclerViewPool,最新的 ViewHolder 都是往 mCachedViews 里放,如果它满了,那就移出一个扔到 ViewPool 里好空出位置来缓存最新的 ViewHolder。</span>
复用:<span style="caret-color: rgb(62, 62, 62); color: rgb(62, 62, 62); font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;">也是先到 mCachedViews 里找 ViewHolder,但需要各种匹配条件,概括一下就是只有原来位置的卡位可以复用存在 mCachedViews 里的 ViewHolder,如果 mCachedViews 里没有,那么才去 ViewPool 里找。</span>
view
基础知识
ViewRoot和DecorView
ViewRoot是连接WindowManager和DecorView的纽带,view的三大流程是通过ViewRoot完成的
View绘制流程从ViewRoot的performTraversals方法开始
measure
获取View测量后的宽高 获取方法:getMeasuredWidth、getMeasuredHeight
MeasureSpec和LayoutParams对应关系
对于DecorView,MeasureSpec由窗口尺寸和其自身的LayoutParams决定
对于普通View,MeasureSpec由父容器的MeasureSpec和其自身LayoutParams共同决定
系统内部通过MeasureSpec进行View测量,它一旦确定后,onMeasure便可确定View的测量宽高
measure过程
View的measure过程
直接继承View的自定义控件需要重写onMeasure并设置wrap_content时的大小,否则布局中使用wrap相当于使用match_parent
ViewGroup的measure过程
获取View的测量宽高
(1)Activity/View#onWindowFocusChanged
注:它会被调用多次,在Activity窗口得到/失去焦点时均会被调用一次
(2)view.post(runable)
(3)ViewTreeObserver
(4)view.measure(widthMeasureSpec,heightMeasureSpec)
layout
决定View四个顶点的坐标 获取方法:getTop、getBottom、getLeft、getRight
决定View实际宽高 获取方法:getWidth、getHeight
layout过程
父元素在layout过程中通过setFrame完成自己的定位后,就通过onLayout调用子元素的layout方法,子元素又回通过自己的layout方法来确定自己的位置
onLayout具体实现和具体布局有关,View和ViewGroup均没有真正实现onLayout方法
draw
决定View显示
绘制先后顺序
绘制背景(background.draw)
绘制自己(onDraw)
绘制children(dispatchDraw)
绘制装饰(onDrawScrollBars)
ViewGroup会默认调用setWillNotDraw方法进行优化,即不调用onDraw
view滑动
滑动实现
使用动画
使用scrollTo/scrollBy
改变布局参数
滑动冲突
类型:
(1)水平滑+竖直滑
(2)水平+水平/竖直+竖直
(3)(1)+(2)
解决:
解决方法
外部拦截法
点击事件都先经过父容器的拦截处理,若父容器需要,则拦截,否则不拦截
实现:
重写父容器onInterceptTouchEvent方法
ACTION_DOWN和ACTION_UP必须返回false
ACTION_MOVE根据需要来决定是否拦截,若父容器需要拦截就返回true,否则返回false
内部拦截法
父容器不拦截任何事件,所有事件都传递给子元素,若子元素需要,则拦截,否则不拦截
实现:
(1)重写子元素的dispatchTouchEvent方法
ACTION_DOWN 中调用parent.requestDisallowInterceptTouchEvent(true)方法(即父元素无法拦截除ACTION_DOWN以外的其他事件)
ACTION_MOVE 中进行判断 若父容器需要此点击事件则调用parent.requestionDisallowInterceptTouchEvent(false)方法
(2)重写父元素onInterceptTouchEvent方法(让父元素默认拦截除ACTION_DOWN以外的事件)
ACTION_DOWN返回flase,其他返回true
针对具体类型进行解决
类型(1)
根据水平滑还是竖直滑来判断由谁拦截
滑动方向的判断
滑动路径与水平方向夹脚
水平、竖直方向的距离/速度差
类型(2)(3)
根据业务找突破点
事件分发
其他
layoutParams理解
<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: Verdana, Arial, Helvetica, sans-serif;">可以这样去形容LayoutParams,在象棋的棋盘上,每个棋子都占据一个位置,也就是每个棋子都有一个位置的信息,如这个棋子在4行4列,这里的“4行4列”就是棋子的LayoutParams。</span><br>
e g:<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; white-space: pre-wrap; background-color: rgb(245, 245, 245);">FrameLayout.LayoutParams lytp = new FrameLayout.LayoutParams(80,LayoutParams.WRAP_CONTENT);</span><pre style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-size: 12px; background-color: rgb(245, 245, 245); font-family: "Courier New" !important;">lytp .gravity = Gravity.CENTER;<br>btn.setLayoutParams(lytp);</pre>
0 条评论
下一页