自定义View (Android群英传)

来源:互联网 发布:单级放大电路实验数据 编辑:程序博客网 时间:2024/05/22 00:28

1.

   一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。

   一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定),父元素不对子元素施加任何束缚,
  子元素可以得到任意想要的大小;EXACTLY(完全),父元素决定自元素的确切大小,

   子元素将被限定在给定的边界里而忽略它本身大小;AT_MOST(至多),子元素至多达到指定大小的值


2.

   onMeasure()函数由包含这个View的具体的ViewGroup调用,因此值也是从这个ViewGroup中传入的。
  这里我直接给出答案:子类View的这两个参数,由ViewGroup中的layout_width,layout_height
  和padding以及View自身的layout_margin共同决定。权值weight也是尤其需要考虑的因素,
  有它的存在情况可能会稍微复杂点


3. 如果该View还需要使用wrap_content属性,那么还必须重写onMeasure()方法


4.

   系统帮我们测量的高度和宽度都是MATCH_PARNET,当我们设置明确的宽度和高度时,系统帮我们测量的结果就是我们设置的结    果,当我们设置为WRAP_CONTENT,或者MATCH_PARENT系统帮我们测量的结果就是MATCH_PARENT的长度。
   所以,当设置了WRAP_CONTENT时,我们需要自己进行测量,即重写onMesure方法”:
   重写之前先了解MeasureSpec的specMode,一共三种类型:
   EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
   AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
  UNSPECIFIED:表示子布局想要多大就多大,很少使用


5. 不管是多么复杂、精美的控件都可以被拆分成一个个小的图形单元



6.ViewGroup:

  (1)当ViewGroup的大小为wrap_content时 ,ViewGroup就需提对子View进
     行遍历,以便获得所有子 View 的大小,从而来决定自己的大小。而在其他模式下会通过具
    体的指定值来决定自身的大小。


  (2)如果需要支持wrap_content,只需要对onmeause进行重写




7.View

 1.对现有控件进行拓展
 (1)获取控件大小
 getMeasuredWidth的值是在setMeasuredDimension方法中设置的,
 而getWidth的值是onLayout方法中我们传过去的四个参数
 
 一般情况下getMeasuredWidth和getWidth方法的值是一致的,
 这里只要记住一般情况下除了在onLayout方法中调用getMeasuredWidth方法外其它的地方用getWidth方法就行了。
 
 ①getMeasuredWidth方法获得的值是setMeasuredDimension方法设置的值,它的值在measure方法运行后就会确定
 ②getWidth方法获得是layout方法中传递的四个参数中的mRight-mLeft,它的值是在layout方法运行后确定的
 ③一般情况下在onLayout方法中使用getMeasuredWidth方法,而在除onLayout方法之外的地方用getWidth方法。
 
 (2)使用 getPaint()方法获取当前绘制TextVicw的Paint对象,并给这个Paint
  对象设置原生 TextView 没有的LinearGradient 属性。


 (3)postInvalidate()是重绘的,也就是调用postInvalidate()后系统会重新调用onDraw方法画一次
    invalidate()
postInvalidateDelayed(long i): 定时刷新界面   重绘




2.创建复合控件
  (1)这种方法通常需要继承一个合适的ViewGroup,再给它添加指定功能的控件,从而组合成新的复合控件
  (2)定义接口,暴露接口给调用者  *
  
3.重写View来实现全新的控件
   (1)通常继承View类,并重写它的onDraw(),onMeasure()等方法来实现绘制逻辑,同时通过重写onTouchEvent()
    等触控事件来实现交互逻辑。

   (2)实现动态效果,只要在onDraw()方法中再去调用invalidate()方法通知View进行重绘就可以了,每一次绘制完新
      矩形就通知View进行重绘,这样会因为刷新速度太快反而影响效果,因此,需要进行View的延迟重绘
 postInvalidateDelayed(300);
 

  


 
3.7 自定义VeiwGroup
1.使用遍历的方式来通知子View对自身进行测量,见代码:onMeasure()


2.确定ViewGroup的宽高


3.onlayout


4.onTouchEvent()使ViewGroup可以滑动






3.8 事件拦截机制分析
1.View重写onTouchEvent(),dispatchTouchEvent(),
  ViewGroup重写onlnterceptTouchEvent(),onTouchEvent(),dispatchTouchEvent()
  
2.事件处理者都是执行onTouchEvcnt()方法。
  事件传递的返回值非常容易理解: True,拦截,不继续; False,不拦截,继续流程。
  事件处理的返回值也类似: True,处理,不用审核了; False,给上级处理。
  
  





4.绘制2图形
1.DrawPoint 绘制点
2.DrawLine 绘制直线
3.DrawLines 绘制多条直线
4.DrawRect 绘制矩形
5.DrawRoundRect 绘制圆角矩形
6.DrawCircle 绘制圆
7.DrawArc 绘制弧形,扇形
8.DrawOval 绘制椭圆
9.DrawText 绘制文本
10.DrawPath 绘制路径















1.将画笔移动到原点
  //画笔平移到指定paddingLeft,getHeight()/2位置,注意以后坐标都为以此为(0,0)  
  canvas.translate(getPaddingLeft(), getHeight() / 2);
  
  


  getMeasuredHeight()返回的是原始测量高度,与屏幕无关,getHeight()返回的是在屏幕上显示的高度。
  实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当view超出屏幕后,才能看出他们的区别。
  当超出屏幕后,getMeasuredHeight()等于getHeight()加上屏幕之外没有显示的高度


2.realWidth = getMeasuredWidth() - getPaddingLeft()-getPaddingRight();    //获取真正的高度


3.//计算出默认的高度------------------测量:onMeasure()
 result =(int)(getPaddingTop()+getPaddingBottom()+Math.max(Math.max(mReachedProgressBarHeight,
                              mUnReachedProgressBarHeight), Math.abs(textHeight))); 

0 0
原创粉丝点击