当前位置: 移动技术网 > IT编程>移动开发>Android > Android使用ImageView 制作透明圆弧实例代码

Android使用ImageView 制作透明圆弧实例代码

2019年07月24日  | 移动技术网IT编程  | 我要评论

出租魔法使国语版,小婉和小娇243,中国航空公司排名

这几天因为项目需求,需要在imageview上面叠加一层透明圆弧,并且在沿着圆弧的方向显示相应的文字,效果如下图所示:


  拿到这个需求,首先想到的是自定义一个imageview来实现此功能,即在ondraw()中绘制圆弧和文字。同时因为要保证圆弧的位置可以任意摆放,圆弧的颜色、透明度以及文字大小、颜色等都是可控的,所以增加了一些自定义属性。实现代码非常简单,如下:

1.自定义imageview:

package com.chunk.customviewsdemo.views.arcimageview;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.path;
import android.graphics.rectf;
import android.util.attributeset;
import android.widget.imageview;
import com.chunk.customviewsdemo.r;
/**
* description:a custom imageview with circular arc and text
* author: xiaoyu
* date: // :
*/
public class arcimageview extends imageview {
/**
* the default text size.
*/
private final float default_text_size = ;
/**
* the default scale value which decides the width of arc.
*/
private final float default_scale = .f;
/**
* the default transparency of arc.
*/
private final int default_arc_alpha =;
/**
* the default width of arc.
*/
private final int default_arc_width =;
/**
* the default angle that the arc starts with.
*/
private final int default_start_angle = ;
/**
* the default angle that the arc.
*/
private final int default_sweep_angle = ;
/**
* the default distance along the path to add to the text's starting position.
*/
private final int default_h_offset = ;
/**
* the default distance above(-) or below(+) the path to position the text.
*/
private final int default_v_offset = ;
private context mcontext;
/**
* the text displayed on imageview along arc.
*/
private string mdrawstr;
/**
* the font size of text.
*/
private float mtextsize = default_text_size;
/**
* the scale value which decides the width of arc.
*/
private float mscale = default_scale;
/**
* the transparency of arc.
*/
private int marcalpha = default_arc_alpha;
/**
* the width of arc.
*/
private int marcwidth = default_arc_width;
/**
* the start angle of angle.
*/
private int mstartangle = default_start_angle;
/**
* the swept angle of angle.
*/
private int msweepangle = default_sweep_angle;
/**
* the default distance along the path to add to the text's starting position.
*/
private float mhoffset = default_h_offset;
/**
* the default distance above(-) or below(+) the path to position the text.
*/
private float mvoffset = default_v_offset;
/**
* the style of arc, all styles includes left_top, left_bottom, right_top, right_bottom, center。
* of course, you can add your own style according to your demands.
*/
private int mdrawstyle;
/**
* the color of arc.
*/
private int marccolor;
/**
* the color of text.
*/
private int mtextcolor;
public arcimageview(context context) {
super(context);
this.mcontext = context;
}
public arcimageview(context context, attributeset attrs) {
super(context, attrs);
this.mcontext = context;
obtainattributes(attrs);
}
public arcimageview(context context, attributeset attrs, int defstyleattr) {
super(context, attrs, defstyleattr);
this.mcontext = context;
obtainattributes(attrs);
}
/**
* set the text that will be drawn on arc.
* @param drawstr the text content.
*/
public void setdrawstr(string drawstr) {
this.mdrawstr = drawstr;
//refresh this view
invalidate();
}
/**
* set the transparency of arc.
* @param marcalpha the value of transparency.
*/
public void setarcalpha(int marcalpha) {
this.marcalpha = marcalpha;
//refresh this view
invalidate();
}
@override
protected void ondraw(canvas canvas) {
super.ondraw(canvas);
//draw arc
paint arcpaint = new paint();
arcpaint.setstrokewidth(marcwidth);
arcpaint.setstyle(paint.style.stroke);
arcpaint.setcolor(marccolor);
arcpaint.setalpha(marcalpha);
int width = getwidth();
int height = getheight();
float radius;
if (width > height) {
radius = mscale * height;
} else {
radius = mscale * width;
}
rectf oval = new rectf();
int center_x = width;
int center_y = height;
switch (mdrawstyle) {
case :
center_x = ;
center_y = ;
mstartangle = ;
msweepangle = -;
break;
case :
center_x = ;
center_y = height;
mstartangle = ;
msweepangle = ;
break;
case :
center_x = width;
center_y = ;
mstartangle = ;
msweepangle = -;
break;
case :
center_x = width;
center_y = height;
mstartangle = ;
msweepangle = ;
break;
case :
center_x = width / ;
center_y = height / ;
mstartangle = ;
msweepangle = ;
break;
}
float left = center_x - radius;
float top = center_y - radius;
float right = center_x + radius;
float bottom = center_y + radius;
oval.set(left, top, right, bottom);
canvas.drawarc(oval, mstartangle, msweepangle, false, arcpaint);
//draw text
paint textpaint = new paint();
textpaint.settextsize(mtextsize);
textpaint.setstyle(paint.style.fill);
textpaint.setcolor(mtextcolor);
path path = new path();
path.addarc(oval, mstartangle, msweepangle);
canvas.drawtextonpath(mdrawstr, path, mhoffset, mvoffset, textpaint);
}
/**
* obtain custom attributes that been defined in attrs.xml.
* @param attrs a collection of attributes.
*/
private void obtainattributes(attributeset attrs) {
typedarray ta = mcontext.obtainstyledattributes(attrs, r.styleable.arcimageview);
mdrawstr = ta.getstring(r.styleable.arcimageview_drawstr);
mtextsize = ta.getdimension(r.styleable.arcimageview_textsize, default_text_size);
marcalpha = ta.getinteger(r.styleable.arcimageview_arcalpha, default_arc_alpha);
marcwidth = ta.getinteger(r.styleable.arcimageview_arcwidth, default_arc_width);
mstartangle = ta.getinteger(r.styleable.arcimageview_startangle, default_start_angle);
msweepangle = ta.getinteger(r.styleable.arcimageview_startangle, default_sweep_angle);
mhoffset = ta.getinteger(r.styleable.arcimageview_hoffset, default_h_offset);
mvoffset = ta.getinteger(r.styleable.arcimageview_voffset, default_v_offset);
marccolor = ta.getcolor(r.styleable.arcimageview_arccolor, xcccccc);
mtextcolor = ta.getcolor(r.styleable.arcimageview_textcolor, xffffff);
mdrawstyle = ta.getint(r.styleable.arcimageview_drawstyle, );
ta.recycle();
}
}

2.在values文件夹下的attrs.xml中自定义属性:

<?xml version="." encoding="utf-"?>
<resources>
<declare-styleable name="arcimageview">
<attr name="drawstr" format="string" />
<attr name="textsize" format="dimension" />
<attr name="arcalpha" format="integer" />
<attr name="arcwidth" format="integer" />
<attr name="startangle" format="integer" />
<attr name="sweepangle" format="integer" />
<attr name="scale" format="float" />
<attr name="hoffset" format="float" />
<attr name="voffset" format="float" />
<attr name="drawstyle" format="enum">
<enum name="left_top" value="" />
<enum name="left_bottom" value="" />
<enum name="right_top" value="" />
<enum name="right_bottom" value="" />
<enum name="center" value="" />
</attr>
<attr name="arccolor" format="color" />
<attr name="textcolor" format="color" />
</declare-styleable>
</resources>

3.在mainactivity调用arcimageview,实现代码如下:

package com.chunk.customviewsdemo;
import android.os.bundle;
import android.support.v.app.appcompatactivity;
import android.view.view;
import android.widget.button;
import com.chunk.customviewsdemo.views.arcimageview.arcimageview;
public class mainactivity extends appcompatactivity implements view.onclicklistener {
private arcimageview aiv_one;
private arcimageview aiv_two;
private arcimageview aiv_three;
private arcimageview aiv_four;
private button btn_another_one;
private int mgroup = ;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
aiv_one = (arcimageview) findviewbyid(r.id.aiv_one);
aiv_one.setarcalpha();
aiv_two = (arcimageview) findviewbyid(r.id.aiv_two);
aiv_two.setarcalpha();
aiv_three = (arcimageview) findviewbyid(r.id.aiv_three);
aiv_three.setarcalpha();
aiv_four = (arcimageview) findviewbyid(r.id.aiv_four);
aiv_four.setarcalpha();
btn_another_one = (button) findviewbyid(r.id.btn_another_one);
btn_another_one.setonclicklistener(this);
}
@override
public void onclick(view v) {
switch (v.getid()) {
case r.id.btn_another_one:
if (mgroup == ) {
aiv_one.setdrawstr("苹果");
aiv_one.setbackgroundresource(r.drawable.apple);
aiv_two.setdrawstr("柚子");
aiv_two.setbackgroundresource(r.drawable.pineapple);
aiv_three.setdrawstr("香蕉");
aiv_three.setbackgroundresource(r.drawable.banana);
aiv_four.setdrawstr("菠萝");
aiv_four.setbackgroundresource(r.drawable.pineapple);
mgroup = ;
} else {
aiv_one.setdrawstr("牛排");
aiv_one.setbackgroundresource(r.drawable.steak);
aiv_two.setdrawstr("海鲜");
aiv_two.setbackgroundresource(r.drawable.seafood);
aiv_three.setdrawstr("奶酪");
aiv_three.setbackgroundresource(r.drawable.cheese);
aiv_four.setdrawstr("烧烤");
aiv_four.setbackgroundresource(r.drawable.barbecue);
mgroup = ;
}
break;
}
}
}

4.mainactivity的布局文件如下:

<linearlayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margintop="dp"
android:layout_marginbottom="dp"
android:orientation="vertical" >
<button
android:id="@+id/btn_another_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="换一组" />
<linearlayout
android:layout_width="match_parent"
android:layout_height="dp"
android:layout_weight=""
android:orientation="horizontal" >
<relativelayout
android:layout_width="dp"
android:layout_weight=""
android:layout_height="match_parent" >
<com.chunk.customviewsdemo.views.arcimageview.arcimageview
android:id="@+id/aiv_one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/steak"
custom:drawstyle="right_bottom"
custom:drawstr="牛排"
custom:arcalpha=""
custom:arccolor="@color/gray"
custom:textcolor="@color/black"
custom:textsize="sp" />
</relativelayout>
<relativelayout
android:layout_width="dp"
android:layout_weight=""
android:layout_height="match_parent" >
<com.chunk.customviewsdemo.views.arcimageview.arcimageview
android:id="@+id/aiv_two"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/seafood"
custom:drawstyle="left_bottom"
custom:drawstr="海鲜"
custom:arcalpha=""
custom:arccolor="@color/gray"
custom:textcolor="@color/black"
custom:textsize="sp" />
</relativelayout>
</linearlayout>
<linearlayout
android:layout_width="match_parent"
android:layout_height="dp"
android:layout_weight=""
android:orientation="horizontal" >
<relativelayout
android:layout_width="dp"
android:layout_weight=""
android:layout_height="match_parent" >
<com.chunk.customviewsdemo.views.arcimageview.arcimageview
android:id="@+id/aiv_three"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/cheese"
custom:drawstyle="right_top"
custom:drawstr="奶酪"
custom:arcalpha=""
custom:arccolor="@color/gray"
custom:textcolor="@color/black"
custom:textsize="sp" />
</relativelayout>
<relativelayout
android:layout_width="dp"
android:layout_weight=""
android:layout_height="match_parent" >
<com.chunk.customviewsdemo.views.arcimageview.arcimageview
android:id="@+id/aiv_four"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/barbecue"
custom:drawstyle="left_top"
custom:drawstr="烧烤"
custom:arcalpha=""
custom:arccolor="@color/gray"
custom:textcolor="@color/black"
custom:textsize="sp" />
</relativelayout>
</linearlayout>
</linearlayout>

注意,在布局文件中引入自定义属性时需要加入一行代码:xmlns:custom="http://schemas.android.com/apk/res-auto"。

好了,需求搞定,剩下的就是搬到实际的项目当中去了。实现效果如下:


总结一下,自定义view一般就是通过重写ondraw、onmeasure()、onlayout()等方法来进行测量、绘制,绘制的时候一般会用到canvas、paint、bitmap等类,测量和绘制的过程其实就是对现实生活中绘图工作的抽象和实现,我们利用面向对象的思想将画板、画纸、画笔等工具以及绘画的动作用一行行代码加以描述就ok啦!

由于实现过程比较简单,我就不贴源码了,大家如果对2d绘图还不是很了解,可以去搜一下相关资料或查阅相关书籍!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网