当前位置: 首页 > article >正文

Android:自定义控件

3.16自定义控件

1.自定义VIEW组件

创建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

http://www.kler.cn/news/233287.html

相关文章:

  • Vue 封装的 axios 类的使用(小bug 改进)
  • 5G技术对物联网的影响
  • C# BackgroundWorker的使用
  • 广义表-C语言
  • 面向工业 X.0 的工业网络简述
  • 微软.NET6开发的C#特性——类、结构体和联合体
  • VitePress-12-markdown中使用vue的语法
  • 年货大数据(电商平台年货节数据):水果销售额增长72%,海鲜肉类涨幅高于蔬菜
  • Stable Diffusion 模型下载:Disney Pixar Cartoon Type A(迪士尼皮克斯动画片A类)
  • React 常用 Hooks
  • 探索Gin框架:Golang Gin框架请求参数的获取
  • 【Web】基于Mybatis的SQL注入漏洞利用点学习笔记
  • 图书商城系统
  • 机器学习系列——(二十二)结语
  • Windows下搭建Redis Sentinel
  • 低代码流程引擎在数字设计平台的应用:简化创作流程,提升生产效率
  • CSS高级技巧
  • 使用python-numpy实现一个简单神经网络
  • [疑难杂症2024-001] java多线程运行时遇到java.util.ConcurrentModificationException的解决方案
  • 如何从 Windows 硬盘恢复丢失或删除的照片
  • 网课:[NOIP2017]奶酪——牛客(疑问)
  • 无人机图像识别技术研究及应用,无人机AI算法技术理论,无人机飞行控制识别算法详解
  • uTools工具使用
  • ChatGPT升级版本GPT-4V(ision)支持多模态语音和图像
  • uni-app 经验分享,从入门到离职(年度实战总结:经验篇)——上传图片以及小程序隐私保护指引设置
  • [Java][算法 双指针]Day 02---LeetCode 热题 100---04~07
  • [word] word中怎么插入另外一个word文档 #媒体#职场发展
  • 【技巧】PCB布局技巧:带条纹的电容
  • 1041.困于环中的机器人(Java)
  • spring上下文简单用法