android 自定义圆角头像以及使用declare-styleable进行配置属解析.doc_第1页
android 自定义圆角头像以及使用declare-styleable进行配置属解析.doc_第2页
android 自定义圆角头像以及使用declare-styleable进行配置属解析.doc_第3页
android 自定义圆角头像以及使用declare-styleable进行配置属解析.doc_第4页
android 自定义圆角头像以及使用declare-styleable进行配置属解析.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

android 自定义圆角头像以及使用declare-styleable进行配置属性解析由于最新项目中正在检查UI是否与效果图匹配,结果关于联系人模块给的默认图片是四角稍带弧度的圆角,而我们截取的图片是正方形的,现在要给应用统一替换。应用中既用到大圆角头像(即整个头像是圆的)又用到四角稍带弧度的圆角头像,封装一下以便重用。以下直接见代码java view plain copy 在CODE上查看代码片派生到我的代码片package com.test.demo; import com.test.demo.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.widget.ImageView; /* * 圆角imageview */ public class RoundImageView extends ImageView private static final String TAG = RoundImageView; /* * 图片的类型,圆形or圆角 */ private int type; public static final int TYPE_CIRCLE = 0; public static final int TYPE_ROUND = 1; /* * 圆角大小的默认值 */ private static final int CORNER_RADIUS_DEFAULT = 10; /* * 圆角的大小 */ private int mCornerRadius; /* * 绘图的Paint */ private Paint mBitmapPaint; / 按下状态颜色 private Paint mPressedColorPaint; private int pressedColor; /* * 圆角的半径 */ private int mRadius; /* * 3x3 矩阵,主要用于缩小放大 */ private Matrix mMatrix; /* * view的宽度 */ private int mWidth; private RectF mRoundRect; public RoundImageView(Context context, AttributeSet attrs) super(context, attrs); mMatrix = new Matrix(); mBitmapPaint = new Paint(); mBitmapPaint.setAntiAlias(true); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView); pressedColor = a.getColor(R.styleable.RoundImageView_pressed_color, -1); if (pressedColor != -1) mPressedColorPaint = new Paint(); mPressedColorPaint.setAntiAlias(true); mPressedColorPaint.setColor(pressedColor); mCornerRadius = a.getDimensionPixelSize( R.styleable.RoundImageView_corner_radius, (int) TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS_DEFAULT, getResources() .getDisplayMetrics();/ 默认为10dp type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);/ 默认为Circle a.recycle(); public RoundImageView(Context context) this(context, null); Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) super.onMeasure(widthMeasureSpec, heightMeasureSpec); /* * 如果类型是圆形,则强制改变view的宽高一致,以小值为准 */ if (type = TYPE_CIRCLE) mWidth = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec); mRadius = mWidth / 2; /* * 初始化BitmapShader */ private void setUpShader() Drawable drawable = getDrawable(); if (drawable = null) return; Bitmap bmp = drawableToBitamp(drawable); / 将bmp作为着色器,就是在指定区域内绘制bmp / 渲染图像,使用图像为绘制图形着色 BitmapShader mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP); float scale = 1.0f; if (type = TYPE_CIRCLE) / 拿到bitmap宽或高的小值 int bSize = Math.min(bmp.getWidth(), bmp.getHeight(); scale = mWidth * 1.0f / bSize; else if (type = TYPE_ROUND) if (!(bmp.getWidth() = getWidth() & bmp.getHeight() = getHeight() / 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; scale = Math.max(getWidth() * 1.0f / bmp.getWidth(), getHeight() * 1.0f / bmp.getHeight(); / shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.setScale(scale, scale); / 设置变换矩阵 mBitmapShader.setLocalMatrix(mMatrix); / 设置shader mBitmapPaint.setShader(mBitmapShader); Override protected void onDraw(Canvas canvas) if (getDrawable() = null) return; setUpShader(); if (type = TYPE_ROUND) canvas.drawRoundRect(mRoundRect, mCornerRadius, mCornerRadius, mBitmapPaint); if (isPressed() & mPressedColorPaint != null) canvas.drawRoundRect(mRoundRect, mCornerRadius, mCornerRadius, mPressedColorPaint); else canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint); if (isPressed() & mPressedColorPaint != null) canvas.drawCircle(mRadius, mRadius, mRadius, mPressedColorPaint); Override protected void onSizeChanged(int w, int h, int oldw, int oldh) super.onSizeChanged(w, h, oldw, oldh); Log.d(TAG, onSizeChanged,w= + w + ,h= + h + ,oldw= + oldw + ,oldh= + oldh); / 圆角图片的范围 if (type = TYPE_ROUND) mRoundRect = new RectF(0, 0, w, h); /* * drawable转bitmap */ private Bitmap drawableToBitamp(Drawable drawable) if (drawable instanceof BitmapDrawable) BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; private static final String STATE_INSTANCE = state_instance; private static final String STATE_TYPE = state_type; private static final String STATE_BORDER_RADIUS = state_border_radius; private static final String STATE_PRESSED_COLOR = state_pressed_color; Override protected Parcelable onSaveInstanceState() Bundle bundle = new Bundle(); bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState(); bundle.putInt(STATE_TYPE, type); bundle.putInt(STATE_BORDER_RADIUS, mCornerRadius); bundle.putInt(STATE_PRESSED_COLOR, pressedColor); return bundle; Override protected void onRestoreInstanceState(Parcelable state) if (state instanceof Bundle) Bundle bundle = (Bundle) state; super.onRestoreInstanceState(Bundle) state) .getParcelable(STATE_INSTANCE); this.type = bundle.getInt(STATE_TYPE); this.mCornerRadius = bundle.getInt(STATE_BORDER_RADIUS); this.pressedColor = bundle.getInt(STATE_PRESSED_COLOR); if (pressedColor != -1) mPressedColorPaint = new Paint(); mPressedColorPaint.setAntiAlias(true); mPressedColorPaint.setColor(pressedColor); else super.onRestoreInstanceState(state); public void setType(int type) if (this.type != type) this.type = type; if (this.type != TYPE_ROUND & this.type != TYPE_CIRCLE) this.type = TYPE_CIRCLE; requestLayout(); Override protected void dispatchSetPressed(boolean pressed) / imageView.setClickable(true),或imageView.setOnClickListener时才可触发dispatchSetPressed super.dispatchSetPressed(pressed); invalidate(); declare-styleable:declare-styleable是给自定义控件添加自定义属性用的。发现它的很多属性都是通过自定义控件并设定相关的配置属性进行配置,即我们需要1.首先,先写attrs.xml在res-vlaues文件夹下创建资源文件attrs.xml或则自定义一个资源文件xx.xml,都可以。之后在里面配置are-styleable ,name为RoundImageViewhtml view plain copy 在CODE上查看代码片派生到我的代码片 这里的format就是格式,里面的就是这个属性对应的格式,下面列出来大致的格式有:1. reference:参考某一资源ID,以此类推(1)属性定义:(2)属性使用:2. color:颜色值3. boolean:布尔值4. dimension:尺寸值。注意,这里如果是dp那就会做像素转换5. float:浮点值。6. integer:整型值。7. string:字符串8. fraction:百分数。9. enum:枚举值10. flag:是自己定义的,类似于 android:gravity=top,就是里面对应了自己的属性值。11. reference|color:颜色的资源文件。12.reference|boolean:布尔值的资源文件注意:/由于reference是从资源文件中获取:所以在XML文件中写这个属性的时候必须 personattr:name=string/app_name这种格式,否则会出错2.设置好属性文件后,在使用的布局中写相关配置:html view lain copy 在CODE上查看代码片派生到我的代码片 注意这里首先要配置这个attr:即 xmlns:roundImageattr= 对应结构是:xmlns:自己定义的名称=你程序的package包名 (包名即在AndroidManifest.xml里面可看到, package=com.test.demo 这样格式的)之后在布局中自定义的类中设相关属性:自己定义的名称:自定义的属性 =属性值;3.最后在自定义控件的构造方法中获取你配置的属性值:html view plain copy 在C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论