安卓自定义view总结1
来源:互联网 发布:广东高考难度 知乎 编辑:程序博客网 时间:2024/06/03 18:02
一直以来用了很多自定义view都没有好好总结,今天就总结总结:
第一个例子:验证码
思路:重写view:
1. values下创建文件attr.xml :这里主要放自定义view(控件)需要的:属性名,属性代表的值;
2.写一个自定义view继承view类:
2.1:重载构造函数的三种: public CustomTitleView(Context context);
public CustomTitleView(Context context, AttributeSet attrs);
public CustomTitleView(Context context, AttributeSet attrs, int defStyle);
在这些构造函数中:按需取得attr.xml文件下第一步定义的属性,和属性值;
一般要用到的类和函数:
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0); //从attr.xml中获取declare-styleable下的节点
int n = a.getIndexCount(); //获取节点的总个数
int attr = a.getIndex(i); //获取位置为i的节点的attr
String str= a.getString(attr); //获取attr设置的字符串的值
int color=a.getColor(attr, Color.YELLOW); //获取attr中设置的颜色,第二个参数是默认颜色,防止未设置时出现错误(可以随意设置颜色)
int a a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(//设定默认字体大小,并返回
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
获取后,务必进行:a.recycle(); //释放资源
当然也可以为自定义的view设置监听事件:
例如:
this.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mTitleText = randomText();
postInvalidate(); //重绘
}
});
2.2:重写protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec):按需求对控件进行测量,并设置宽高
一个测量的例子:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
/**
* 设置宽度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec); //获取宽设置的模式
int specSize = MeasureSpec.getSize(widthMeasureSpec); //获取宽尺寸
switch (specMode)
{
case MeasureSpec.EXACTLY:// 明确指定了
width = getPaddingLeft() + getPaddingRight() + specSize; //宽为外边距加尺寸
break;
case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
width = getPaddingLeft() + getPaddingRight() + mBound.width();
break;
}
/**
* 设置高度
*/
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
switch (specMode)
{
case MeasureSpec.EXACTLY:// 明确指定了
height = getPaddingTop() + getPaddingBottom() + specSize;
break;
case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
height = getPaddingTop() + getPaddingBottom() + mBound.height();
break;
}
setMeasuredDimension(width, height); //设置宽高
}
2.3:重写onDraw(Canvas canvas):进行绘制
重绘的话,无非就是画笔,画布,矩阵,其他类型的矩阵之类的:
mPaint = new Paint(); //画笔
mPaint.setTextSize(mTitleTextSize); //设置画笔写字的大小
// mPaint.setColor(mTitleTextColor);
mBound = new Rect(); //矩阵
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);//获取文字占据的区域
重写onDraw(Canvas canvas)例子
@Override
protected void onDraw(Canvas canvas)
{
//mPaint.setColor(Color.YELLOW);
//canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
mPaint.setColor(mTitleTextColor);
canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
}
完整的例子: 例子来自鸿洋大神的
材料:一个设置属性的attr.xml
一张包含了自定义的布局:activity_main.xml
一个继承了view类的自定义类:CustomTitleView
一个Activity:MainActivity
attr.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="titleText" format="string" /> <!--定义属性为字符串-->
<attr name="titleTextColor" format="color" /> <!-- 定义属性为颜色 -->
<attr name="titleTextSize" format="dimension" /> <!-- 定义属性为字体大小 -->
<declare-styleable name="CustomTitleView"> <!-- 声明属性 -->
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
</declare-styleable>
</resources>
<!-- format还可以指定其他的类型比如;
reference 表示引用,参考某一资源ID
string 表示字符串
color 表示颜色值
dimension 表示尺寸值
boolean 表示布尔值
integer 表示整型值
float 表示浮点值
fraction 表示百分数
enum 表示枚举值
flag 表示位运算 -->
2.activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01" <!--引入此句,设置自定义属性时便可以用custom:属性:属性值-,com.example.customview01是view类包名字-->
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.customview01.view.CustomTitleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:titleText="3712"
android:padding="10dp"
custom:titleTextColor="#ff0000"
android:layout_centerInParent="true"
custom:titleTextSize="40sp" />
</RelativeLayout>
3.CustomTitle.java
public class CustomTitleView extends View
{
/**
* 文本
*/
private String mTitleText;
/**
* 文本的颜色
*/
private int mTitleTextColor;
/**
* 文本的大小
*/
private int mTitleTextSize;
/**
* 绘制时控制文本绘制的范围
*/
private Rect mBound;
private Paint mPaint;
public CustomTitleView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public CustomTitleView(Context context)
{
this(context, null);
}
/**
* 获得我自定义的样式属性
*
* @param context
* @param attrs
* @param defStyle
*/
public CustomTitleView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
/**
* 获得我们所定义的自定义样式属性
*/
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0); //从attr.xml中获取sttleable下的节点
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i); //获取该attr
switch (attr)
{
case R.styleable.CustomTitleView_titleText:
mTitleText = a.getString(attr); //返回字符串属性
break;
case R.styleable.CustomTitleView_titleTextColor:
// 默认颜色设置为黑色
mTitleTextColor = a.getColor(attr, Color.YELLOW); //设定默认颜色,并返回标签
break;
case R.styleable.CustomTitleView_titleTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(//设定默认字体大小,并返回
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle(); //释放资源
/**
* 获得绘制文本的宽和高
*/
mPaint = new Paint(); //画笔
mPaint.setTextSize(mTitleTextSize); //设置画笔写字的大小
// mPaint.setColor(mTitleTextColor);
mBound = new Rect();
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);//获取文字占据的区域
this.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
mTitleText = randomText();
postInvalidate();
}
});
}
private String randomText() //随机产生四位数字
{
Random random = new Random();
Set<Integer> set = new HashSet<Integer>();
while (set.size() < 4)
{
int randomInt = random.nextInt(10);
set.add(randomInt);
}
StringBuffer sb = new StringBuffer();
for (Integer i : set)
{
sb.append("" + i);
}
return sb.toString();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
/**
* 设置宽度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec); //获取宽设置的模式
int specSize = MeasureSpec.getSize(widthMeasureSpec); //获取宽尺寸
switch (specMode)
{
case MeasureSpec.EXACTLY:// 明确指定了
width = getPaddingLeft() + getPaddingRight() + specSize; //宽为外边距加尺寸
break;
case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
width = getPaddingLeft() + getPaddingRight() + mBound.width();
break;
}
/**
* 设置高度
*/
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
switch (specMode)
{
case MeasureSpec.EXACTLY:// 明确指定了
height = getPaddingTop() + getPaddingBottom() + specSize;
break;
case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
height = getPaddingTop() + getPaddingBottom() + mBound.height();
break;
}
setMeasuredDimension(width, height); //设置宽高
}
@Override
protected void onDraw(Canvas canvas)
{
mPaint.setColor(Color.YELLOW);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
mPaint.setColor(mTitleTextColor);
canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
}
}
4.MainActivity:
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
例子完成,view第一篇
- 安卓自定义view总结1
- 安卓自定义View
- 安卓自定义view
- 安卓自定义View
- 安卓自定义View
- 安卓自定义view
- 安卓自定义view进阶(1)
- 安卓自定义View组件
- 安卓常用自定义View
- 安卓开发自定义View
- 安卓自定义View详解
- 安卓自定义View教程
- 安卓自定义View网址
- 安卓自定义View进阶
- 安卓自定义View进阶
- 安卓自定义分页view
- 安卓学习笔记:1:用自定义View
- 安卓开发28:自定义View类
- 润乾集算报表实现T+0报表
- bzoj 4520 [Cqoi2016]K远点对
- comet4j的使用
- YII2 日志
- 【leetcode】2. Add Two Numbers
- 安卓自定义view总结1
- Window系统下CMD命令大全(二)
- XML解析小记之防止数据过长被截断
- redis中数据持久化(四)
- HDU 4499 Cannon
- JavaSE学习笔记_19:Java-GUI
- 《Head First设计模式》 - 观察者模式
- "多米诺骨牌"问题的动态规划算法
- Java NIO - CountDownLatch