写点什么

自定义 View

用户头像
Android架构
关注
发布于: 6 小时前

// 一般是在第二个构造函数里主动调用


// 如 View 有 style 属性时


public CircleView(Context context,AttributeSet attrs,int defStyleAttr ){


super(context, attrs,defStyleAttr);


init();


}


//API21 之后才使用


// 不会自动调用


// 一般是在第二个构造函数里主动调用


// 如 View 有 style 属性时


public CircleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {


super(context, attrs, defStyleAttr, defStyleRes);


}


// 画笔初始化


private void init() {


// 创建画笔


mPaint1 = new Paint ();


// 设置画笔颜色为蓝色


mPaint1.setColor(Color.BLUE);


// 设置画笔宽度为 10px


mPaint1.setStrokeWidth(5f);


//设置画笔模式为填充


mPaint1.setStyle(Paint.Style.FILL);


}


// 复写 onDraw()进行绘制


@Override


protected void onDraw(Canvas canvas) {


super.onDraw(canvas);


// 获取控件的高度和宽度


int width = getWidth();


int height = getHeight();


// 设置圆的半径 = 宽,高最小值的 2 分之 1


int r = Math.min(width, height)/2;


// 画出圆(蓝色)


// 圆心 = 控件的中央,半径 = 宽,高最小值的 2 分之 1


canvas.drawCircle(width/2,height/2,r,mPaint1);


}


}


步骤 2:在 xml 中加入这个 view


<?xml version="1.0" encoding="utf-8"?>


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"


xmlns:tools="http://schemas.android.com/tools"


android:layout_width="match_parent"


android:layout_height="match_parent"


tools:context="Rikka.MainActivity">


<scut.carson_ho.diy_view.CircleView


android:layout_width="match_parent"


android:layout_height="150dp"


android:background="#000000"/>


</RelativeLayout>


效果如下:



接着手动支持 wrap_content 和 padding,以及为自定义 view 设置属性。


(1)支持 wrap_content


(2)padding,在 CircleView 中的 onDraw 添加如下代码:


绘制时考虑传入 padding 属性值(4 个方向)


// 仅看复写的 onDraw()


@Override


protected void onDraw(Canvas canvas) {


super.onDraw(canvas);


// 获取传入的 padding 值


final int paddingLeft = getPaddingLeft();


final int paddingRight = getPaddingRight();


final int paddingTop = getPaddingTop();


final int paddingBottom = getPaddingBottom();


// 获取绘制内容的高度和宽度(考虑了四个方向的 padding 值)


int width = getWidth() - paddingLeft - paddingRight ;


int height = getHeight() - paddingTop - paddingBottom ;


// 设置圆的半径 = 宽,高最小值的 2 分之 1


int r = Math.min(width, height)/2;


// 画出圆(蓝色)


// 圆心 = 控件的中央,半径 = 宽,高最小值的 2 分之 1


canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2,r,mPaint1);


}


这时候在 xml 的 view 中添加 android:padding="20dp",view 就会支持 padding 了



(3)提供自定义属性:


// 基本是以 android 开头


android:layout_width="match_parent"


android:layout_height="match_parent"


android:background="#000000"


android:padding="30dp"


上面是系统自带的自定义属性。


但有时候我们需要定义系统所没有的属性,称为自定义属性,实现步骤有下:


①、在 values 目录下自定义属性的 xml 文件


②、在自定义 view 的构造方法中解析自己定义属性的值


③、在布局文件中自己定义属性


具体实现:


①:在 values 中定义 xml 文件:


attrs_circle_view.xml


<?xml version="1.0" encoding="utf-8"?>


<resources>


<declare-styleable name="CircleView">


<attr name="circle_color" format="color"/>


</declare-styleable>


</resources>


对于自定义属性类型有如下格式:


<-- 1. reference:使用某一资源 ID -->


<declare-styleable name="名称">


<attr name="background" format="reference" />


</declare-styleable>


// 使用格式


// 1. Java 代码


private int ResID;


private Drawable ResDraw;


ResID = typedArray.getResourceId(R.styleable.SuperEditText_background, R.drawable.background); // 获得资源 ID


ResDraw = getResources().getDrawable(ResID); // 获得 Drawble 对象


// 2. xml 代码


<ImageView


android:layout_width="42dip"


android:layout_height="42dip"


app:background="@drawable/图片 ID" />


<-- 2. color:颜色值 -->


<declare-styleable name="名称">


<attr name="textColor" format="color" />


</declare-styleable>


// 格式使用


<TextView


android:layout_width="42dip"


android:layout_height="42dip"


android:textColor="#00FF00" />


<-- 3. boolean:布尔值 -->


<declare-styleable name="名称">


<attr name="focusable" format="boolean" />


</declare-styleable>


// 格式使用


<Button


android:layout_width="42dip"


android:layout_height="42dip"


android:focusable="true" />


<-- 4. dimension:尺寸值 -->


<declare-styleable name="名称">


<attr name="layout_width" format="dimension" />


</declare-styleable>


// 格式使用:


<Button


android:layout_width="42dip"


android:layout_height="42dip" />


<-- 5. float:浮点值 -->


<declare-styleable name="AlphaAnimation">


<attr name="fromAlpha" format="float" />


<attr name="toAlpha" format="f


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


loat" />


</declare-styleable>


// 格式使用


<alpha


android:fromAlpha="1.0"


android:toAlpha="0.7" />


<-- 6. integer:整型值 -->


<declare-styleable name="AnimatedRotateDrawable">


<attr name="frameDuration" format="integer" />


<attr name="framesCount" format="integer" />


</declare-styleable>


// 格式使用


<animated-rotate


xmlns:android="http://schemas.android.com/apk/res/android"


android:frameDuration="100"


android:framesCount="12"


/>


<-- 7. string:字符串 -->


<declare-styleable name="MapView">


<attr name="apiKey" format="string" />


</declare-styleable>


// 格式使用


<com.google.android.maps.MapView


android:apiKey="0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g" />


<-- 8. fraction:百分数 -->


<declare-styleable name="RotateDrawable">


<attr name="pivotX" format="fraction" />


<attr name="pivotY" format="fraction" />


</declare-styleable>


// 格式使用


<rotate


xmlns:android="http://schemas.android.com/apk/res/android"


android:pivotX="200%"


android:pivotY="300%"


/>


<-- 9. enum:枚举值 -->


<declare-styleable name="名称">


<attr name="orientation">


<enum name="horizontal" value="0" />


<enum name="vertical" value="1" />


</attr>


</declare-styleable>


// 格式使用


<LinearLayout


android:layout_width="fill_parent"


android:layout_height="fill_parent"


/>


<-- 10. flag:位或运算 -->


<declare-styleable name="名称">


<attr name="windowSoftInputMode">


<flag name="stateUnspecified" value="0" />


<flag name="stateUnchanged" value="1" />


<flag name="stateHidden" value="2" />


<flag name="stateAlwaysHidden" value="3" />


<flag name="stateVisible" value="4" />


<flag name="stateAlwaysVisible" value="5" />


<flag name="adjustUnspecified" value="0x00" />


<flag name="adjustResize" value="0x10" />


<flag name="adjustPan" value="0x20" />


<flag name="adjustNothing" value="0x30" />


</attr>


</declare-styleable>、


// 使用


<activity


android:name=".StyleAndThemeActivity"


android:label="@string/app_name"


android:windowSoftInputMode="stateUnspecified | stateUnchanged | stateHidden" >


<intent-filter>


<action android:name="android.intent.action.MAIN" />


<category android:name="android.intent.category.LAUNCHER" />


</intent-filter>

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
自定义View