赞
踩
创建CustomizeView,继承View。重写onDraw方法,通过onDraw方法绘制我们自定义的图像、位图、路径等。
示例:
- //自定义绘制View
- public class CutomizeView extends View {
- //构造方法
- public CutomizeView(Context context) {
- super(context);
- }
- //构造方法,这个构造必须有
- public CutomizeView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- //重新onDraw方法
- @Override
- protected void onDraw(Canvas canvas) {
- //矩形位置坐标
- RectF rectF=new RectF(100,100,400,400);
- //画笔
- Paint paint=new Paint();
- //设置画笔
- //设置反锯齿
- paint.setAntiAlias(true);
- //设置绘制颜色
- paint.setColor(0xFF20FF22);
- //设置绘制样式
- paint.setStyle(Paint.Style.STROKE);
- //设置绘制文本大小
- paint.setTextSize(100);
- //绘制矩形
- canvas.drawRect(rectF,paint);
- //绘制椭圆
- canvas.drawOval(rectF,paint);
- //绘制圆
- canvas.drawCircle(300,300,200,paint);
- //绘制线段
- canvas.drawLine(0,0,100,100,paint);
- //绘制文本
- canvas.drawText("hello",200,900,paint);
- //绘制圆弧
- canvas.drawArc(rectF,0,100,true,paint);
- //绘制点
- canvas.drawPoint(800,800,paint);
- //绘制图片
- //bitmap位图,1、将项目已有图片转为bitmap
- Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
- canvas.drawBitmap(bitmap,200,1000,paint);
- //2.创建一个bitmap
- //Bitmap bitmap1=Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
- //绘制路径
- drawPath(canvas);
- }
- //绘制路径
- public void drawPath(Canvas canvas){
- Paint paint=new Paint();
- paint.setColor(0xFF0022FF);
- paint.setStyle(Paint.Style.STROKE);
- //绘制路径
- Path path=new Path();
- //起点
- path.moveTo(300,400);
- //直线
- path.lineTo(500,200);
- path.lineTo(550,350);
- path.lineTo(800,700);
- //曲线
- path.quadTo(500,300,300,800);
- canvas.drawPath(path,paint);
- }
- }
创建对应layout文件,l_customize1.xml文件
示例:
- <?xml version="1.0" encoding="utf-8"?>
-
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:orientation="vertical" android:layout_width="match_parent"
-
- android:layout_height="match_parent">
-
- <com.example.pro_customizeview.view.CutomizeView
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content">
-
- </com.example.pro_customizeview.view.CutomizeView>
-
- </LinearLayout>
补充:Canvas对象坐标变换方法
translate(100,100):平移变化;
rotate(90):旋转变化;
scale():缩放变化;
save():保存当前坐标系;
restore():销毁当前坐标系,返回上一次坐标系;
自定义属性:
在res/values/attrs.xml中创建我们自定义组件属性。
示例:
定义属性名和属性需要数据格式类型
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <declare-styleable name="CutomizeView">
- <attr name="fontColor" format="color"></attr>
- <attr name="fontSize" format="dimension"></attr>
- </declare-styleable>
- </resources>
修改l_customize1.xml文件,设置自定义属性。
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:zdy="http://schemas.android.com/apk/res-auto"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <com.example.pro_customizeview.view.CutomizeView
- zdy:fontSize="20dp"
- zdy:fontColor="@color/colorPrimary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>
在自定义组件CutomizeView中构造函数中获取到我们自定义的属性,然后可以在onDraw,onMeasure,onLayout方法中使用。
- //构造方法,这个构造必须有
- public CutomizeView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- //所有的属性存放在AttributeSet中
- int count = attrs.getAttributeCount();
- //1、遍历获取
- for(int i=0;i<count;i++){
- //获取属性名
- String attrName=attrs.getAttributeName(i);
- //获取属性值
- String attrValue=attrs.getAttributeValue(i);
- }
- //2、直接获取到自定义属性
- //在R文件中会自动生成
- TypedArray typedArray= context.obtainStyledAttributes(attrs,R.styleable.CutomizeView);
- //将获取到的属性可以在onDraw,onMesure,onLayout中使用。
- int fontColor=typedArray.getColor(R.styleable.CutomizeView_fontColor,0xFF0022FF);
- float fontSize=typedArray.getDimension(R.styleable.CutomizeView_fontSize,20);
- //注意使用完释放资源
- typedArray.recycle();
- }
onMeasure方法和onLayout方法。
示例:
- //测量方法,获取控件宽高,模式
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- //调用父类onMeasure方法,实际注释掉
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- //1、获取mode和size
- int widthMode=MeasureSpec.getMode(widthMeasureSpec);
- int widthSize=MeasureSpec.getSize(widthMeasureSpec);
- int heightMode=MeasureSpec.getMode(heightMeasureSpec);
- int heightSize=MeasureSpec.getSize(heightMeasureSpec);
-
-
- //当父控件为viewgroup时,要获取子控件宽高,必须先测量一次,强制测量
-
- //否则childView的getMeasuredWidth拿不到宽度
-
- measureChildren(widthMeasureSpec,heightMeasureSpec);
-
-
- //2、通过mode设置合理size
- switch (widthMode){
- //父控件对子控件限制最大值,wrap_content
- case MeasureSpec.AT_MOST:
- //宽度设置,
-
- widthSize = 100dp ;
- break;
- //控件大小是个确定值,100dp,match_parent(父控件大小确定)等
- case MeasureSpec.EXACTLY:
- break;
- //父控件对子控件大小不做限定
- case MeasureSpec.UNSPECIFIED:
- break;
- }
- switch (heightMode){
- //父控件对控件限制最大值,wrap_content
- case MeasureSpec.AT_MOST:
- //宽度设置,
- break;
- //控件大小是个确定值,layout中设置为具体20dp等或者match_parent,父控件大小确定
- case MeasureSpec.EXACTLY:
- break;
- //父控件对控件大小不做限定,例如:ListView中子item数量不定
- case MeasureSpec.UNSPECIFIED:
- br
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。