项目:具有圆形效果的自定义View

一、继承View并重写onDraw方法

public class CircleView extends View{
private static final int COLOR = Color.RED;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mWidth = 0;
private int mHeight = 0; public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} public CircleView(Context context) {
super(context);
init();
} public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
} private void init(){
mPaint.setColor(COLOR);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取当前View的宽/高
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
//获取半径
int radium = Math.min(mWidth,mHeight)/2;
//画圆
canvas.drawCircle(mWidth/2,mHeight/2,radium,mPaint);
} }

CircleView

在xml中测试margin发现可以用,说明margin是由父容器控制的(想起measureChildMarginLayout源码)

但是wrap_content和padding都不生效。

二、让wrap_content生效

根据上一章View的工作原理:①、重写onMeasure方法  ②、给CircleView设定一个固定的宽高

//设定wrap_content时候的宽度
private static final int AT_WIDTH = 30;
private static final int AT_HEIGHT = 30; //重写onMeasure()方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取子View的范围
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//判断当属性为wrap_content的时候
if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST){
setMeasuredDimension(AT_WIDTH,AT_HEIGHT);
}
else if (widthMode == MeasureSpec.AT_MOST){
setMeasuredDimension(AT_WIDTH,heightSize);
}
else if (heightMode == MeasureSpec.AT_MOST){
setMeasuredDimension(widthSize,AT_HEIGHT);
}
else {
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
}

三、解决无法padding的问题

原理:只需要在onDraw中,获取padding的参数就可以了

//重写onDraw方法
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取padding
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
//获取当前View的宽/高 减去padding
mWidth = getMeasuredWidth() - paddingLeft - paddingRight;
mHeight = getMeasuredHeight() - paddingTop - paddingBottom;
//获取半径
int radium = Math.min(mWidth,mHeight)/2;
//画圆
canvas.drawCircle(paddingLeft+mWidth/2,paddingTop - mHeight/2,radium,mPaint);
}

CircleView

四、自定义属性

步骤:①、在values目录中创建xml文件名,文件名必须以attr_开头。②、内容的编写:<declare-styleadable>标签中:name代表自定义属性(该为CircleView类)

<attr>标签中 name代表之后使用的属性名(circle_color),format代表格式(color)

<resources>
<declare-styleable name="CircleView">
<attr name="color_circle" format="color"/>
</declare-styleable>
</resources>

attr_circleview

步骤③、在布局文件中使用自定义属性  必须在schemas声明:xmlns:app="http://schemas.android.com/apk/res-auto" 其中app名字可以随便替换。

但是circleView中自定义属性名的前缀必须是和这里一致(一般习惯使用app)

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
//这一段必须要加 app名字可以替换
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.maikefengchao.circleview.MainActivity"> <com.maikefengchao.circleview.CircleView
android:layout_width="80dp"
android:layout_height="80dp"
//前缀与添加的声明前缀一致
app:color_circle="#9999"/>
</LinearLayout>

步骤④:在CircleView中获取自定义属性参数

//在构造方法中使用
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//加载自定义属性集合CircleView
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleView);
//解析集合中的circle_circle,设置默认颜色
mColor = a.getColor(R.styleable.CircleView_color_circle,Color.RED);
init();
}

全部代码:(P209 ①)

最新文章

  1. java基础知识 多线程
  2. QSS的应用
  3. 未能加载文件或程序集“projectname, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的文件。
  4. Socket之TCP连接_TcpNoDelay
  5. 字符串String: 常量池
  6. OpenCV成长之路(4):图像直方图
  7. 如何在plSql查询数据查出的数据可编辑
  8. ContentProvider官方教程(7)3种访问形式:批处理、异步访问、intent间接访问(临时URI权限)
  9. 感受机房管理化繁为简-新款KVM使用心得
  10. 泡泡堂、QQ堂游戏通信架构分析
  11. ogg实现oracle到sql server 2005的同步
  12. [转]Flex 布局教程:语法篇
  13. 自定义栈类型,具有找到站内最小元素的min函数 ,且min(),pop(),push()函数的时间复杂度为O(1)
  14. [core java学习笔记][第十一章异常断言日志调试]
  15. 登录SQL注入
  16. nginx配置优化+负载均衡+动静分离详解
  17. Sampling
  18. window下部署Solr
  19. python 之 列表list &amp;&amp; 元组tuple
  20. Java公开课-03.内部类

热门文章

  1. PHP设置http头信息
  2. Javascript经典实例 - 字符串
  3. php读取和保存base64编码的图片内容
  4. 【Ecstore2.0】第三方信任登陆问题解决_备忘
  5. 使用jekyll主题
  6. python安装第三方包的两种方式
  7. Loadrunner11 录制手机App脚本多种方法介绍
  8. instancetype和id的区别
  9. asm.uew
  10. javascript调试