最近,在做考試試題排版,產品提出題號希望顯示成圓形背景,序號文本居中顯示。

(有點問題:文本沒有絕對居中,暫時沒做處理。)
為此,我采取的方式是重寫TextView的onDraw方法,繪制一個圓形背景。
具體代碼如下:
package com.example.myapp;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* 自定義形狀的TextView 圓形 橢圓形
* Created by cjy on 16/11/30.
*/
public class CustomShapTextView extends TextView{
private Context mContext;
/**
* 畫筆
*/
private Paint mPaint;
/**
* 畫筆顏色 默認灰色
*/
private int mPaintNormalColor = 0xFFDCDCDC;
/**
* 畫筆顏色 選中時的顏色,默認灰色
*/
private int mPaintSelectColor = 0xFFDCDCDC;
/**
* 是否填充顏色
*/
private boolean isFillColor = false;
public CustomShapTextView(Context context) {
super(context);
}
public CustomShapTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint(context,attrs);
}
public CustomShapTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initPaint(context,attrs);
}
/**
* 初始化畫筆和自定義屬性
* @param context
* @param attrs
*/
private void initPaint(Context context,AttributeSet attrs){
mContext = context;
TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.CustomShapTextView);
mPaintNormalColor = typeArray.getColor(R.styleable.CustomShapTextView_paintNormalColor,mPaintNormalColor);
mPaintSelectColor = typeArray.getColor(R.styleable.CustomShapTextView_paintSelectColor,mPaintSelectColor);
mPaint = new Paint();
}
/**
* 調用onDraw繪制邊框
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
//抗鋸齒
mPaint.setAntiAlias(true);
if (isFillColor) {
//畫筆顏色
mPaint.setColor(mPaintSelectColor);
mPaint.setStyle(Paint.Style.FILL);
}else{
//畫筆顏色
mPaint.setColor(mPaintNormalColor);
//畫筆樣式:空心
mPaint.setStyle(Paint.Style.STROKE);
}
//創建一個區域,限制圓弧范圍
RectF rectF = new RectF();
//設置半徑,比較長寬,取最大值
int radius = getMeasuredWidth() > getMeasuredHeight() ? getMeasuredWidth() : getMeasuredHeight();
//設置Padding 不一致,繪制出的是橢圓;一致的是圓形
rectF.set(getPaddingLeft(),getPaddingTop(),radius-getPaddingRight(),radius-getPaddingBottom());
//繪制圓弧
canvas.drawArc(rectF,0,360,false,mPaint);
//最后調用super方法,解決文本被所繪制的圓圈背景鎖覆蓋的問題
super.onDraw(canvas);
}
/**
* 設置是否填充顏色
* @param isFill
*/
public void setFillColor(boolean isFill){
this.isFillColor = isFill;
invalidate();
}
}
為了顏色設置的靈活性,顏色屬性自定義attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomShapTextView">
<!-- Default Paint Color (color). -->
<attr name="paintNormalColor" format="reference|color"/>
<!-- Selected Paint Color (color). -->
<attr name="paintSelectColor" format="reference|color"/>
</declare-styleable>
</resources>
這樣子,我們就可以直接在xml中使用自定義的TextView了,代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.example.myapp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
>
<com.example.myapp.CustomShapTextView
android:id="@+id/circle_tv_view"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/blue"
android:text="A"
android:textSize="16sp"
android:textColor="@drawable/tv_view_color"
android:gravity="center"
android:paddingLeft="12dp"
android:paddingTop="12dp"
android:paddingRight="12dp"
android:paddingBottom="12dp"
app:paintNormalColor="@color/gray"
app:paintSelectColor="@color/blue"
/>
</RelativeLayout>
現在效果是出來,但是發現圓角雖然畫上了,但是文字被覆蓋了。
猜測是我們繪制的圖層覆蓋了文字。
因為自己要畫的東西是在下面的,所以要先畫上去,然后在讓父類(TextView)畫他的文字。
所以調整了super.onDraw方法的調用順序:放到最后調用。
