自定义圆形控件RoundImageView并认识一下attr.xml

编程之家收集整理的这篇文章主要介绍了自定义圆形控件RoundImageView并认识一下attr.xml编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

(点击上方公众号,可快速关注)


公众号:smart_android

作者:耿广龙|loonggg

点击“阅读原文”,可查看更多内容和干货


昨天我们学习了自定义图片文字的ImageTextButton,非常简单,我承诺给大家要讲一下用自定义属性的方式学习真正的实现自定义控件,在布局文件中使用属性的方式就需要用到attr.xml这个文件,以前很多同学问我这个是干什么的,现在学了这篇内容,你就差不多知道了,以后就别再问了。自定义圆形控件 RoundImageView ,我相信大家在开发中会经常遇到设置圆形头像的情况,因为这样的头像显得漂亮。怎么做呢?先看效果图:


讲之前解释一下attr.xml的作用,我用土话废话说,这样容易理解:比如我自定义一个控件,怎么实现呢,以RoundImageView为例,首先是继承ImageView,然后实现其构造函数,在构造函数中,获取attr.xml中的属性值(再次解释:这里获取的具体的这个属性的值是怎么来的呢?比如颜色和宽度,这个在attr.xml中定义了相关的名字,而在使用RoundImageView的xml布局文件中,我们会为其设置值,这里需要用的值,就是从那里设置的),并设置在本控件中,然后继承onDraw方法,画出自己想要的图形或者形状即可。


由于我在代码中加了很多注释,我就直接给大家介绍代码了哈。


第一步:定义RoundImageView的属性配置文件:attr.xml


<?xml version="1.0" encoding="utf-8"?>

<resources>


<declare-styleable name="round_image_view">

<attr name="border_width" format="dimension" />

<attr name="border_incolor" format="color" />

<attr name="border_outcolor" format="color"></attr>

</declare-styleable>


</resources>


第二步:自定义圆形控件RoundImageView并继承ImageView


package net.loonggg.rivd.demo.view;


import net.loonggg.rivd.demo.R;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PorterDuff;

import android.graphics.PorterDuffXfermode;

import android.graphics.Rect;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.graphics.drawable.NinePatchDrawable;

import android.util.AttributeSet;

import android.widget.ImageView;


/**

*

* @author loongggdroid

*/

public class RoundImageView extends ImageView {

private int mBorderThickness = 0;

private Context mContext;

private int defaultColor = 0xFFFFFFFF;

// 外圆边框颜色

private int mBorderOutsideColor = 0;

// 内圆边框颜色

private int mBorderInsideColor = 0;

// RoundImageView控件默认的长、宽

private int defaultWidth = 0;

private int defaultHeight = 0;


public RoundImageView(Context context) {

super(context);

mContext = context;

}


public RoundImageView(Context context,AttributeSet attrs) {

super(context,attrs);

// 设置RoundImageView的属性值,比如颜色,宽度等

setRoundImageViewAttributes(attrs);

// 从attr.xml文件获取属性值,并给RoundImageView设置

private void setRoundImageViewAttributes(AttributeSet attrs) {

TypedArray a = mContext.obtainStyledAttributes(attrs,

R.styleable.round_image_view);

mBorderThickness = a.getDimensionPixelSize(

R.styleable.round_image_view_border_width,0);

mBorderOutsideColor = a.getColor(

R.styleable.round_image_view_border_outcolor,defaultColor);

mBorderInsideColor = a.getColor(

R.styleable.round_image_view_border_incolor,89); font-size: 14px; white-space: pre;"> a.recycle();

// 具体解释:比如我自定义一个控件,怎么实现呢,以RoundImageView为例,首先是继承ImageView,然后实现其构造函数,在构造函数中,获取attr中的属性值(再次解释:这里获取的具体的这个属性的值是怎么来的呢?比如颜色和宽度,这个在attr.xml中定义了相关的名字,而在使用RoundImageView的xml布局文件中,我们会设置其值,这里需要用的值,就是从那里设置的),并设置在本控件中,然后继承onDraw方法,画出自己想要的图形或者形状即可。

/**

* 这个是继承的父类的onDraw方法

*

* onDraw和下面的方法不用管,基本和学习自定义没关系,就是实现怎么画圆的,你可以改变下面代码试着画三角形头像,哈哈

*/

@Override

protected void onDraw(Canvas canvas) {

Drawable drawable = getDrawable();

if (drawable == null) {

return;

}

if (getWidth() == 0 || getHeight() == 0) {

this.measure(0,89); font-size: 14px; white-space: pre;"> if (drawable.getClass() == NinePatchDrawable.class)

Bitmap b = ((BitmapDrawable) drawable).getBitmap();

Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888,true);

if (defaultWidth == 0) {

defaultWidth = getWidth();

if (defaultHeight == 0) {

defaultHeight = getHeight();

int radius = 0;

// 这里的判断是如果内圆和外圆设置的颜色值不为空且不是默认颜色,就定义画两个圆框,分别为内圆和外圆边框

if (mBorderInsideColor != defaultColor

&& mBorderOutsideColor != defaultColor) {

radius = (defaultWidth < defaultHeight ? defaultWidth

: defaultHeight) / 2 - 2 * mBorderThickness;

// 画内圆

drawCircleBorder(canvas,radius + mBorderThickness / 2,89); font-size: 14px; white-space: pre;"> mBorderInsideColor);

// 画外圆

+ mBorderThickness / 2,mBorderOutsideColor);

} else if (mBorderInsideColor != defaultColor

&& mBorderOutsideColor == defaultColor) {// 这里的是如果内圆边框不为空且颜色值不是默认值,就画一个内圆的边框

: defaultHeight) / 2 - mBorderThickness;

} else if (mBorderInsideColor == defaultColor

&& mBorderOutsideColor != defaultColor) {// 这里的是如果外圆边框不为空且颜色值不是默认值,就画一个外圆的边框

mBorderOutsideColor);

} else {// 这种情况是没有设置属性颜色的情况下,即没有边框的情况

: defaultHeight) / 2;

Bitmap roundBitmap = getCroppedRoundBitmap(bitmap,radius);

canvas.drawBitmap(roundBitmap,defaultWidth / 2 - radius,defaultHeight

/ 2 - radius,null);

* 获取裁剪后的圆形图片

* @param bmp

* @param radius

* 半径

* @return

public Bitmap getCroppedRoundBitmap(Bitmap bmp,int radius) {

Bitmap scaledSrcBmp;

int diameter = radius * 2;

// 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片

int bmpWidth = bmp.getWidth();

int bmpHeight = bmp.getHeight();

int squareWidth = 0,squareHeight = 0;

int x = 0,y = 0;

Bitmap squareBitmap;

if (bmpHeight > bmpWidth) {// 高大于宽

squareWidth = squareHeight = bmpWidth;

x = 0;

y = (bmpHeight - bmpWidth) / 2;

// 截取正方形图片

squareBitmap = Bitmap.createBitmap(bmp,x,y,squareWidth,89); font-size: 14px; white-space: pre;"> squareHeight);

} else if (bmpHeight < bmpWidth) {// 宽大于高

squareWidth = squareHeight = bmpHeight;

x = (bmpWidth - bmpHeight) / 2;

y = 0;

} else {

squareBitmap = bmp;

if (squareBitmap.getWidth() != diameter

|| squareBitmap.getHeight() != diameter) {

scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap,diameter,89); font-size: 14px; white-space: pre;"> diameter,89); font-size: 14px; white-space: pre;"> scaledSrcBmp = squareBitmap;

Bitmap output = Bitmap.createBitmap(scaledSrcBmp.getWidth(),89); font-size: 14px; white-space: pre;"> scaledSrcBmp.getHeight(),Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(output);


Paint paint = new Paint();

Rect rect = new Rect(0,scaledSrcBmp.getWidth(),89); font-size: 14px; white-space: pre;"> scaledSrcBmp.getHeight());


paint.setAntiAlias(true);

paint.setFilterBitmap(true);

paint.setDither(true);

canvas.drawARGB(0,89); font-size: 14px; white-space: pre;"> canvas.drawCircle(scaledSrcBmp.getWidth() / 2,89); font-size: 14px; white-space: pre;"> scaledSrcBmp.getHeight() / 2,scaledSrcBmp.getWidth() / 2,89); font-size: 14px; white-space: pre;"> paint);

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

canvas.drawBitmap(scaledSrcBmp,rect,paint);

bmp = null;

squareBitmap = null;

scaledSrcBmp = null;

return output;

* 画边缘的圆,即内圆或者外圆

private void drawCircleBorder(Canvas canvas,int radius,int color) {

/* 去锯齿 */

paint.setColor(color);

/* 设置paint的 style 为STROKE:空心 */

paint.setStyle(Paint.Style.STROKE);

/* 设置paint的外框宽度 */

paint.setStrokeWidth(mBorderThickness);

canvas.drawCircle(defaultWidth / 2,defaultHeight / 2,radius,89); font-size: 14px;">}


第三步:在xml配置中使用控件:activity_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

xmlns:loonggg="http://schemas.android.com/apk/res-auto"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:gravity="center_horizontal"

android:orientation="vertical"

android:paddingTop="20dp" >


<!-- 没有指定圆形ImageView属性时,默认没有外边圆颜色 -->


<net.loonggg.rivd.demo.view.RoundImageView

android:layout_width="200dp"

android:layout_height="200dp"

android:src="@drawable/pigu" />


<!-- border_outcolor 外部圆圈的颜色 -->

<!-- border_incolor 内部部圆圈的颜色 -->

<!-- border_width 外圆和内圆的宽度 -->

<!-- 再解释一遍,我们在布局中使用了我们在sttr中定义的属性,并在这里的布局文件中赋了值,所以在RoundImageView类中的结构体设置属性使用的值,就是我们在这里赋的,如果不使用attr.xml文件也可以,这样就是我们在activity中使用这个控件的时候,再设置值,不如这样方便罢了,比如昨天我们讲的【自定义图片文字的ImageTextButton】那样罢了 -->


<!-- 说明:这里的loonggg可能大家不太明白,这个名字可以随便起,你们也可以自己随便定义,只要上下统一即可,在布局声明的时候一样就行,比如我在布局顶端是这样声明的 xmlns:loonggg="http://schemas.android.com/apk/res-auto" -->


android:layout_marginTop="20dp"

android:src="@drawable/pigu"

loonggg:border_incolor="#000fff"

loonggg:border_outcolor="#fff000"

loonggg:border_width="10dp" />


</LinearLayout>


废话不多说了,直接上demo,获取demo的方法跟以前一样,只需在公众号里回复关键字“3”即可获得。


【特别推荐↓】



「非著名程序员」本人建立了一个高端Android微信交流群,如果有想加入的请先加我个人微信号:loonggg ,具体加入条件非常简单,加我个人微信号时,请备注为:加群,到时会告诉你具体的加入流程,感谢

总结

以上是编程之家为你收集整理的自定义圆形控件RoundImageView并认识一下attr.xml全部内容,希望文章能够帮你解决自定义圆形控件RoundImageView并认识一下attr.xml所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢寻找一群志同道合、互帮互助的学习伙伴,可以点击下方链接加入:
编程之家官方1群
编程之家官方2群
编程之家官方3群
编程之家官方4群

相关文章

猜你在找的XML相关文章

引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满足人的生产生活需要而产生的。具体到小小的一个手机,里面蕴含的技术也是浩如烟海,是几千年来人类科技的结晶,单个人穷其一生也未必能掌握其一角。不过个人一直认为基本的技术和思想是放之四海而皆准的,许多技术未必需要我们从头到尾再研究一遍,我们要做的就是站在巨人的肩膀上,利用其成果来为人们的需求服务。 随着移动互联网时代的大潮,越来越多
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1、不认识到犯错,然后得到永久的教训。 2、认识JAXB 3、代码实战   1、不认识到犯错,然后得到永久的教训。   也不是所谓的教训吧,真正的教训来自于对错误的剖析理解很深刻。然后有种“吃一堑,长一智”的感觉才叫教训。近日
http://blog.jobbole.com/79252/ 引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满足人的生产生活需要而产生的。具体到小小的一个手机,里面蕴含的技术也是浩如烟海,是几千年来人类科技的结晶,单个人穷其一生也未必能掌握其一角。不过个人一直认为基本的技术和思想是放之四海而皆准的,许多技术未必需要我们从头到尾再研究一遍,我们要做的就是站在巨人的肩膀上,利用
(点击上方公众号,可快速关注) 公众号:smart_android 作者:耿广龙|loonggg 点击“阅读原文”,可查看更多内容和干货 昨天我们学习了自定义带图片和文字的ImageTextButton,非常简单,我承诺给大家要讲一下用自定义属性的方式学习真正的实现自定义控件,在布局文件中使用属性的方式就需要用到attr.xml这个文件,以前很多同学问我这个是干什么的,现在学了这篇内容,你就差不多
引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满足人的生产生活需要而产生的。具体到小小的一个手机,里面蕴含的技术也是浩如烟海,是几千年来人类科技的结晶,单个人穷其一生也未必能掌握其一角。不过个人一直认为基本的技术和思想是放之四海而皆准的,许多技术未必需要我们从头到尾再研究一遍,我们要做的就是站在巨人的肩膀上,利用其成果来为人们的需求服务。 随着移动互联网时代的大潮,越来越多
 (点击上方公众号,可快速关注) 来源: Long Luo 的博客 链接:http://longluo.github.io/blog/20141031/master-XML-JSON-and-how-to-aprse-them-in-10-minutes/ 引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满足人的生产生活需要而产生的。具体到小小的一个手机,里面蕴含的技术也是浩
接上文 2.4 如何解析JSON? Android JSON所有相关类,都在org.json包下。 包括JSONObject、JSONArray、JSONStringer、JSONTokener、JSONWriter、JSONException。 <1>. 常见方法 目前JSON解析有2种方法,分别是get和opt方法,可以使用JSON 那么使用get方法与使用opt方法的区别是? JsonObj
原文出处:  Long Luo 的博客(@Long_Luo)   引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满足人的生产生活需要而产生的。具体到小小的一个手机,里面蕴含的技术也是浩如烟海,是几千年来人类科技的结晶,单个人穷其一生也未必能掌握其一角。不过个人一直认为基本的技术和思想是放之四海而皆准的,许多技术未必需要我们从头到尾再研究一遍,我们要做的就是站在巨人的肩膀上,
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注