android自定义view实现公章效果
上次去一个公司面试,面试官问了一个题,怎么用android的自定义view实现一个公章的效果,据说这是华为之前的面试题,我想了下,要是公章的效果,最外层是一个圆,里面是一个五角星,但是这文字怎么画呢,比较难搞,后来回来看了下java的api,发现人家的Path里面本来就提供了这么一个方法:
public void addArc(RectF oval, float startAngle, float sweepAngle) {
addArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle);
}
然后人家解释说了,根据狐线的角度生成相应的路径,所以我们就可以给文字设置一个相应绘制区域,使其绘制的文字都在这个区域内,
path.addArc(oval,-(firstrad-), textPadding);
接下来我们只需要在这个区域内把文字绘制上去就行了。
好的,下面是全部代码:
首先继承自View,我们在构造里面初始化,同样为了方便程序的扩展性,我们用自定义属性,
<declare-styleable name="Seal"> <attr name="scale_text_size" format="dimension" /> <attr name="scale_text_color" format="color" /> <attr name="scale_text" format="string" /> <attr name="scale_text_padding" format="float" /> <attr name="circle_stroke_width" format="dimension" /> <attr name="circle_color" format="color" /> <attr name="circle_radius" format="dimension" /> </declare-styleable>
然后我们初始化的时候主要初始化文字,文字大小,文字间距,文字颜色等等,
private void initViews(AttributeSet attrs, int defStyle) { TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.Seal, defStyle, 0); circleText = typedArray.getString(R.styleable.Seal_scale_text); textSize = typedArray.getDimension(R.styleable.Seal_scale_text_size, 20); scaleTextColor = typedArray.getColor(R.styleable.Seal_scale_text_color, getResources().getColor(R.color.c9)); textPadding=typedArray.getFloat(R.styleable.Seal_scale_text_padding,50); circleStrokeWidth = typedArray.getDimensionPixelSize(R.styleable.Seal_circle_stroke_width, 3); circleColor = typedArray.getColor(R.styleable.Seal_circle_color, getResources().getColor(R.color.c9)); circleRadius = typedArray.getDimensionPixelSize(R.styleable.Seal_circle_radius, 7); typedArray.recycle(); }接下来我们在重写Ondraww(Canvas canvas)
@Override protected void onDraw(Canvas rootCanvas) { super.onDraw(rootCanvas); Bitmap image = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(image); Paint paint=new Paint(); drawRing(canvas,paint); drawStar(canvas); drawText(canvas); rootCanvas.drawBitmap(image, 0, 0, null); }
接下来是对应的三个方法:画圆环(ring),五角星(star),文字(text)
//圆环
private void drawRing(Canvas canvas, Paint paint) { centre = canvas.getWidth() / 2; // 获取圆心的x坐标 radius = (int) (centre - circleStrokeWidth / 2); // 圆环的半径 paint.setColor(Color.RED); // 设置圆环的颜色 paint.setStyle(Paint.Style.STROKE); // 设置空心 paint.setStrokeWidth(circleStrokeWidth); // 设置圆环的宽度 paint.setAntiAlias(true); // 消除锯齿 canvas.drawCircle(centre, centre, radius, paint); // 画出圆环 }//绘制五角星private void drawStar(Canvas canvas){ float start_radius = (float) ((radius / 2)*1.1); int x = centre, y = centre; float x1,y1,x2,y2,x3,y3,x4,y4,x5,y5; float r72 = (float) Math.toRadians(72); float r36 = (float) Math.toRadians(36); //顶点 x1 = x; y1 = y - start_radius; //左1 x2 = (float) (x - start_radius*Math.sin(r72)); y2 = (float) (y - start_radius*Math.cos(r72)); //右1 x3 = (float) (x + start_radius*Math.sin(r72)); y3 = (float) (y - start_radius*Math.cos(r72)); //左2 x4 = (float) (x - start_radius*Math.sin(r36)); y4 = (float) (y + start_radius*Math.cos(r36)); //右2 x5 = (float) (x + start_radius*Math.sin(r36)); y5 = (float) (y + start_radius*Math.cos(r36)); //连接各个节点,绘制五角星 Path path = new Path(); path.moveTo(x1, y1); path.lineTo(x5, y5); path.lineTo(x2, y2); path.lineTo(x3, y3); path.lineTo(x4, y4); path.close(); Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawPath(path, paint); }//文字
private void drawText(Canvas canvas){ Paint paint = new Paint(); paint.setColor(Color.RED); paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setTextAlign(Paint.Align.CENTER); paint.setTextSize(radius/5+5); //圆弧文字所在矩形范围 RectF oval=new RectF(0, 0, 2*radius, (float) (2*radius)); //第一个文字偏移角度,其中padding/2为文字间距 float firstrad = 90 + textPadding * (circleText.length()) / 4 - textPadding/8; for(int i = 0; i < circleText.length(); i++){ Path path = new Path(); //根据角度生成弧线路径 path.addArc(oval,-(firstrad-textPadding*i/2), textPadding); canvas.drawTextOnPath(String.valueOf(circleText.charAt(i)), path, -(float) (radius/3),(float) (radius/3), paint); } }最后在我们需要的视图中引用下就好了
<com.xzh.sealmaster.view.SealView android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center" app:scale_text_size="16sp" app:scale_text_padding="50" app:scale_text="华为上海有限公司" />有需要源码的,请到下面地址下载:http://download.csdn.net/detail/xiangzhihong8/9479372好的,就是这么简单,有任何疑问的请加我们的技术群278792776或者188716429
android自定义view实现公章效果的更多相关文章
- Android 自定义View跑马灯效果(一)
今天通过书籍重新复习了一遍自定义VIew,为了加强自己的学习,我把它写在博客里面,有兴趣的可以看一下,相互学习共同进步: 通过自定义一个跑马灯效果,来诠释一下简单的效果: 一.创建一个类继承View, ...
- android 自定义view之侧滑效果
效果图: 看网上的都是两个view拼接,默认右侧的不显示,水平移动的时候把右侧的view显示出来.但是看最新版QQ上的效果不是这样的,但给人的感觉却很好,所以献丑来一发比较高仿的. 知识点: 1.Vi ...
- Android自定义View 画弧形,文字,并增加动画效果
一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类 B ...
- Android自定义View(LimitScrollerView-仿天猫广告栏上下滚动效果)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53303872 本文出自:[openXu的博客] 1分析 2定义组合控件布局 3继承最外层控件 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- Android 自定义 view(三)—— onDraw 方法理解
前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...
- Android 自定义view(二) —— attr 使用
前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...
- Android 自定义View及其在布局文件中的使用示例(二)
转载请注明出处 http://www.cnblogs.com/crashmaker/p/3530213.html From crash_coder linguowu linguowu0622@gami ...
- Android自定义View
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...
随机推荐
- MySQL 存储过程探秘
关于存储过程的优点,本文不再阐述.这里只是对创建存储过程时可能遇到的问题做一下简单的分析. 必备基础 这里说的基础,是相关于如何创建一个存储过程的. DELIMITER:分隔符,定界符. 作用就是:作 ...
- Spark集群术语
Spark集群术语解析 1. Application Application是用户在Spark上构建(编写)的程序,包含driver program 和executors(分布在集群中多个节点上运行的 ...
- Java项目源码为什么要做代码混淆(解释的很好)
代码混淆,是将计算机程序的代码转换成一种功能上等价,但是难于阅读和理解的形式的行为.代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码.执行代码混淆的程序被称作代码混淆器.目前已经存在许多种 ...
- 利用gradle添加构建版本号
在java的程序中,貌似都没有这个构建版本号的概念,用的诸如eclipse, idea和android studio的IDE也没有直接提供构建版本号的选项.不过我却想在android程序的版本号当中添 ...
- iOS中 Swift初级入门学习(二)
// Copyright (c) 2015年 韩俊强. All rights reserved. // import Foundation /* // 控制语句 // for - in // 遍历字符 ...
- 基于java自身技术实现消息方式的系统间通信
这篇博客基本照搬了分布式java应用基础与实践一书的内容 java自带的远程调用分两种一种是rmi,一种是webservice 我们先看rmi(remote method invoke)# 使用rmi ...
- JAVA DOM4j解析XML数据到自定义javabean
我们获取xml中的数据,一般以面向对象的思想去处理这些数据.因此,我们需要自定义类来封装解析出来的数据,以方便我们操作这些数据. 自定义的java类,称为javabean. 自定义Contact类代码 ...
- tomcat的realm域
Realm域,其实可以看成是一个包含了用户及密码的数据库,而且每个用户还会包含了若干角色.也就是包含了用户名.密码.角色三个列的数据记录集合,如下图,最下面椭圆内的包含的整块即可以看成realm域.它 ...
- Java Swing 之Timer配合JProgressBar的使用
Timer作为java开发中常用的一个定时工具,配合JProgressBar使用起来还真是方便,只需要调用timer.start()方法就能激活并运行,然后调用stop()方法便能停止,还可以再次通过 ...
- 《java入门第一季》正则表达式小案例
案例一:当你登陆某个论坛,向发帖子留下自己qq号的时候,可惜你的号码就是留不下,总是输入*,或者其它奇妙的字符串.其实原理就是用了正则表达式替换. /* * 替换功能 * String类的public ...