当前位置:文档之家› android 自定义圆角头像以及使用declare-styleable进行配置属性解析

android 自定义圆角头像以及使用declare-styleable进行配置属性解析

android 自定义圆角头像以及使用declare-styleable进行配置属性解析
android 自定义圆角头像以及使用declare-styleable进行配置属性解析

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(https://www.doczj.com/doc/104970664.html,PLEX_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(STA TE_INSTANCE, super.onSaveInstanceState());

bundle.putInt(STA TE_TYPE, type);

bundle.putInt(STA TE_BORDER_RADIUS, mCornerRadius);

bundle.putInt(STA TE_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(STA TE_BORDER_RADIUS);

this.pressedColor = bundle.getInt(STA TE_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,都可以。之后在里面配置https://www.doczj.com/doc/104970664.html,are-styleable ,name为RoundImageView

[html] view plain copy 在CODE上查看代码片派生到我的代码片

这里的format就是格式,里面的就是这个属性对应的格式,下面列出来大致的格式有:1. reference:参考某一资源ID,以此类推

(1)属性定义:

(2)属性使用:

android:layout_width = "42dip"

android:layout_height = "42dip"

android:background = "@drawable/图片ID"

/>

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 https://www.doczj.com/doc/104970664.html,lain copy 在CODE上查看代码片派生到我的代码片

< android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/contact_head_img"

android:layout_width="@dimen/contact_photo_size"

android:layout_height="@dimen/contact_photo_size"

android:background="@null"

android:clickable="false"

android:focusable="false"

android:scaleType="fitCenter"

android:layout_marginBottom="@dimen/contact_picture_margin_top_bottom"

android:layout_marginLeft="@dimen/contact_view_margin_left"

android:layout_marginTop="@dimen/contact_picture_margin_top_bottom"

roundImageattr:corner_radius="5dp"

roundImageattr:pressed_color="@color/bottom_bar_bg_color"

roundImageattr:type="circle"

/>

注意这里首先要配置这个attr:即xmlns:roundImageattr=" "

对应结构是:xmlns:自己定义的名称="你程序的package包名"

(包名即在AndroidManifest.xml里面可看到,package="com.test.demo" 这样格式的)

之后在布局中自定义的类中设相关属性:

自己定义的名称:自定义的属性="属性值";

3.最后在自定义控件的构造方法中获取你配置的属性值:

[html] view plain copy 在CODE上查看代码片派生到我的代码片

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(https://www.doczj.com/doc/104970664.html,PLEX_UNIT_DIP,

CORNER_RADIUS_DEFAULT, getResources()

.getDisplayMetrics()));// 默认为10dp type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circle

a.recycle();

}

android 自定义圆角头像以及使用declare-styleable进行配置属性解析

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; /** * 圆角大小的默认值

windowsXP下Android安卓开发环境搭建详细教程及图解

注:本教程是讲解在Windows XP下搭建安卓开发环境的。 安装目录: 步骤1 安装JDK 步骤2 安装Android SDK 步骤3 安装Tomcat 步骤4 安装Ant 步骤5 安装Eclipse 步骤6 安装Eclipse的ADT插件 步骤7 在图形界面下管理AVD 步骤8 设置Android系统语言 本教程的软件可以从我博客“绿杨芳草”下载。 方法/步骤 1、安装JDK 运行安装程序【jdk-6u22-windows-i586-p.exe】,分别点击下一步进行安装。 在安装过程中先后会出现两次选择安装目录的界面,全部改为以下路径: jdk安装目录:C:\Java\jdk1.6.0_22 jre安装目录:C:\Java\jre6\

安装好之后,配置环境变量: 打开环境变量窗口方法:右键【我的电脑】--单击【属性】--单击【高级】--单击【环境变量】。 在上方的用户变量中依次新建如下变量,并分别填入如下路径: 变量名:JAVA_HOME 变量值:C:\Java\jdk1.6.0_22 变量名:PATH 变量值:%JAVA_HOME%/bin 变量名:CLASSPATH 变量值:.;%JAVA_HOME%/lib/tools.jar;%JAVA_HOME%/lib/dt.jar 图1 配置完成之后,分别点击【开始】--【运行】--输入【cmd】--输入【javac】--按【回车键】,若看到以下信息,则代表配置成功。

图2 2、安装Android SDK 将【android-sdk_r17-windows.zip】解压到E:\Android目录下(Android目录自己新建,以后所有关于Android开发相关软件都会统一放到该目录中),得到一个android-sdk-windows 文件夹,该文件夹包含如下文件结构: add-ons:该目录下存放额外的附件软件。刚解压后,该目录为空。 platforms:该目录下存放不同版本的Android版本。刚解压后,该目录为空。 tools:该目录下存放了大量Android开发、调试的工具。 SDK Manager.exe:该程序就是Android SDK和AVD(Android虚拟设备)管理器。 通过该工具可以管理Android SDK和AVD。 运行E:\Android\android-sdk-windows目录下的【SDK Manager.exe】 然后等待更新...(该步骤必须联网,因为SDK安装包需要在线获取)。 在更新的过程中若遇到如下的提示窗口:

Android开发规范参考文档

Android开发参考文档 一、Android编码规范 1. java代码中不出现中文,最多注释中可以出现中文.xml代码中注释 2. 成员变量,局部变量、静态成员变量命名、常量(宏)命名 1). 成员变量: activity中的成员变量以m开头,后面的单词首字母大写(如Button mBackButton; String mName);实体类和自定义View的成员变量可以不以m开头(如ImageView imageView,String name), 2). 局部变量命名:只能包含字母,组合变量单词首字母出第一个外,都为大写,其他字母都为小写 3). 常量(宏)命名: 只能包含字母和_,字母全部大写,单词之间用_隔开UMENG_APP_KEY 3. Application命名 项目名称+App,如SlimApp,里面可以存放全局变量,但是杜绝存放过大的实体对象4. activity和其中的view变量命名 activity命名模式为:逻辑名称+Activity view命名模式为:逻辑名称+View 建议:如果layout文件很复杂,建议将layout分成多个模块,每个模块定义一个moduleViewHolder,其成员变量包含所属view 5. layout及其id命名规则 layout命名模式:activity_逻辑名称,或者把对应的activity的名字用“_”把单词分开。

命名模式为:view缩写_模块名称_view的逻辑名称, 用单词首字母进行缩写 view的缩写详情如下 LayoutView:lv RelativeView:rv TextView:tv ImageView:iv ImageButton:ib Button:btn 6. strings.xml中的 1). id命名模式: activity名称_功能模块名称_逻辑名称/activity名称_逻辑名称/common_逻辑名称,strings.xml中,使用activity名称注释,将文件内容区分开来 2). strings.xml中使用%1$s实现字符串的通配,合起来写 7. drawable中的图片命名 命名模式:activity名称_逻辑名称/common_逻辑名称/ic_逻辑名称 (逻辑名称: 这是一个什么样的图片,展示功能是什么) 8. styles.xml 将layout中不断重现的style提炼出通用的style通用组件,放到styles.xml中; 9. 使用layer-list和selector,主要是View onCclick onTouch等事件界面反映

Android平台我的日记设计文档

Android平台我的日记 设计文档 项目名称:mydiray 项目结构示意: 阶段任务名称(一)布局的设计 开始时间: 结束时间: 设计者: 梁凌旭 一、本次任务完成的功能 1、各控件的显示 二、最终功能及效果 三、涉及知识点介绍 四、代码设计 activity_main.xml:

android:layout_centerHorizontal="true" android:layout_marginTop="88dp" android:text="@string/wo" android:textSize="35sp"/>

相关文档 最新文档