Android 自己定义View (二) 进阶
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125
继续自己定义View之旅。前面已经介绍过一个自己定义View的基础的样例,Android
自己定义View (一),假设你还对自己定义View不了解能够去看看。今天给大家带来一个略微复杂点的样例。
自己定义View显示一张图片,以下包括图片的文本介绍,类似相片介绍什么的,只是不重要,主要是学习自己定义View的使用方法么。
还记得上一篇讲的4个步骤么:
1、自己定义View的属性
2、在View的构造方法中获得我们自己定义的属性
[ 3、重写onMesure ]
4、重写onDraw
直接切入正题:
1、在res/values/attr.xml
<?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>
2、在构造中获得我们的自己定义属性:
/**
* 初始化所特有自己定义类型
*
* @param context
* @param attrs
* @param defStyle
*/
public CustomImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle); 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_image:
mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
break;
case R.styleable.CustomImageView_imageScaleType:
mImageScale = a.getInt(attr, 0);
break;
case R.styleable.CustomImageView_titleText:
mTitle = a.getString(attr);
break;
case R.styleable.CustomImageView_titleTextColor:
mTextColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomImageView_titleTextSize:
mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
16, getResources().getDisplayMetrics()));
break; }
}
a.recycle();
rect = new Rect();
mPaint = new Paint();
mTextBound = new Rect();
mPaint.setTextSize(mTextSize);
// 计算了描绘字体须要的范围
mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextBound); }
3、重写onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// super.onMeasure(widthMeasureSpec, heightMeasureSpec); /**
* 设置宽度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec); if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
Log.e("xxx", "EXACTLY");
mWidth = specSize;
} else
{
// 由图片决定的宽
int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();
// 由字体决定的宽
int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width(); if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
int desire = Math.max(desireByImg, desireByTitle);
mWidth = Math.min(desire, specSize);
Log.e("xxx", "AT_MOST");
}
} /***
* 设置高度
*/ specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
mHeight = specSize;
} else
{
int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
mHeight = Math.min(desire, specSize);
}
}
setMeasuredDimension(mWidth, mHeight); }
4、重写onDraw
@Override
protected void onDraw(Canvas canvas)
{
// super.onDraw(canvas);
/**
* 边框
*/
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.CYAN);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint); rect.left = getPaddingLeft();
rect.right = mWidth - getPaddingRight();
rect.top = getPaddingTop();
rect.bottom = mHeight - getPaddingBottom(); mPaint.setColor(mTextColor);
mPaint.setStyle(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_FITXY)
{
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);
} }
代码,结合凝视和第一篇View的使用,应该能够看懂,不明确的留言。以下我们引入我们的自己定义View:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.customview02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <com.zhy.customview02.view.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/ic_launcher"
zhy:imageScaleType="center"
zhy:titleText="hello andorid ! "
zhy:titleTextColor="#ff0000"
zhy:titleTextSize="30sp" /> <com.zhy.customview02.view.CustomImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/ic_launcher"
zhy:imageScaleType="center"
zhy:titleText="helloworldwelcome"
zhy:titleTextColor="#00ff00"
zhy:titleTextSize="20sp" /> <com.zhy.customview02.view.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
zhy:image="@drawable/lmj"
zhy:imageScaleType="center"
zhy:titleText="妹子~"
zhy:titleTextColor="#ff0000"
zhy:titleTextSize="12sp" /> </LinearLayout>
我特意让显示出现3中情况:
1、字体的宽度大于图片,且View宽度设置为wrap_content
2、View宽度设置为精确值。字体的长度大于此宽度
3、图片的宽度大于字体。且View宽度设置为wrap_content
看看显示效果:
怎么样,对于这三种情况所展示的效果都还不错吧。
好了,就到这里,各位看官,没事留个言,顶一个呗~
源代码点击下载
Android 自己定义View (二) 进阶的更多相关文章
- Android 自己定义View须要重写ondraw()等方法
Android 自己定义View须要重写ondraw()等方法.这篇博客给大家说说自己定义View的写法,须要我们继承View,然后重写一些 方法,方法多多,看你须要什么方法 首先写一个自己定义的V ...
- 【Android自己定义View实战】之自己定义超简单SearchView搜索框
[Android自己定义View实战]之自己定义超简单SearchView搜索框 这篇文章是对之前文章的翻新,至于为什么我要又一次改动这篇文章?原因例如以下 1.有人举报我抄袭,原文链接:http:/ ...
- Android 自己定义View学习(2)
上一篇学习了基本使用方法,今天学一下略微复杂一点的.先看一下效果图 为了完毕上面的效果还是要用到上一期开头的四步 1,属性应该要有颜色,要有速度 <?xml version="1.0& ...
- Android自己定义view之measure、layout、draw三大流程
自己定义view之measure.layout.draw三大流程 一个view要显示出来.须要经过測量.布局和绘制这三个过程,本章就这三个流程具体探讨一下.View的三大流程具体分析起来比較复杂,本文 ...
- Android自己定义View的实现方法
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了.回 ...
- Android自己定义View基础篇(三)之SwitchButton开关
自己定义View基础篇(二) 自己定义View基础篇(一) 自己定义View原理 我在解说之前,先来看看效果图,有图有真相:(转换gif图片效果太差) 那来看看真实图片: 假设你要更改样式,请改动例如 ...
- 手把手带你画一个 时尚仪表盘 Android 自己定义View
拿到美工效果图.咱们程序猿就得画得一模一样. 为了不被老板喷,仅仅能多练啊. 听说你认为前面几篇都so easy,那今天就带你做个相对照较复杂的. 转载请注明出处:http://blog.csdn.n ...
- android 自己定义View之SubmitView
转载请注明出处:王亟亟的大牛之路 近期看了一大堆的自己定义View多数都能够充当耗时操作的交互界面.再接再厉再传一个SubmitView.一个和可用于模仿提交等待与用户交互用的一个自己定义View 效 ...
- Android 自己定义View (四) 视频音量调控
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24529807 今天没事逛eoe,看见有人求助要做一个以下的效果,我看以下一哥们说 ...
随机推荐
- HTML+CSS - 搜索 And 高级搜索
- PHP学习之-1.1 PHP 可以做什么?
PHP 可以做什么? 为什么要学习PHP,"我可以用javascript来实现程序的编写."但是javascript的能力是有限的,javascript通常运行在浏览器(客户端), ...
- Koa -- 基于 Node.js 平台的下一代 web 开发框架
http://koa.bootcss.com/ 多研究点 react 和 nodejs 这个是未来
- 做自己的Android ROM,屏蔽对framework中的系统APK的签名检查
最近两天一直在尝试更新Android中的关键库以达到定制ROM的效果,中间比较曲折,记录下来供自己和大家参考. 因为我需要基于Android的原生代码做一定的修改,所以如果无法将我自己编译出的APK或 ...
- 编程算法 - 有序双循环链表的插入 代码(C)
有序双循环链表的插入 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 有序双循环链表的插入, 须要找到插入位置, 能够採用, 两个指针, 一个在前, 一 ...
- POJ 3481 & HDU 1908 Double Queue (map运用)
题目链接: PKU:http://poj.org/problem?id=3481 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1908 Descript ...
- Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...
- Friends
Description Mike has many friends. Here are nine of them: Alice, Bob, Carol, Dave, Eve, Frank, Glori ...
- 头文件 boost/cstdint.hpp
Header boost/cstdint.hpp 头文件 boost/cstdint.hpp 头文件 <boost/cstdint.hpp> 提供了用于编写要求指定整数宽度的可移植代码的 ...
- mssql数据库游标批量改动符合条件的记录
//需求:因为项目刚上传,没有票数,为了表现出一定的人气,须要在一開始把各项目的票数赋一个值 , 但每一个项目不能一样,否则easy看出问题,呵呵 . DECLARE @Id varchar(50) ...