Android开发使用自定义View将圆角矩形绘制在Canvas上的方法
作者:伟雪无痕 发布时间:2021-06-08 01:03:17
本文实例讲述了Android开发使用自定义View将圆角矩形绘制在Canvas上的方法。分享给大家供大家参考,具体如下:
前几天,公司一个项目中,头像图片需要添加圆角,这样UI效果会更好看,于是写了一个小的demo进行圆角的定义,该处主要是使用BitmapShader进行了渲染(如果要将一张图片裁剪成椭圆或圆形显示在屏幕上,也可以使用BitmapShader来完成).
BitmapShader类完成渲染图片的基本步骤如下:
1、创建BitmapShader类的对象
/**
* Call this to create a new shader that will draw with a bitmap.
*
* @param bitmap The bitmap to use inside the shader
* @param tileX The tiling mode for x to draw the bitmap in.
* @param tileY The tiling mode for y to draw the bitmap in.
*/
public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY) {
......
}
其中,Shader.TitleMode类型有三种,CALMP、MIRROR、REPEAT
CALMP:使用边界颜色来填充剩余空间
MIRROR:使用镜像方式
REPEAT:使用重复方式
2、通过Paint的setShader(bitmapShafer)
来设置画笔
3、使用已经setShader(bitmapShafer)
的画笔来绘制图形
下面展示绘制圆角图片的demo
1、自定义RounderCornerImageView.java类
package com.example.test;
import android.content.Context;
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;
import android.util.AttributeSet;
import android.view.View;
public class RounderCornerImageView extends View {
private Bitmap mImage;// source bitmap
private Paint mBitmapPaint;//paint
private RectF mBrounds;//rect
private float mRadius=20.0f;//round
public RounderCornerImageView(Context context) {
this(context, null);
}
public RounderCornerImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RounderCornerImageView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mBitmapPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
mBrounds=new RectF();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int height,width;
height=width=0;
//obtain bitmap size
int imageHeight,imageWidth;
if (null!=mImage) {
imageHeight=imageWidth=0;
}else
{
imageHeight=mImage.getHeight();
imageWidth=mImage.getWidth();
}
//obtain best measure data and set on View
width=getMeasurement(widthMeasureSpec,imageWidth);
height=getMeasurement(heightMeasureSpec, imageHeight);
//set View last size
setMeasuredDimension(width, height);
}
/**
* measure width and height by specMode
**/
private int getMeasurement(int measureSpec, int contentSize) {
int specSize=MeasureSpec.getSize(measureSpec);
switch (MeasureSpec.getMode(measureSpec)) {
case MeasureSpec.AT_MOST:
return Math.min(specSize, contentSize);
case MeasureSpec.UNSPECIFIED:
return contentSize;
case MeasureSpec.EXACTLY:
return specSize;
default:
return 0;
}//switch
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w!=oldw || h!=oldh) {
int imageWidth,imageHeight;
if (null==mImage) {
imageWidth=imageHeight=0;
}else
{
imageWidth=mImage.getWidth();
imageHeight=mImage.getHeight();
}
//center point
int left=(w-imageWidth)/2;
int top=(h-imageHeight)/2;
mBrounds.set(left, top, left+imageWidth, top+imageHeight);
if (null!=mBitmapPaint.getShader()) {
Matrix m=new Matrix();
m.setTranslate(left, top);
mBitmapPaint.getShader().setLocalMatrix(m);
}
}
}
public void setImage(Bitmap bitmap) {
if (mImage!=bitmap) {
mImage=bitmap;
if (null!=mImage) {
BitmapShader shader=new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setShader(shader);
}else {
mBitmapPaint.setShader(null);
}
requestLayout();//invalidated the layout of this view by onDraw()
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (null!=mBitmapPaint) {
//draw Round Rect
canvas.drawRoundRect(mBrounds, mRadius, mRadius, mBitmapPaint);
}
}
}
2、显示圆角图片的RoundActivity.java类
package com.example.test;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
public class RoundActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RounderCornerImageView view=new RounderCornerImageView(this);
Bitmap souBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.sun);
view.setImage(souBitmap);
setContentView(view);
}
}
另外,附注下自定义View的一些基本步骤和必须实现的方法
1、继承view
2、重写自定义View的构造方法
3、如需要对view进行位置进行测量和重写布局,则需要重写onMeasure()
、onLayout()
、onDraw()
方法
onMeasure():view本身大小多少,可以测量出来
onLayout():view在ViewGroup中的位置可以决定
onDraw():定义了如何绘制该view
希望本文所述对大家Android程序设计有所帮助。
来源:http://blog.csdn.net/j086924/article/details/49868543


猜你喜欢
- •强引用(FinalReference),在java中,有点像C++的指针,通过引用,可以对堆中的对象进行操作。强引用具备以下特点: 1.强
- 使用WebSocketSharp自定义实现Web服务时,无法解析multipart/form-data请求的数据。通过查找资料,采用以下方式
- 前言上一篇文章用贝塞尔曲线画了一个看起来不错的小红点功能,技术上没什么难度,主要就是数学上的计算。这篇文章也差不多,模仿了一个常用的滑动解锁
- 本文实例讲述了Java实现二叉树的深度优先遍历和广度优先遍历算法。分享给大家供大家参考,具体如下:1. 分析二叉树的深度优先遍历的非递归的通
- 每次看IOS上的应用,应用中状态栏的颜色总能与应用标题栏颜色保持一致,用户体验很不错,对于这种效果,像我这种好奇心强的人就会去看看那安卓是否
- 目录ProxyFactory的工作原理JdkDynamicAopProxy创建代理对象过程JdkDynamicAopProxy创建代理对象执
- 什么是事务处理事务是计算机应用中不可或缺的组件模型,它保证了用户操作的原子性 ( Atomicity )、一致性 ( Consistency
- 题目:求1+2!+3!+...+20!的和程序分析:此程序只是把累加变成了累乘。程序设计:public class Ex21 {  
- 目录1、简介2、访问修饰符3、原则总结1、简介访问修饰符是Java语法中很基础的一部分,但是能正确的使用Java访问修饰符的程序员只在少数。
- 某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后除以10的余数代替该数字,再将第一
- Android获取系统内核版本的方法 &nbs
- Java 数据库连接池详解数据库连接池的原理是:连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库
- 本文实例为大家分享了Android调用外置摄像头的具体代码,供大家参考,具体内容如下1、布局文件<?xml version="
- 一.什么是泛型当我们不确定数据类型时,我们可以暂时使用一个字母 T代替数据类型。例如写一个方法,但是我们不知道它是传递的是什么数据类型,我们
- 本文实例讲述了.NET WinForm实现在listview中添加progressbar的方法。分享给大家供大家参考,具体如下:找了好长时间
- 概述:@Valid是使用Hibernate validation的时候使用@Validated是只用Spring Validator校验机制
- JPA介绍JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映
- 特性一:委托委托是C#语言 * 有的概念,相当于C/C++中的函数指针,与C/C++中函数指针的不同之处是:委托是面向对象的、类型安全的和保险
- 本文实例讲述了Android编程实现自定义ProgressBar样式。分享给大家供大家参考,具体如下:效果图如下,本例中设置了第一级进度条和
- C#开发WinForm,如何实现TextBox获取输入焦点时自动全选?&nbs