自定义View 一 (继承VIew重写onDraw方法)
项目:具有圆形效果的自定义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 ①)
自定义View 一 (继承VIew重写onDraw方法)的更多相关文章
- Django admin 继承user表后密码为明文,继承UserAdmin,重写其方法
Django用户继承AbstractUser后密码为明文 其实本不应该有这个问题,却花了我很久的时间,因为还是初学阶段. 造成这个原因是因为在admin注册的生活没有指定Admin 在app的admi ...
- 向集合中添加自定义类型--建议在自定义类型的时候要重写equals方法
package com.bjpowernode.t01list; import java.util.ArrayList; /* * 向集合中添加自定义类型 */public class TestLis ...
- Swing自定义JScrollPane的滚动条设置,重写BasicScrollBarUI方法
Swing自定义JScrollPane的滚动条设置,重写BasicScrollBarUI方法 摘自:https://blog.csdn.net/qq_31635851/article/details/ ...
- C#中在比较自定义对象的时候要重写Equals方法
using System;using System.Collections.Generic;using System.Text; namespace Equal{ using System; c ...
- 自定义视图(继承View)
前言 Android提供了丰富的控件,但是有时候还是不能满足自己的需求,这时候就需要自定义视图了,自定义视图分为几种,一种为继承为View的,一种为继承于ViewGroup的.继承于View的需要我们 ...
- java继承 子类重写父类方法
package com.addd; //多态 public class Sld { private String name = "zhangsan"; public Sld() { ...
- 自定义View(二)--继承自ViewGroup
自定义View包括很多种,上一次随笔中的那一种是完全继承自View,这次写的这个小Demo是继承自ViewGroup的,主要是将自定义View继承自ViewGroup的这个流程来梳理一下,这次的Dem ...
- Android单独继承View类来实现自定义控件
一个单独继承view类来实现自定义控件,在该方法中,需要重写ondraw方法来绘制自己所需要的控件,下面也以一个简单的例子来说明如何实现自定义控件.该方法可以实现所需要的所有的自定义控件. 属性文件中 ...
- Android-自定义控件-继承View与ViewGroup的初步理解
继承View需要走的流程是: 1.构造实例化, public ChildView(Context context, @Nullable AttributeSet attrs) 2.测量自身的高和宽on ...
随机推荐
- 火狐浏览器,hostadmin hosts文件访问权限不足
开始->附件->以管理员身份运行. cacls %windir%\system32\drivers\etc\hosts /E /G Users:W
- Python变量和数据类型
十六进制用0x前缀和0-9 a-f表示 字符串是以''或""括起来的任意文本 一个布尔值只有True和False两种值 布尔值可以用and or not运算 空值是 ...
- Django学习之路
Django Website Collect django packages http://djangopackages.com/ django project http://code.djangop ...
- opencv + numpy for python
OpenCV的全称是:Open Source Computer Vision Library.OpenCV是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS ...
- 定时任务:Java中Timer和TimerTask的使用
java.util.Timer定时器,实际上是个线程,定时调度所拥有的TimerTasks. 一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerT ...
- 常用财务软件:用友,金蝶,新中大,速达,管家婆,金算盘,远方,远光,金钥匙,润衡,浪潮,上海博科,易商,任我行,千方百剂,智管,小蜜蜂,SAP,ORACLE,SSA,QAD,MAPICS,JDE。
常用财务软件:用友,金蝶,新中大,速达,管家婆,金算盘,远方,远光,金钥匙,润衡,浪潮,上海博科,易商,任我行,千方百剂,智管,小蜜蜂,SAP,ORACLE,SSA,QAD,MAPICS,JDE. 申 ...
- < IOS > X-code 5.1 x86 - 64 编译问题
关于xcode 5.1 x86 - 64 编译问题 坐等了N久,终于IOS 7.1 发布了,作为一个果粉,忍不住第一时间升级了.结果用设备测试的时候,出问题了,一直检测不到设备,哈哈,纠结了半 ...
- bzoj3407 [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题
Description 贝茜像她的诸多姊妹一样,因为从约翰的草地吃了太多美味的草而长出了太多的赘肉.所以约翰将她置于一个及其严格的节食计划之中.她每天不能吃多过H(5≤日≤45000)公斤的干 ...
- ThreadPool(线程池) in .Net
本文来自:http://rickie.cnblogs.com/archive/2004/11/23/67275.html 在多线程的程序中,经常会出现两种情况.一种情况下,应用程序中的线程把大部分的时 ...
- unity 3d 生成apk文件时,设置图标
如图所示:注意红线标注部分: 如果安装到手机之后,程序的图标还是unity的默认图标,重启手机即可.