基于TextView实现的SemiCircleRectView<热门标签>
2016-05-07 02:20
573 查看
前言
相信大家都在网上见过热门标签的View是长什么样子,此文章就带大家在Android上实现效果图
看了上面的效果图后,可能有的同学就会有疑问了,这些效果,不都可以通过
shape来实现吗?还用得着大动干戈来自定义一个控件吗?
这里说下实现这种背景的几种方式:.9图、shape、svg,当然还有我们这次要说的代码的灵活实现
大伙莫急,好说我也是有一点安卓开发经验的人,不会做这种无聊的事的,我们想想如下几个问题:
1. 一个shape能适配任何大小的View吗
2. 一个shape能实现不同颜色的背景吗
3. 一个shape能实现根据View的实际长与宽的情况来画吗
答案肯定是不能实现
实现思路
其实实现方式很简单,和shape一个意思,只是我们是动态根据情况来实现一个Drawable对象背景,所以我们主要工作就是实现一个我们想要的图形Drawable实现背景Drawable对象
直接上实现代码,代码量并不多class SemiCircleRectDrawable extends Drawable { private final Paint mPaint; private RectF rectF; public SemiCircleRectDrawable() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(backgroundColor); } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); if (rectF == null) { rectF = new RectF(left, top, right, bottom); } else { rectF.set(left, top, right, bottom); } } @Override public void draw(Canvas canvas) { float R = rectF.bottom / 2; if (rectF.right < rectF.bottom) { R = rectF.right / 2; } canvas.drawRoundRect(rectF, R, R, mPaint); } @Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter colorFilter) { mPaint.setColorFilter(colorFilter); } @Override public int getOpacity() { return PixelFormat.TRANSPARENT; } }
mPaint.setColor(backgroundColor)这里的
backgroundColor来自
SemiCircleRectView自定义属性的值,默认为透明的。
SemiCircleRectDrawable主要两个方法:
setBounds确定矩形大小,
draw画圆角矩形
我们重点来分析下
draw方法的实现
public void draw(Canvas canvas) { float R = rectF.bottom / 2; if (rectF.right < rectF.bottom) { R = rectF.right / 2; } canvas.drawRoundRect(rectF, R, R, mPaint); }
变量
R代表圆的半径,这里就要思考下矩形的宽度与高度的大小,根据情况来计算
R的值,一点就是,始终以小的为准来计算
R
给View设置Background
设置背景是肯定的,但我们什么情况下去设置了?不可能在View创建的时候,因为这个时候可能View在大小还没确认,View的大小还没确认那么我们创建的Drawable对象的大小就不能确认,所以我们需要在一个完全已经能确定View的大小的条件下去调用setBackground()或
setBackgroundDrawable()方法,两者的区别是前者是
sdk version level 16的API,所以我们需要根据系统版本来使用不同的API,所以我思考了
1000ms的时间,确定了在View的
onSizeChanged方法来设置Background,代码如下:
protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { setBackground(new SemiCircleRectDrawable()); } else { setBackgroundDrawable(new SemiCircleRectDrawable()); } }
为SemiCircleRectView自定义属性attr:backgroundColor
此属性在画矩形时Paint对象的颜色值<declare-styleable name="SemiCircleRectView"> <attr name="backgroundColor" format="color" /> </declare-styleable>
public SemiCircleRectView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SemiCircleRectView, defStyleAttr, 0); backgroundColor = typedArray.getColor(R.styleable.SemiCircleRectView_backgroundColor, Color.TRANSPARENT); typedArray.recycle(); }
布局xml中的使用
<com.jay.semicirclerectview.widget.SemiCircleRectView android:gravity="center" android:layout_width="150dp" android:layout_height="50dp" android:text="SemiCircleRectView" app:backgroundColor="@color/colorAccent"/>
注意事项
此控件是继承于
TextView,所以拥有
TextView所有的特性
当View的宽与高相等时,就会实现一个圆的背景效果,这属正常行为
当View的
高 < 宽时,画的是View的左右两端的半圆弧
当View的
高 > 宽时,画的是View的上下两端的半圆弧
Github
https://github.com/JaySong/SemiCircleRectView相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories