上次去一个公司面试,面试官问了一个题,怎么用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实现公章效果的更多相关文章

  1. Android 自定义View跑马灯效果(一)

    今天通过书籍重新复习了一遍自定义VIew,为了加强自己的学习,我把它写在博客里面,有兴趣的可以看一下,相互学习共同进步: 通过自定义一个跑马灯效果,来诠释一下简单的效果: 一.创建一个类继承View, ...

  2. android 自定义view之侧滑效果

    效果图: 看网上的都是两个view拼接,默认右侧的不显示,水平移动的时候把右侧的view显示出来.但是看最新版QQ上的效果不是这样的,但给人的感觉却很好,所以献丑来一发比较高仿的. 知识点: 1.Vi ...

  3. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  4. Android自定义View(LimitScrollerView-仿天猫广告栏上下滚动效果)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53303872 本文出自:[openXu的博客] 1分析 2定义组合控件布局 3继承最外层控件 ...

  5. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  6. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  7. Android 自定义view(二) —— attr 使用

    前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...

  8. Android 自定义View及其在布局文件中的使用示例(二)

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3530213.html From crash_coder linguowu linguowu0622@gami ...

  9. Android自定义View

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...

随机推荐

  1. Android ListView中Item点击事件失效解决方案

    欢迎关注公众号,每天推送Android技术文章,二维码如下:(可扫描) 在平常的开发过程中,我们的ListView可能不只是简单的显示下文本或者按钮,更多的是显示复杂的布局,这样的话,我们就得自己写布 ...

  2. iOS下JS与OC互相调用(四)--JavaScriptCore

    前面讲完拦截URL的方式实现JS与OC互相调用,终于到JavaScriptCore了.它是从iOS7开始加入的,用 Objective-C 把 WebKit 的 JavaScript 引擎封装了一下, ...

  3. eclispe 导入android或者java项目出现中文乱码

    中文乱码经常是我们是一个比较麻烦的问题,对于这个问题,我想说一下我的解决思路. 1.到Windows- >Pereferences- >Genral->Workspace- > ...

  4. springMVC系列之(四) spring+springMVC+hibernate 三大框架整合

    首先我们要知道Hibernate五大对象:,本实例通过深入的使用这五大对象和spring+springMVC相互结合,体会到框架的好处,提高我们的开发效率 Hibernate有五大核心接口,分别是:S ...

  5. 参数估计:最大似然估计MLE

    http://blog.csdn.net/pipisorry/article/details/51461997 最大似然估计MLE 顾名思义,当然是要找到一个参数,使得L最大,为什么要使得它最大呢,因 ...

  6. java中hashCode()与equals()详解

    首先之所以会将hashCode()与equals()放到一起是因为它们具备一个相同的作用:用来比较某个东西.其中hashCode()主要是用在hash表中提高 查找效率,而equals()则相对而言使 ...

  7. Android开发学习之路--Activity之生命周期

    其实这篇文章应该要在介绍Activity的时候写的,不过那个时候还不怎么熟悉Activity,还是在这里详细介绍下好了.还是参考下官方文档的图吧: 从上面的流程,我们可以看出首先就是打开APP,开始执 ...

  8. android sdutio常用快捷键

    快捷键 说明 F2 定位到高亮错误或警告的位置 F4 若选中项目,打开 Project Struture F5 复制文件 Alt+F3 选中文本,逐个往下查找相同文本,并高亮显示 Alt+F1 可以将 ...

  9. HDFS HA: 高可靠性分布式存储系统解决方案的历史演进

    1. HDFS 简介 HDFS,为Hadoop这个分布式计算框架提供高性能.高可靠.高可扩展的存储服务.HDFS的系统架构是典型的主/从架构,早期的架构包括一个主节点NameNode和多个从节点Da ...

  10. Oracle分页存储过程及PLSQL中的调用脚本

    撰写过程:网上搜集测试了好多的Oracle分页存储过程代码,经整理后终于通过测试,特分享给大家 测试步骤:1.运行创建包命令;2.运行创建存储过程命令;3.运行调用分页存储过程语句 测试环境:wind ...