自定义控件学习第二课
来源:互联网 发布:厦门网游网络 编辑:程序博客网 时间:2024/06/05 21:53
自定义控件学习第二课
这节课效果如下:
第一步还是先写属性文件
<?xml version="1.0" encoding="utf-8"?><resources> <attr name="titleText" format="string"/> <attr name="titleTextSize" format="dimension"/> <attr name="titleTextColor" format="color"/> <attr name="image" format="reference"/> <attr name="imageScaleType"> <enum name="fillXY" value="0"/> <enum name="center" value="1"/> </attr> <declare-styleable name="CustomImageView"> <attr name="titleText"/> <attr name="titleTextSize"/> <attr name="titleTextColor"/> <attr name="image"/> <attr name="imageScaleType"/> </declare-styleable></resources>
第二步实现类:
public class CustomImageView extends View { private String mTitleText; private int mTitleTextSize; private int mTitleTextColor; private Bitmap mImage; private int mImageScaleType; private Paint mPaint; private Rect mBound; private Rect rect;// 可绘制的范围 private int mWidth; private int mHeight; public CustomImageView(Context context) { this(context, null); // TODO Auto-generated constructor stub } public CustomImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); // TODO Auto-generated constructor stub } public CustomImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.CustomImageView_titleText: mTitleText = a.getString(attr); break; case R.styleable.CustomImageView_titleTextSize: mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); break; case R.styleable.CustomImageView_titleTextColor: mTitleTextColor = a.getColor(attr, Color.BLACK); break; case R.styleable.CustomImageView_image: mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0)); break; case R.styleable.CustomImageView_imageScaleType: mImageScaleType = a.getInt(attr, 0); break; } } a.recycle(); mPaint = new Paint(); mBound = new Rect(); rect = new Rect(); mPaint.setTextSize(mTitleTextSize); mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub /* * 处理宽度 */ int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { mWidth = widthSize; } else { int widthByImg = mImage.getWidth() + getPaddingLeft() + getPaddingRight(); int widthByText = mBound.width() + getPaddingLeft() + getPaddingRight(); if (widthMode == MeasureSpec.AT_MOST) { mWidth = Math.min(widthSize, Math.max(widthByImg, widthByText)); } } /* * 处理高度 */ int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (heightMode == MeasureSpec.EXACTLY) { mHeight = heightSize; } else { int heightImgAddText = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mBound.width(); if (heightMode == MeasureSpec.AT_MOST) { mHeight = Math.min(heightSize, heightImgAddText); } } setMeasuredDimension(mWidth, mHeight); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub // 边框 mPaint.setStrokeWidth(4); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.CYAN); canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint); // 画字 mPaint.setColor(mTitleTextColor); mPaint.setStyle(Paint.Style.FILL); if (mBound.width() > mWidth) {// 字的范围超出当前设置范围了 TextPaint p = new TextPaint(mPaint); String msg = TextUtils.ellipsize(mTitleText, p, (float) mWidth - getPaddingLeft() - getPaddingRight(), TextUtils.TruncateAt.END).toString(); canvas.drawText(msg, getPaddingLeft(), mHeight - getPaddingBottom(), mPaint); } else {// 正常,则居中显示 canvas.drawText(mTitleText, mWidth / 2 - mBound.width() / 2, mHeight - getPaddingBottom(), mPaint); } // 只考虑字的宽度,保证字的高度,确保显示 rect.left = getPaddingLeft(); rect.right = mWidth - getPaddingRight(); rect.top = getPaddingTop(); rect.bottom = mHeight - getPaddingBottom() - mBound.height(); // 现在rect就是图片可显示的大小了 if (mImageScaleType == 0) { canvas.drawBitmap(mImage, null, rect, mPaint); } else { rect.left = mWidth / 2 - mImage.getWidth() / 2; rect.right = mWidth / 2 + mImage.getWidth() / 2; rect.top = (mHeight - mBound.height()) / 2 - mImage.getHeight() / 2; rect.bottom = (mHeight - mBound.height()) / 2 + mImage.getHeight() / 2; canvas.drawBitmap(mImage, null, rect, mPaint); } }}
其中有些知识点讲下:
TextUtils类介绍
对于字符串处理Android为我们提供了一个简单实用的TextUtils类,如果处理比较简单的内容不用去思考正则表达式不妨试试这个在android.text.TextUtils的类,主要的功能如下:
是否为空字符 boolean android.text.TextUtils.isEmpty(CharSequence str)
拼接字符串 String android.text.TextUtils.join(CharSequence delimiter, Object[] tokens)
拆分字符串 String[] android.text.TextUtils.split(String text, String expression)
拆分字符串使用正则 String[] android.text.TextUtils.split(String text, Pattern pattern)
确定大小写是否有效在当前位置的文本 int android.text.TextUtils.getCapsMode(CharSequence cs, int off, int reqModes)
使用HTML编码这个字符串 String android.text.TextUtils.htmlEncode(String s)
另外,String[] android.text.TextUtils.split(String text, String expression)中的expression较特殊,如果采用
TextUtils.split(someString, “-“);
来分割someString的话返回的将是错误结果,正确的用法应该是
TextUtils.split(line, “,|\-“);
对图片剪接和限定显示区域
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint);
Rect src: 是对图片进行裁截,若是空null则显示整个图片
RectF dst:是图片在Canvas画布中显示的区域,
大于src则把src的裁截区放大,
小于src则把src的裁截区缩小。
- 自定义控件学习第二课
- JSF 学习之 编写自定义控件(第二部分)
- 自定义控件学习第一课
- 第二章(3)自定义控件
- 加班~~~第二天之自定义UIPageControl控件
- 自定义控件系列<第二篇>--多维表头
- dotnet 自定义控件学习
- 自定义控件学习
- 唉,学习自定义控件
- [自定义控件学习]Textview
- 学习日志--自定义控件
- 学习自定义控件
- 学习笔记:自定义控件
- 创建自定义控件学习
- 自定义控件学习Topbar
- android 自定义控件学习
- Android自定义控件学习
- 自定义控件学习:Toggle
- JavaScript简介
- 将DataTable转换为标准的JSON
- IOC---教你打造 Android 中的 IOC 框架 【ViewInject】 (上)
- Centos 6.5下code::blocs搭建GTK+
- Web性能测试工具大全
- 自定义控件学习第二课
- 详解Spring事件驱动模型
- 理解 Android Build 系统_Make 文件说明_4
- 关于Java的若干基础知识
- 不用USBASP芯片也可用USB,纯AVR实现USB通讯:AVRUSB
- Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED
- Android进程通信:AIDL入门实例
- 理解 Android Build 系统_Make 目标说明_5
- IOC---教你打造 Android 中的 IOC 框架【ViewInject】 (下)