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,看见有人求助要做一个以下的效果,我看以下一哥们说 ...
随机推荐
- linux命令:rm
删文件要一个个回答y,谁有好办法自动删除? rm -rf 用rm递归删除目录下面的所有.o文件: find . -name "*.o" | xargs rm -f :
- jssdk微信图片上传功能
/*wx.config({ debug: false, appId: data.appid, timestamp: data.timestamp, nonceStr: data.nonceStr, s ...
- Web前端,高性能优化
高性能HTML 一.避免使用iframe iframe也叫内联frame,可将一个HTML文档嵌入另一个HTML文档中. iframe的好处是,嵌入的文档独立于父文档,通常也借此使浏览器模拟多线程.缺 ...
- 九度OnlineJudge之1014:排名
题目描述: 今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名.给定录取分数线,请你写程序找出最后通过分数线的考生,并将他 ...
- js实现密码强度验证
<html> <head> <meta http-equiv="content-type" content="text/html" ...
- 网页插入QQ 无需加好友
<p>联系方式:1073351325<a href="tencent://message/?Menu=yes&uin=1073351325&Site=dsf ...
- BestR #31
hdu 5178 求|a[i] - a[j]| <= k (i < j) <i,j>的对数,一开始认为数据不大就直接ans++了,后来结果出来才知道,啊啊啊,too young ...
- Maven插件之portable-config-maven-plugin(不同环境打包)
在大型的项目组中,分不同的开发环境,测试环境,生产环境(说白了就是配置文件不同,或者数据源,或者服务器,或者数据库等);问题来了,如何使用Maven针对不同的环境来打包呢? Maven提供了Profi ...
- Android事件详解——拖放事件DragEvent
1.Android拖放框架的作用? 利用Android的拖放框架,可以让用户用拖放手势把一个View中的数据移到当前layout内的另一个View中去. 2.拖放框架的内容? 1)拖放事件类 2)拖放 ...
- jquery的ajax提交form表单方式总结
方法一: function AddHandlingFeeToRefund() { var AjaxURL= "../OrderManagement/AjaxModifyOrderServic ...