自定义控件一、
2016-03-03 15:20
141 查看
本文参考鸿神:http://blog.csdn.net/lmj623565791/article/category/2680591. 仅作个人动手总结.
1. 自定义View的属性.
2. 在View的构造方法中获取各个属性.
3. 重写onMesure()方法.
4. 重写onLayout()方法
5. 重写OnDraw()方法.
第一个简单自定义控件的实现
新建attrs.xml文件,在该文件中定义控件的各个属性
自定义类继承目标控件,实现相关方法
xml布局文件中定义
效果
1. 自定义View的属性.
2. 在View的构造方法中获取各个属性.
3. 重写onMesure()方法.
4. 重写onLayout()方法
5. 重写OnDraw()方法.
第一个简单自定义控件的实现
新建attrs.xml文件,在该文件中定义控件的各个属性
<?xml version="1.0" encoding="utf-8" ?> <resources> <!--format:string,color,demension,integer,enum,reference,float,boolean,fraction,flag--> <attr name="titleText" format="string" /> <attr name="titleColor" format="color" /> <attr name="titleSize" format="dimension" /> <declare-styleable name="CatfaceTextView"> <attr name="titleText" /> <attr name="titleColor" /> <attr name="titleSize" /> </declare-styleable> </resources>
自定义类继承目标控件,实现相关方法
public class CatfaceTextView extends TextView { // 自定义控件的属性 private String titleText; private int titleColor, titleSize; // 初始化控件内容的范围 private Rect rect = new Rect(); // 初始化画笔 private Paint paint = new Paint(); public CatfaceTextView(Context context) { this(context, null); } public CatfaceTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CatfaceTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); /** 获取自定义控件的属性 */ TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CatfaceTextView, defStyleAttr, 0); int indexCount = typedArray.getIndexCount(); for (int i = 0; i < indexCount; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.CatfaceTextView_titleText: titleText = typedArray.getString(attr); break; case R.styleable.CatfaceTextView_titleColor: titleColor = typedArray.getColor(attr, Color.argb(255, 0, 0, 0)); // 默认字体颜色黑色 break; case R.styleable.CatfaceTextView_titleSize: titleSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); // 默认大小16sp break; } /** 给当前控件设置监听事件:点击更换控件内容 */ this.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { titleText = new Random().nextInt(1000) + ""; postInvalidate(); } }); } typedArray.recycle(); /** 获取控件内容的宽高 */ paint.setTextSize(titleSize); paint.getTextBounds(titleText, 0, titleText.length(), rect); } // 以下介绍MeasureSpec的三个属性值 // EXACTLY:一般是设置了明确的值或者是MATCH_PARENT // AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT // UNSPECIFIED:表示子布局想要多大就多大,很少使用 @Override /** 初始化执行一次 */ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.d("sequency", "mesure"); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width, height; if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { // 当使用wrap_content包裹时重新确认控件宽高 paint.setTextSize(titleSize); paint.getTextBounds(titleText, 0, titleText.length(), rect); float textWidth = rect.width(); int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight()); width = desired; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { paint.setTextSize(titleSize); paint.getTextBounds(titleText, 0, titleText.length(), rect); float textHeight = rect.height(); int desired = (int) (getPaddingTop() + getPaddingBottom() + textHeight); height = desired; } setMeasuredDimension(width, height); } @Override /** 初始化执行一次 */ protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); Log.d("sequency", "layout"); } @Override /** 每次绘制都会执行 */ protected void onDraw(Canvas canvas) { Log.d("sequency", "draw"); /** 填充控件背景 */ paint.setColor(Color.argb(255, 255, 0, 0)); canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), paint); /** 绘制内容及确定文本相对控件的位置 */ paint.setColor(titleColor); // 确定文本相对控件的左下角坐标 canvas.drawText(titleText, getWidth() / 2 - rect.width() / 2, getHeight() / 2 + rect.height() / 2, paint); } }
xml布局文件中定义
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <!-- 必须声明命名空间! --> xmlns:catface="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <catface.myview01.view.CatfaceTextView android:layout_centerInParent="true" android:layout_width="150dp" android:layout_height="100dp" catface:titleText="999" catface:titleColor="#ff0" catface:titleSize="36sp"/> </RelativeLayout>
效果
相关文章推荐
- C# 文件压缩与解压(ZIP格式)
- Topcoder SRM 683 Div2 B
- codeforce 621A(水题)
- qt creator 快速入门 知识点索引 笔记
- 谈谈Android中的Divider是个什么东东
- Xcode控制台命令
- BZOJ 1176: [Balkan2007]Mokia
- Mariadb/MySQL存储过程中的3种循环
- [Android] animated-rotate简单的转菊花...
- FAQ00366]如何使Android应用程序获取系统权限
- 读《深入php面向对象、模式与实践》有感(二)
- 读《深入php面向对象、模式与实践》有感(二)
- Android 后端 Bmob的使用
- json 转 T
- Codeforces Round #295 (Div. 1) C. Pluses everywhere
- C#实现多选项卡的浏览器控件
- RecyclerView使用详解(一)
- iOS CoreData数据迁移-轻量级迁移
- variable type of buffer_handle_t
- 爱奇艺牵手环球音乐再发力视频付费服务(来源:数娱梦工厂)