D1-从N角星开始论述自定义控件

简介: 零、前言[1].个人对安卓绘制逻辑感到繁琐,自己封装了一个绘图框架[2].自定义控件的绘制流程都基于我的这个库,详见:开源计划之--Android绘图库--LogicCanvas [3].

零、前言

[1].个人对安卓绘制逻辑感到繁琐,自己封装了一个绘图框架
[2].自定义控件的绘制流程都基于我的这个库,详见:开源计划之--Android绘图库--LogicCanvas
[3].星星控件目的:总结自定义控件的流程
[4].功能:自定义星星的角数,高矮,胖瘦,填充与否,


一、准备

1.新建StarView继承自View,重写构造方法

这里为了方便,准备了dp转px的方法
一参数构造用于直接new视图
二参数构造用于支持视图在xml中有效

/**
 * 作者:张风捷特烈<br/>
 * 时间:2018/9/3 0003:19:01<br/>
 * 邮箱:1981462002@qq.com<br/>
 * 说明:星星控件
 */
public class StarView extends View {
   
    public StarView(Context context) {
        this(context, null, 0);
    }

    public StarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    /**
     * 适配dp
     *
     * @param dp
     * @return
     */
    public Float dp2px(Float dp) {
        if (dp != null) {
            final Float scale = getContext().getResources().getDisplayMetrics().density;
            return dp * scale + 0.5f;
        }
        return dp;
    }
}

2.定义属性
/**
 * 星星的角数
 */
private int mAngleNum = 5;
/**
 * 星星高
 */
private float mHeight = dp2px(20f);
/**
 * 星星内接圆直径
 */
private float mr = dp2px(10f);
/**
 * 星星颜色
 */
private int mStarColor = Color.BLUE;
/**
 * 是否填充
 */
private boolean isFill = true;

3.先查看绘制效果:重写onDraw方法

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    ZCanvas zCanvas = new ZCanvas(canvas);
    //设置绘图对象
    Painter painter = new Painter().num(mAngleNum).R(mHeight / 2).r(mr / 2).b(dp2px(1f));
    //判断是否填充
    if (isFill) {
        painter.fs(mStarColor);
    } else {
        painter.ss(mStarColor);
    }
    //绘制图形
    zCanvas.drawNStar(painter);
}
star1.png
2.设置控件属性:先介绍一下自定义属性吧

我们常用的TextView、ImageView等都可以在xml里配置相关属性,就是自定义属性

第一步,明确自己的自定义属性有哪些,最后先想好名字
第二步,在res/values文件夹下创建attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--一个自定义控件-->
    <declare-styleable name="StarView">
        <!--自定义属性名 和 类型-->
        <attr name="z_star_height" format="dimension"/>
        <attr name="z_star_AngleNum" format="integer"/>
        <attr name="z_star_r" format="dimension"/>
        <attr name="z_star_color" format="reference"/>
        <attr name="z_star_isFill" format="boolean"/>
    </declare-styleable>
</resources>

其中:

1、reference 引用类型值 : @id/...
2、color 颜色类型值     #ff00ff
3、boolean 布尔类型值    true , false
4、dimension 尺寸类型值     dp / px /sp
5、integer 整数类型值       weight  progress max
6、float 浮点型值        0.1f
7、string 字符串类型值  "atrrs"
8、<enum> 枚举类型值 :水平/垂直
9、flag:位或运算
10、fraction:百分数
第三步:在自定义View的构造函数里使用
    /**
     * 初始化
     * @param attrs 自定义属性
     */
    private void init(AttributeSet attrs) {
        TypedArray ta = attrs == null ? null : getContext().obtainStyledAttributes(attrs, R.styleable.StarView);
        mAngleNum=ta.getInt(R.styleable.StarView_z_star_AngleNum, mAngleNum);
        mHeight=ta.getDimension(R.styleable.StarView_z_star_height, mHeight);
        mr=ta.getDimension(R.styleable.StarView_z_star_height, mr);
        mStarColor=ta.getColor(R.styleable.StarView_z_star_color, mStarColor);
        isFill = ta.getBoolean(R.styleable.StarView_z_star_isFill, isFill);
        ta.recycle();//一定记得回收!!!
    }
第四步:在xml里使用(为简洁、外层的布局省略):

其中标签头是类全名:com.toly1994.d.view.StarView
xmlns:toly="http://schemas.android.com/apk/res-auto"是名空间
因为我英文名叫toly,可见它的随意性,toly:z_star_AngleNum="6"也是基于此
我习惯自定义属性已z_开头,好找,AndroidStudio自动提示。

    <com.toly1994.d.view.StarView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        xmlns:toly="http://schemas.android.com/apk/res-auto"
        toly:z_star_AngleNum="6"
        toly:z_star_color="#f00"
        toly:z_star_height="40dp"
        toly:z_star_isFill="false"
        toly:z_star_r="20dp"/>
3.Activity中使用:
setContentView(R.layout.activity_star);

一个不同风格的星星跃然纸上


自定义属性.png

二、测量:

现在问题来了:添加背景可以看出控件区域竟然占了全屏,这不是我们想要的。

宽高.png
这时要重写测量方法:onMeasure方法

这个控件的测量很简单:无论什么测量模式,宽高相同并且等于mHeight,
也就是layout_width和layout_height无作用,全靠z_star_height确定布局宽高。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension((int)mHeight,(int) mHeight);
    }

现在你想要多少角星都不是事儿,拿走,不谢

效果图

三、事件:效果点击时填充与不填充切换

@Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isFill = !isFill;
                invalidate();
        return true;
    }
点击事件.gif

点击事件是你的控件对外的接口,提供修改状态的可能性,你可以发挥无限想象力,这就是自定义控件的魅力。
比如随机颜色,当然你也可以随机大小,随机角数,一切创造取决于你!

点击事件升级.gif

这是一个非常简单的自定义控件,作为自定义控件的第一篇,总结一下绘制的流程还是挺不错的
自定义控件还有很多很多坑,来和我一起填吧。


后记、

1.声明:

[1]本文由张风捷特烈原创,转载请注明
[2]欢迎广大编程爱好者共同交流
[3]个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
[4]你的喜欢与支持将是我最大的动力

2.连接传送门:

更多安卓技术欢迎访问:安卓技术栈
我的github地址:欢迎star
简书首发,腾讯云+社区同步更新
张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com

3.联系我

QQ:1981462002
邮箱:1981462002@qq.com
微信:zdl1994328

4.欢迎关注我的微信公众号,最新精彩文章,及时送达:
公众号.jpg
相关文章
|
容器
Pyside6-第十三篇-布局(最后一章废话-理论篇)
Pyside6-第十三篇-布局(最后一章废话-理论篇)
602 0
|
4月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
2月前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
|
4月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件基础与进阶
【10月更文挑战第5天】在Android应用开发中,自定义控件是提升用户体验和界面个性化的重要手段。本文将通过浅显易懂的语言和实例,引导你了解自定义控件的基本概念、创建流程以及高级应用技巧,帮助你在开发过程中更好地掌握自定义控件的使用和优化。
72 10
|
5月前
|
缓存 前端开发 Android开发
安卓应用开发中的自定义控件
【9月更文挑战第28天】在安卓应用开发中,自定义控件是提升用户界面和交互体验的关键。本文通过介绍如何从零开始构建一个自定义控件,旨在帮助开发者理解并掌握自定义控件的创建过程。内容将涵盖设计思路、实现方法以及性能优化,确保开发者能够有效地集成或扩展现有控件功能,打造独特且高效的用户界面。
|
6月前
|
Android开发 UED 开发者
安卓开发中的自定义控件基础
【8月更文挑战第31天】在安卓应用开发过程中,自定义控件是提升用户界面和用户体验的重要手段。本文将通过一个简易的自定义按钮控件示例,介绍如何在安卓中创建和使用自定义控件,包括控件的绘制、事件处理以及与布局的集成。文章旨在帮助初学者理解自定义控件的基本概念,并能够动手实践,为进一步探索安卓UI开发打下坚实的基础。
|
XML 设计模式 Android开发
Android自定义控件 | 运用策略模式扩展单选按钮和产品经理成为好朋友
变化是永恒的,产品需求稳定不变是不可能的,和产品经理互怼是没有用的,但有一个方向是可以努力的:让代码更有弹性,以不变应万变。 继上一次发版前突然变更单选按钮样式之后,又新增了两个和选项按钮有关的需求。
130 0
|
Android开发 Java API
自定义控件探索之旅一2(笔记)
前言:这是自定义控件探索之旅的第二篇,上一篇主要介绍了安卓自定义控件的基础,这些基础内容主要有Android的坐标系、角度与弧度的换算、安卓的颜色介绍。这一篇我们继续自定义控件的探索之旅。
972 0
|
Android开发
自定义控件探索之旅一1(笔记)
前言:自定义控件,是Android攻城狮进阶的必备技能,是Android应用研发的一门高级艺术,所以接下来的文章主要是学习和探索自定义控件,方便开发使用以及日后查阅。
1205 0