Android自定义带边框的圆形view

由于项目需要,需要做一个圆形的带边框并且里边还有文字的view →_→

↓↓↓↓这样↓↓↓↓

如果在布局文件中做的话是非常麻烦的,而且复用性也不高。所以想到用自定义一个view的来实现该功能,这样封装性和复用性就会相对提高,可方便在以后类似的项目中使用。可能也有同学有过这样的需求,所以在这分享出来供大家参考,不足之处还请多多指点。

看代码:

  1package com.stock.manage.friend.view;import android.content.Context;

  2 import android.content.res.TypedArray;
  3 import android.graphics.Bitmap;
  4 import android.graphics.Bitmap.Config;
  5 import android.graphics.BitmapFactory;
  6 import android.graphics.Canvas;
  7 import android.graphics.Color;
  8 import android.graphics.Paint;
  9 import android.graphics.Paint.FontMetrics;
 10 import android.graphics.PorterDuff;
 11 import android.graphics.PorterDuffXfermode;
 12 import android.util.AttributeSet;
 13 import android.view.View;
 14
 15 /**
 16  * 自定义View 实现圆 圆形等效果
 17  * @author chengzijian
 18  *
 19  */
 20 public class CustomImageView extends View {
 21
 22     /**
 23      * 图片
 24      */
 25     private Bitmap mSrc;
 26
 27     /**
 28      * 控件的宽度
 29      */
 30     private int mWidth;
 31     /**
 32      * 控件的高度
 33      */
 34     private int mHeight;
 35     /**
 36      *内颜色
 37      */
 38     private int inColor;
 39     /**
 40      * 边框颜色
 41      */
 42     private int outColor;
 43     /**
 44      *边框粗细
 45      */
 46     private int outStrokeWidth;
 47     /**
 48      * 文字
 49      */
 50     private String mText;
 51     /**
 52      * 文字颜色
 53      */
 54     private int mTextColor;
 55     /**
 56      * 文字大小
 57      */
 58     private float mTextSize;
 59
 60     public CustomImageView(Context context, AttributeSet attrs) {
 61         this(context, attrs, 0);
 62     }
 63
 64     public CustomImageView(Context context) {
 65         this(context, null);
 66     }
 67
 68     /**
 69      * 初始化一些自定义的参数
 70      *
 71      * @param context
 72      * @param attrs
 73      * @param defStyle
 74      */
 75     public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
 76         super(context, attrs, defStyle);
 77
 78         TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.StockManage);
 79         mSrc = BitmapFactory.decodeResource(getResources(), array.getResourceId(R.styleable.StockManage_icon, -1));
 80         if (mSrc == null) {
 81             inColor = array.getColor(R.styleable.StockManage_inColor, Color.WHITE);
 82         }
 83         mTextColor = array.getColor(R.styleable.StockManage_textColor, Color.BLACK);
 84         outColor = array.getColor(R.styleable.StockManage_outColor, -1);
 85         outStrokeWidth = array.getDimensionPixelSize(R.styleable.StockManage_stroke, 0);
 86         mWidth = array.getDimensionPixelSize(R.styleable.StockManage_width, 0);
 87         mHeight = array.getDimensionPixelSize(R.styleable.StockManage_height, 0);
 88         mText = array.getString(R.styleable.StockManage_text);
 89         mTextSize = array.getDimension(R.styleable.StockManage_textSize,R.dimen.text_size_sub);// 如果设置为DP等单位,会做像素转换
 90         //释放资源
 91         array.recycle();
 92     }
 93
 94     /**
 95      * 计算控件的高度和宽度
 96      */
 97     @Override
 98     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 99         setMeasuredDimension(mWidth, mHeight);
100     }
101
102     /**
103      * 绘制
104      */
105     @Override
106     protected void onDraw(Canvas canvas) {
107
108         int min = Math.min(mWidth, mHeight);
109         /**
110          * 长度如果不一致,按小的值进行压缩
111          */
112         if (mSrc != null) {
113             mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);
114             canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);
115         } else {
116             canvas.drawBitmap(createCircleImage(null, min), 0, 0, null);
117         }
118     }
119
120     /**
121      * 根据原图和边长绘制圆形图片
122      *
123      * @param source
124      *            color 这两个参数只能取一个
125      * @param min
126      * @return
127      */
128     private Bitmap createCircleImage(Bitmap source, int min) {
129
130         final Paint paint = new Paint();
131         paint.setAntiAlias(true);
132         Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
133         /**
134          * 产生一个同样大小的画布
135          */
136         Canvas canvas = new Canvas(target);
137         /**
138          * 首先绘制圆形
139          */
140         canvas.drawCircle(min / 2, min / 2, min / 2, paint);
141
142         /**
143          * 使用SRC_IN,参考上面的说明
144          */
145         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
146         /**
147          * 绘制图片
148          */
149         if (source != null)// 画图片
150             canvas.drawBitmap(source, 0, 0, paint);
151         else { // 画圆
152             paint.setColor(inColor);
153             canvas.drawCircle(min / 2, min / 2, min / 2, paint);
154         }
155
156         if (outColor != 0) {
157             // 让画出的图形是空心的
158             paint.setStyle(Paint.Style.STROKE);
159             // 设置画出的线的 粗细程度
160             paint.setStrokeWidth(outStrokeWidth);
161             paint.setColor(outColor);
162             canvas.drawCircle(min / 2, min / 2, min / 2, paint);
163         }
164         if(mText != null){
165             // 让画出的图形是实心的
166             paint.setStyle(Paint.Style.FILL);
167             paint.setStrokeWidth(1);
168             if(mTextColor != 0 ){
169                 paint.setColor(mTextColor);
170             }
171             if(mTextSize != 0 ){
172                 paint.setTextSize(mTextSize);
173             }
174             paint.setTextAlign(Paint.Align.CENTER);
175             FontMetrics fm = paint.getFontMetrics();
176             //得到文字的高度
177             float fFontHeight = (float)Math.ceil(fm.descent - fm.ascent);
178
179             canvas.drawText(mText, mWidth/2, mHeight/2+fFontHeight/4, paint);
180         }
181         return target;
182     }
183
184     //设置文字
185     public void setText(String string) {
186         mText = string;
187         //重绘
188         invalidate();
189         requestLayout();
190     }
192 }

这段代码其实也很简单,主要就是初始化参数信息并画圆和文字的, 代码中大部分的注释都写了,这里就不在描述。

做的的自定义view,难免少不了自定属性。上边代码中78行使用到的 R.styleable.StockManage 就是我们要定义的属性。

需要在values文件夹中新建arrays.xml 并定义以下内容

代码如下:

 1     <declare-styleable name="StockManage">
 2         <attr name="width" format="dimension" /><!-- 宽度 -->
 3         <attr name="height" format="dimension" /><!-- 高度 -->
 4         <attr name="inColor" format="color" /><!-- 圈内颜色 -->
 5         <attr name="outColor" format="color" /><!-- 圈外颜色 -->
 6         <attr name="textColor" format="color" /><!-- 颜色-->
 7         <attr name="stroke" format="dimension" /><!-- 圆圈的宽度 -->
 8         <attr name="textSize" format="dimension" /><!-- 字体大小 -->
 9         <attr name="text" format="string" /><!-- 字 -->
10         <attr name="icon" format="reference" /><!-- 图片 -->
11     </declare-styleable>

这段代码中的 name="StockManage" 就是我们要调用的的名称。里面的字段调动办法为 name_name, 前面的name是StockManage后面的是属性的name。

比如:

mTextColor = array.getColor(R.styleable.StockManage_textColor, Color.BLACK);

对自定义属性不太了解的同学,可去查看下相关的资料。。。

现在我们自定义的view已经写完了。接着 看使用方法。

我们在布局文件中使用:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:sm="http://schemas.android.com/apk/res/com.stock.manage.friend"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     android:orientation="vertical" >
 8
 9         <com.stock.manage.friend.view.CustomImageView
10             android:id="@+id/my_view"
11             android:layout_width="wrap_content"
12             android:layout_height="wrap_content"
13             sm:height="100dip"
14             sm:inColor="@color/white"
15             sm:outColor="@color/black"
16             sm:stroke="2dip"
17             sm:text="文字"
18             sm:textColor="@color/black"
19             sm:textSize="12sp"
20             sm:width="100dip" />
21
22 </LinearLayout >

其中:

xmlns:sm="http://schemas.android.com/apk/res/com.stock.manage.friend"

定义的是命名空间。黑色字体是我的包名。sm是名称。这样就可以使用arrays下面的属性了。

调用方法就是 sm:width="100dip"。类似这样。

这样就实现了自定义圆形view的功能了。 就不上图了,该吃饭了。。。

时间: 2024-08-29 18:50:23

Android自定义带边框的圆形view的相关文章

Android 自定义带刻度的seekbar

自定义带刻度的seekbar 1.布局 <span style="font-family:SimHei;font-size:18px;"><com.imibaby.client.views.CustomSeekbar android:id="@+id/myCustomSeekBar" android:layout_width="wrap_content" android:layout_height="wrap_cont

Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示

Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过Paint和onDraw()进行圆形图片显示. 效果图: 代码: 1 activity_image.xml 2 <?xml version="1.0" encoding="utf-8"?> 3 <LinearLayoutxmlns:android=&q

android 自定义带动画的统计饼图

闲来无事,发现市面上好多app都有饼图统计的功能,得空自己实现以下,菜鸟一只,求指教,轻喷!   基本要求: 在XML布局中可配置控件的属性. 遵守基本的安卓规范 View基本绘制原理: 首先计算View的大小,测量View的大小主要有三个: public final void measure(int widthMeasureSpec, int heightMeasureSpec) protected void onMeasure(int widthMeasureSpec, int height

UIImage类扩展返回一个带边框的圆形图片

/** * 将image转换为圆型带边框的图片(最好写一个UIImage的类扩展) * * @param name 图片的名字 * @param borderWidth 外层边框的宽度 * @param borderColor 外层边框的颜色 * * @return 返回已经处理好的圆形图片 */ + (instancetype)circleImageWithName:(NSString *)name borderWidth:(CGFloat)borderWidth borderColor:(U

【Android】Android自定义带board的圆角控件

介绍 圆角控件常用于头像,按钮,图标等,用途十分广泛,而且常常配合board使用. 在IOS中,UIVIew的CALayer层已经提供了圆角和board的方法,所以圆角控件的制作非常简单,只需要类似以下简单代码即可实现: view.layer.cornerRadius = 20; view.layer.borderColor = [UIColor yellowColor].CGColor; view.layer.borderWidth = 10; view.clipsToBounds = YES

android 自定义带按钮的Notification及点击事件和伸缩通知栏

1.自定义一个带按钮的Notification布局:layout_notification: 2.创建Notification: RemoteViews views = new RemoteViews(getPackageName(),R.layout.layout_nitification); //自定义的布局视图 //按钮点击事件: PendingIntent homeIntent = PengdingIntent.getBroadcast(this,1,new Intent("action

Android 自定义ImageView实现圆角/圆形 附加OnTouchListener详细注释以及Button圆角

转载请注明出处:王亟亟的大牛之路 平时要用一些非方方正正的按钮之类的小伙伴们是如何实现的?RadioButton?ImageButton?还是其他? 今天亟亟上的是ImageView来实现的 先上下效果图(目录结构) 分析: shape.xml用于Button的"倒角"(做过机械类的都懂,哈哈) attr.xml用于自定义ImageView的标签的定义 ids.xml用于控件findbyid用,为什么补+id 等会我会来解释 效果图: 分析:一个Button 2个自定义ImageVie

Android 自定义录音、播放动画View,让你的录音浪起来

最近公司项目有一个录音的录制和播放动画需求,然后时间是那么紧,那么赶紧开撸. 先看效果图 嗯,然后大致就是这样,按住录音,然后有一个倒计时,最外层一个进度条,还有一个类似模拟声波的动画效果(其实中间的波浪会根据声音的大小浪起来的~) 2 实现思路 然后,我们适当的来分析一下这个录音动画的实现方式.这个肯定是通过自定义控件,咱们来把这个效果完完全全画出来. 大致包括以下几个点: 1. 最外层的进度条,最坑的就是一开始的一个渐变的效果 2. 然后进度条最前方是有一个点的(我肯定选择用图片来实现) 3

Android 自定义实现翻转卡片的View

一般一个View只有一面,但是可以自定义一个View,实现像翻书那样的翻转效果. 旋转View: /** * 两种方式构造一个翻转卡片 * 1:直接提供一个特定命名格式的View * 2:提供两个线性布局(正面和,反面) * Created by lip on 2015/4/8. */ public class FlipView extends LinearLayout implements View.OnClickListener,RotateAnimation.InterpolatedTim