自定义View(2):自定义文本和图像显示
来源:互联网 发布:人工智能的未来与伦理 编辑:程序博客网 时间:2024/06/05 22:30
继承自View的文本+图像显示控件CustomViewImage,需要自定义属性:文字内容,字体颜色和字体大小;图像资源和图像显示方式。
第一步:资源文件中定义属性
<attr name="titleText" format="string" /><attr name="titleTextColor" format="color" /><attr name="titleTextSize" format="dimension" /><attr name="image" format="reference" /><attr name="imageScaleType"><enum name="fillXY" value="0" /><enum name="center" value="1" /></attr><declare-styleable name="CustomViewImage"><attr name="titleText" /><attr name="titleTextSize" /><attr name="titleTextColor" /><attr name="image" /><attr name="imageScaleType" /></declare-styleable>
第二步:在布局文件中添加CustomViewImage,注意定义xmlns:custom,可以更改的是属性资源所在的包名[com.twelve],即manifest文件中定义的包名。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.twelve" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"><com.twelve.custom.CustomViewImageandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:padding="10dp"custom:image="@drawable/girl"custom:imageScaleType="fillXY"custom:titleText="妹子~"custom:titleTextColor="#ff0000"custom:titleTextSize="12sp"/></LinearLayout>第三步,获取自定义属性值
public CustomViewImage(Context context) { this(context, null); } public CustomViewImage(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomViewImage(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); /** * 初始化控件边界 */ rect = new Rect(); /** * 初始化画笔对象 */ mPaint = new Paint(); /** * 初始化文本绘制框 */ mTextBound = new Rect(); /** * 获取文本和图像属性 */ TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomViewImage, defStyle, 0); int n = a.length(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.CustomViewImage_image: /** * 获取图像对象 */ mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0)); break; case R.styleable.CustomViewImage_imageScaleType: /** * 获取图像显示模式 */ mImageScale = a.getInt(attr, 0); break; case R.styleable.CustomViewImage_titleText: /** * 获取文本内容 */ mTitle = a.getString(attr); break; case R.styleable.CustomViewImage_titleTextColor: /** * 获取文本颜色 */ mTextColor = a.getColor(attr, Color.BLACK); break; case R.styleable.CustomViewImage_titleTextSize: /** * 获取文本字号 */ mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); mPaint.setTextSize(mTextSize); break; } } a.recycle(); /** * 获取文本占据上控件画布的大小 */ mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextBound); }
第四步:确定控件的宽度和高度
/** * 确定视图的总宽度和总高度 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); /** * 设置宽度 */ if (widthMode == MeasureSpec.EXACTLY){ /** * 如果显示模式为指定大小,宽度就是给定的宽度 */ mWidth = widthSize; } else { /** * 由图片决定的宽度:图片本身的宽度+与边界的距离 */ int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth(); /** * 由文字决定的宽度:文字本身的宽度+与边界的距离 */ int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width(); /** * 可变宽度下,原则上使得内容显示不超出边界。 */ int desire = Math.max(desireByImg, desireByTitle); mWidth = Math.min(desire, widthSize); } /** * 设置高度 */ if (heightMode == MeasureSpec.EXACTLY){ /** * 如果显示模式为指定大小,高度就是给定的高度 */ mHeight = heightSize; } else { /** * 由图片和文字决定的高度:图片本身的高度+文字本身高度+与边界的距离 */ int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height(); /** * 可变高度下,原则上使得内容显示不超出边界。 */ mHeight = Math.min(desire, heightSize); } setMeasuredDimension(mWidth, mHeight); }第五步,按照上面图像下面文字的方式,把文字和图像显示显示到屏幕上。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setStrokeWidth(4); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.BLUE); /** * 边框:View视图最外边框,与内容距离--padding */ canvas.drawRect(0,0,getWidth(),getHeight(), mPaint); rect.left = getPaddingLeft(); rect.right = mWidth - getPaddingRight(); rect.top = getPaddingTop(); rect.bottom = mHeight - getPaddingBottom(); /** * 边框:紧贴着文字和图像内容的长方形边框 */ mPaint.setColor(Color.RED); canvas.drawRect(rect, mPaint); mPaint.setColor(mTextColor); mPaint.setStyle(Paint.Style.FILL); /** * 当前设置的宽度小于字体需要的宽度,将字体改为xxx... */ if (mTextBound.width() > mWidth) { TextPaint paint = new TextPaint(mPaint); String msg = TextUtils.ellipsize(mTitle, paint, (float) mWidth - getPaddingLeft() - getPaddingRight(), TextUtils.TruncateAt.END).toString(); canvas.drawText(msg, getPaddingLeft(), mHeight - getPaddingBottom(), mPaint); } else { /** * 正常情况,将字体居中 */ canvas.drawText(mTitle, mWidth / 2 - mTextBound.width() * 1.0f / 2, mHeight - getPaddingBottom(), mPaint); } /** * 图形显示在文字的上方,图形可使用的位置高度要减去文字已经使用的高度。 */ rect.bottom -= mTextBound.height(); /** * 如果图片显示模式为填充模式,图片沾满余下的空间 */ if (mImageScale == IMAGE_SCALE_FIT_XY) { canvas.drawBitmap(mImage, null, rect, mPaint); } else { /** * 如果不沾满,图形居中显示,有可能图像不能完全显示在给定的范围内 */ rect.left = mWidth / 2 - mImage.getWidth() / 2; rect.right = mWidth / 2 + mImage.getWidth() / 2; rect.top = (mHeight - mTextBound.height()) / 2 - mImage.getHeight() / 2; rect.bottom = (mHeight - mTextBound.height()) / 2 + mImage.getHeight() / 2; canvas.drawBitmap(mImage, null, rect, mPaint); } }canvas画方框时传入的是方框对象;canvas画图片时,传入方框是图像的边界,图像会被画在方框内;canvas画文字时,传入的是文字左下角的点坐标。
0 0
- 自定义View(2):自定义文本和图像显示
- 自定义View(1):自定义文本显示
- 自定义View实现正好显示文本
- 自定义view(一 <文本>)
- 自定义View绘制心得(自定义view和自定义viewGroup)
- Android - 自定义View 实现 文本吉他谱的 显示 实现
- 自定义view 和linearlayout 的显示区别
- 自定义View的显示
- android自定义View文本居中
- 自定义view之Text文本
- 自定义view文本点击切换
- 自定义View(四)之提取和封装自定义View
- 自定义View和自定义Button
- android自定义view显示歌词
- 自定义view:图片显示指示器
- android自定义view显示日历
- 自定义View显示超大图片
- 自定义View显示不出来
- Winfrom 重绘dataGridView边框颜色(SourceGrid、Panel通用)
- 详解强大的SQL注入工具——SQLMAP(转载)
- [51Testing情人节活动]情人节,爱要有“礼”才完美!
- 设计模式六大原则:单一职责原则 + 依赖倒置原则
- UML领域模型和类图
- 自定义View(2):自定义文本和图像显示
- UML用例图总结
- 1033. To Fill or Not to Fill (25)
- 虚拟应用架构分析
- 视频会议 影响音视频效果的因素
- python eventlet并发原理分析
- 地址格式转换 Excel是最常用的办公软件。每个单元格都有唯一的地址表示。
- STL迭代器之迭代器绑定器:Stream Iterator
- 强连通分量