@@ -93,26 +93,26 @@ public static int makeMeasureSpec(int size, int mode) {
9393那我们如何从MeasureSpec值中提取模式和大小呢?该方法内部是采用位移计算.
9494``` java
9595/**
96- * Extracts the mode from the supplied measure specification.
97- *
98- * @param measureSpec the measure specification to extract the mode from
99- * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
100- * {@link android.view.View.MeasureSpec#AT_MOST} or
101- * {@link android.view.View.MeasureSpec#EXACTLY}
102- */
103- public static int getMode(int measureSpec) {
104- return (measureSpec & MODE_MASK );
105- }
96+ * Extracts the mode from the supplied measure specification.
97+ *
98+ * @param measureSpec the measure specification to extract the mode from
99+ * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
100+ * {@link android.view.View.MeasureSpec#AT_MOST} or
101+ * {@link android.view.View.MeasureSpec#EXACTLY}
102+ */
103+ public static int getMode(int measureSpec) {
104+ return (measureSpec & MODE_MASK );
105+ }
106106
107- /**
108- * Extracts the size from the supplied measure specification.
109- *
110- * @param measureSpec the measure specification to extract the size from
111- * @return the size in pixels defined in the supplied measure specification
112- */
113- public static int getSize(int measureSpec) {
114- return (measureSpec & ~ MODE_MASK );
115- }
107+ /**
108+ * Extracts the size from the supplied measure specification.
109+ *
110+ * @param measureSpec the measure specification to extract the size from
111+ * @return the size in pixels defined in the supplied measure specification
112+ */
113+ public static int getSize(int measureSpec) {
114+ return (measureSpec & ~ MODE_MASK );
115+ }
116116```
117117
118118
@@ -127,17 +127,17 @@ public static int makeMeasureSpec(int size, int mode) {
127127
128128``` java
129129// Account for padding
130- float xpad = (float )(getPaddingLeft() + getPaddingRight());
131- float ypad = (float )(getPaddingTop() + getPaddingBottom());
130+ float xpad = (float )(getPaddingLeft() + getPaddingRight());
131+ float ypad = (float )(getPaddingTop() + getPaddingBottom());
132132
133- // Account for the label
134- if (mShowText) xpad += mTextWidth;
133+ // Account for the label
134+ if (mShowText) xpad += mTextWidth;
135135
136- float ww = (float )w - xpad;
137- float hh = (float )h - ypad;
136+ float ww = (float )w - xpad;
137+ float hh = (float )h - ypad;
138138
139- // Figure out how big we can make the pie.
140- float diameter = Math . min(ww, hh);
139+ // Figure out how big we can make the pie.
140+ float diameter = Math . min(ww, hh);
141141```
142142
143143
@@ -158,6 +158,48 @@ public static int makeMeasureSpec(int size, int mode) {
158158- 绘制什么,由` Canvas ` 处理。
159159- 怎么去绘制,由` Paint ` 处理。
160160
161+
162+ #####` Canvas `
163+
164+ > The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels,
165+ a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap),
166+ and a paint (to describe the colors and styles for the drawing).
167+
168+
169+ - ` Canvas() ` :创建一个空的画布,可以使用` setBitmap() ` 方法来设置绘制的具体画布;
170+ - ` Canvas(Bitmap bitmap) ` :以` bitmap ` 对象创建一个画布,则将内容都绘制在` bitmap ` 上,` bitmap ` 不得为` null ` ;
171+ - ` canvas.drawRect(RectF,Paint) ` 方法用于画矩形,第一个参数为图形显示区域,第二个参数为画笔,设置好图形显示区域` Rect ` 和画笔` Paint ` 后,即可画图;
172+ - ` canvas.drawRoundRect(RectF, float, float, Paint) ` 方法用于画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。
173+ - ` canvas.drawLine(startX, startY, stopX, stopY, paint) ` :前四个参数的类型均为` float ` ,最后一个参数类型为` Paint ` 。表示用画笔` paint ` 从点` (startX,startY) ` 到点` (stopX,stopY) ` 画一条直线;
174+ - ` canvas.drawLines (float[] pts, Paint paint)``pts ` :是点的集合,大家下面可以看到,这里不是形成连接线,而是每两个点形成一条直线,` pts ` 的组织方式为` {x1,y1,x2,y2,x3,y3,……} ` ,例如` float []pts={10,10,100,100,200,200,400,400}; ` 就是有四个点:(10,10)、(100,100),(200,200),(400,400)),两两连成一条直线;
175+ - ` canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint) ` :第一个参数` oval ` 为` RectF ` 类型,即圆弧显示区域,` startAngle ` 和` sweepAngle ` 均为` float ` 类型,分别表示圆弧起始角度和圆弧度数,3点钟方向为0度,` useCenter ` 设置是否显示圆心,` boolean ` 类型,` paint ` 为画笔;
176+ - ` canvas.drawCircle(float,float, float, Paint) ` 方法用于画圆,前两个参数代表圆心坐标,第三个参数为圆半径,第四个参数是画笔;
177+ - ` canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) ` 位图,参数一就是我们常规的` Bitmap ` 对象,参数二是源区域(这里是` bitmap ` ),参数三是目标区域(应该在` canvas ` 的位置和大小),参数四是` Paint ` 画刷对象,因为用到了缩放和拉伸的可能,当原始` Rect ` 不等于目标` Rect ` 时性能将会有大幅损失。
178+ - ` canvas.drawText(String text, float x, floaty, Paint paint) ` 渲染文本,` Canvas ` 类除了上
179+ 面的还可以描绘文字,参数一是` String ` 类型的文本,参数二` x ` 轴,参数三` y ` 轴,参数四是` Paint ` 对象。
180+ - ` canvas.drawPath (Path path, Paint paint) ` ,根据` Path ` 去画.
181+ ``` java
182+ Path path = new Path ();
183+ path. moveTo(10 , 10 ); // 设定起始点
184+ path. lineTo(10 , 100 );// 第一条直线的终点,也是第二条直线的起点
185+ path. lineTo(300 , 100 );// 画第二条直线
186+ path. lineTo(500 , 100 );// 第三条直线
187+ path. close();// 闭环
188+ canvas. drawPath(path, paint);
189+ ```
190+
191+ #####`Paint `
192+
193+ - `setARGB(int a, int r, int g, int b)` 设置`Paint `对象颜色,参数一为`alpha`透明值
194+ - `setAlpha(int a)` 设置`alpha`不透明度,范围为0 ~ 255
195+ - `setAntiAlias(boolean aa)`是否抗锯齿
196+ - `setColor(int color)`设置颜色
197+ - `setTextScaleX(float scaleX)`设置文本缩放倍数,1.0f 为原始
198+ - `setTextSize(float textSize)`设置字体大小
199+ - `setUnderlineText(String underlineText)`设置下划线
200+
201+
202+
161203例如,`Canvas `提供了一个画一条线的方法,而`Paint `提供了指定这条线的颜色的方法。`Canvas `提供了绘制长方形的方法,而`Paint `提供了是用颜色填充整个长方形还是空着的方法。简单的说,`Canvas `指定了你想在屏幕上绘制的形状,而`Paint `指定了你要绘制的形状的颜色、样式、字体和样式等等。
162204
163205所以,在你`draw`任何东西之前,你都需要创建一个或者多个`Paint `对象。下面的`PieChart `例子就是在构造函数中调用的`init`方法:
@@ -276,9 +318,9 @@ public class ToogleView extends View {
276318 super . onDraw(canvas);
277319 Paint paint = new Paint ();
278320 paint. setAntiAlias(true );
279- // 先画背景图
321+ // 先画背景图
280322 canvas. drawBitmap(backgroundBitmap, 0 , 0 , paint);
281- // 再画滑块,用mSlideMarginLeft来控制滑块距离左边的距离。
323+ // 再画滑块,用mSlideMarginLeft来控制滑块距离左边的距离。
282324 canvas. drawBitmap(slideButton, mSlideMarginLeft, 0 , paint);
283325 }
284326```
@@ -297,7 +339,7 @@ public class ToogleView extends View {
297339 < / LinearLayout >
298340```
299341
300- ! [image](https:// raw.githubusercontent.com/CharonChui/Pictures/master/toogle_1.png?raw=true)
342+ ! [image](https:// raw.githubusercontent.com/CharonChui/Pictures/master/toogle_1.png?raw=true)
301343很明显显示的不对,因为高设置为`warp_content`了,但是界面显示的确实整个屏幕,而且`paddingLeft`也没生效,那该怎么做呢? 当然是重写`onMeasure ()` 方法:
302344```java
303345public class ToogleView extends View {
@@ -383,18 +425,64 @@ public class ToogleView extends View {
383425这样就可以了。简单的说明一下,就是如果当前的模式是`EXACTLY `那就把父`View `传递进来的宽高设置进来,如果是`AT_MOST `或者`UNSPECIFIED `的话就使用背景图片的宽高。
384426
385427
428+ 最后再来一个自定义`ViewGroup `的例子:
386429
430+ 之前的引导页面都是通过类似`ViewPager `这种方法左右滑动,现在想让他上下滑动,该怎么弄呢?
431+ ```java
432+ public class VerticalLayout extends ViewGroup {
433+ public VerticalLayout (Context context ) {
434+ super (context);
435+ }
436+ public VerticalLayout (Context context , AttributeSet attrs ) {
437+ super (context, attrs);
438+ }
439+
440+ public VerticalLayout (Context context , AttributeSet attrs , int defStyleAttr ) {
441+ super (context, attrs, defStyleAttr);
442+ }
387443
444+ @Override
445+ protected void onLayout (boolean changed , int l , int t , int r , int b ) {
446+
447+ }
448+ }
449+ ```
450+ 继承`ViewGroup `必须要重写`onLayout`方法。其实这也很好理解,因为每个`ViewGroup `的排列方式不一样,所以让子类来自己实现是最好的。
451+ 当然畜类重写`onLayout`之外,也要重写`onMeasure`。
452+ 代码如下,滑动手势处理的部分就不贴了。
453+ ```java
454+ @Override
455+ protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
456+ int measureSpec = MeasureSpec . makeMeasureSpec(mScreenHeight
457+ * getChildCount(), MeasureSpec . getMode(heightMeasureSpec));
458+ super . onMeasure(widthMeasureSpec, measureSpec);
459+ measureChildren(widthMeasureSpec, heightMeasureSpec);
460+ }
461+
462+ @Override
463+ protected void onLayout (boolean changed , int l , int t , int r , int b ) {
464+ // 就像猴子捞月一样,让他们一个个的从上往下排就好了
465+ if (changed) {
466+ int childCount = getChildCount();
467+ for (int i = 0 ; i < childCount; i++ ) {
468+ View child = getChildAt(i);
469+ if (child. getVisibility() != View . GONE ) {
470+ child. layout(l, i * mScreenHeight, r, (i + 1 )
471+ * mScreenHeight);
472+ }
473+ }
474+ }
475+ }
476+ ```
388477
389478
390479
391-
392- http: // blog.csdn.net/cyp331203/article/details/40736027
393480
394- http: // blog.csdn.net/lmj623565791/article/details/24529807
481+ 参考部分:
482+ - http: // blog.csdn.net/cyp331203/article/details/40736027
395483
396484
397485-- -
398486
399487- 邮箱 :charon. chui@gmail . com
400- - Good Luck !
488+ - Good Luck ! I
0 commit comments