我们在项目中常常有使用到某个图形的点击效果,例如点击加边框,通常的做法通过自定义shape的xml 来实现效果,但是自定义的shape 无法很方便的控制图形的内部颜色,当需要动态改变改变颜色的时候,就需要定义多个shape的xml.例如:
对于这样的就只需要一个shape 就可以了,但是内部的颜色有5中呢?那就需要再写5个xml ,20中呢?50+呢,
里面唯一的不同就是颜色,代码显示很累赘。所以就想到是否有办法通过自定义的图形来控制形状和颜色。
下面是效果图:
1、自定义View的样式,首先在res/values/ style.xml
<!-- 自定义圆形的样式-->
<declare-styleable name="CustomCircleView">
<attr name="topText" />
<attr name="titleTextSize" />
<attr name="circleRadius" />
</declare-styleable>
2、自定义View的属性,在res/values/ attrs.xml
<!--自定义圆形的属性-->
<attr name="topText" format="string" />
<attr name="titleTextSize" format="dimension" />
<attr name="circleRadius" format="dimension" />
format的属性一共有:
string,color,demension,integer,enum,reference,float,boolean,fraction,flag
3、在对应的xml 下使用自定义的view
<RelativeLayout
android:id="@+id/percent_25_layout"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<com.test.view.CustomCircleView
android:id="@+id/percent_25_bg"
android:layout_width="67dp"
android:layout_height="67dp"
app:topText="25%"
app:circleRadius="32dp"
app:titleTextSize="17sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
主意顶部要加上自定义的命名空间
xmlns:app=”http://schemas.android.com/apk/res-auto”
需要不同的字体,以及圆的大小都可以在xml 内部设置,当然可以增加一个rgb 颜色值得属性,在xml 中就初始化好当前的颜色值,有兴趣的可以试试.
4、下面就是自定义的view 的构造函数
/**
* 自定义的圆形的view
* lh on 2016/1/6.
*/
public class CustomCircleView extends View{
.......
.......
public CustomCircleView(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public CustomCircleView(Context context){
this(context, null);
}
/
**
* 获得自定义的样式属性
* @param context 上下文
* @param attrs 属性
* @param defStyle 默认的样式
*/
public CustomCircleView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
//获得所定义的自定义样式属性
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCircleView, defStyle, 0);
int arrayIndexCount = array.getIndexCount();
for(int i=0;i<arrayIndexCount;i++){
int attr = array.getIndex(i);
switch (attr){
case R.styleable.CustomCircleView_topText:
mTopText = array.getString(attr);
break;
case R.styleable.CustomCircleView_titleTextSize:
mTextSize = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
case R.styleable.CustomCircleView_circleRadius:
mCircleRadius = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()));
break;
}
}
array.recycle();
strokePaint = new Paint();
strokePaint.setAntiAlias(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setARGB(255,0,0,0);
//获得绘制文本的宽和高
mPaint.setTextSize(mTextSize);
mBound = new Rect();
mPaint.getTextBounds(mTopText, 0, mTopText.length(), mBound);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
//画圆
mPaint.setARGB(255, rgbColor[0], rgbColor[1], rgbColor[2]);
canvas.drawCircle(getWidth()/2,getHeight()/2,mCircleRadius,mPaint);
if(viewSelected){
//边框
strokePaint.setColor(Color.WHITE);
if(!mDefaultStrokeColor){
strokePaint.setColor(Color.BLACK);
}
strokePaint.setStrokeWidth(3);
strokePaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(getWidth()/2, getHeight()/2, mCircleRadius-1, strokePaint);
}
//绘制文本内容
mPaint.setColor(Color.WHITE);
if(!mDefaultStrokeColor) {
mPaint.setColor(Color.BLACK);
}
mPaint.setTextSize(mTextSize);
canvas.drawText(mTopText, getWidth()/2 - mBound.width()/2, getHeight()/2 + mBound.height()/2, mPaint);
}
注意点:
array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()));
array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
format=”dimension” 的属性是dimension,会将sp和dp 转化为具体的数值
5、然后就是控制点击变色的部分
public void setViewSelected(boolean selected){
if(viewSelected != selected){
postInvalidate();
}
viewSelected = selected;
}
public boolean isViewSelected() {
return viewSelected;
}
public void setRGBColor(int[] rgb,boolean defaultStrokeColor) {
rgbColor = rgb;
mDefaultStrokeColor = defaultStrokeColor;
// invalidate(); 两者的具体的区别
postInvalidate();
}
此处作为开放的端口,是得获得具体对象以后可以调用
通过 setRGBColor 这个函数设置不同的rgb 的颜色的值,传递过来,刷新绘制图形即可
6、然后就是代码段端的调用了。
根据需要动态的设置改变颜色值就好,我这里使用的是rgb ,也可以似乎#f00的形式,只要增加对应的方法即可,就不赘述了。
percent25.setRGBColor(colorResource[position], true);
本文介绍了一种通过自定义View实现在Android应用中动态改变图形颜色的方法,避免了为每种颜色状态创建单独的XML文件。自定义View支持设置文本、尺寸及颜色等属性,并能在点击时更改边框。
1904

被折叠的 条评论
为什么被折叠?



