重寫TextView,實現圓形背景,文本居中顯示


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

(有點問題:文本沒有絕對居中,暫時沒做處理。)

為此,我采取的方式是重寫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方法的調用順序:放到最后調用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM