重写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方法的调用顺序:放到最后调用。

时间: 2024-10-11 14:59:05

重写TextView,实现圆形背景,文本居中显示的相关文章

flex的Accordion组件头部文本居中显示

flex的Accordion组件头部文本默认是居左的,可以通过设置headerStyleName属性使之居中,另外还可以设置字体的样式等 1 <?xml version="1.0" encoding="utf-8"?> 2 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 3 xmlns:s="library://ns.adobe.com/flex/spar

CSS文本居中显示

因为一直为元素居中问题而困扰,所以决定把自己遇到和看到的方法记录下来,以便以后查看 如果要让inline或inline-block元素居中显示,则父元素css中包含text-align:center; 如果让block元素居中,为其本身添加margin:0 auto; 复杂情形下可以用: display:flex; /*盒子模型*/ flex-direction: row; /*横向*/ justify-content: space-around; /*主轴居中*/ align-items: c

LabelControl文本居中显示

https://www.devexpress.com/Support/Center/Question/Details/Q94915 If you set the AutoSizeMode to None, you will be able to set the Height and Width of the LabelControl, and align the Text using the LabelControl.Appearance.TextOptions.HAlignment prope

让TextView的drawableLeft与文本一起居中显示

 TextView的drawableLeft.drawableRight和drawableTop是一个常用.好用的属性,可以在文本的上下左右放置一个图片,而不使用更加复杂布局就能达到,我也常常喜欢用RadioButton的这几个属性实现很多效果,但是苦于不支持让drawbleLeft与文本一起居中,设置gravity为center也无济于事,终于有空研究了一下,这里与大家一起分享. 声明 欢迎转载,请注明出处! 博客园:http://www.cnblogs.com/ 农民伯伯: http://w

TextView加载html图片异步显示(Picasso)

项目中有这样一个需求: textview加载一段 html标签 其中包含 "<Img url= " 图片异步展示 而且 根据图片的比例 宽度满屏展示. 思路: 重写textview Html.fromHtml方法  以及 图片Picasso展示(后面会附带Picasso 的两个转换类) 感觉网上没有合适的或者用的是Gilde加载 其实无论是Gilde还是Picasso加载豆豆都能满足我们的需求. 需求描述完毕 上张帅图: 好吧 废话不多说了 直接上实现代码 RichText: p

ListView设置某一项item的文本居中

使用ListView和volley写了一个使用网络获取天气的demo ListView中Item的文本模式都是左侧对齐 我这边需要一些标题文本居中对齐 网上也找不到示例,不过找到了getView这个函数 于是自己摸索出了代码: 方式就是在adapter的getView中判断是否含有指定的item,如果有那么就设置这个item的文本居中: 1 this.adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_ite

css布局方式及背景文本属性

一.布局方式 1.标准流/静态流 默认布局方式,按照代码书写顺序及标签类型从上到下,从左到右依次显示 2.浮动布局 主要用于设置块元素的水平排列 1)属性:float 2)取值: 可取left或right,设置元素向左浮动或向右浮动. 示例:float:left/right; 3)特点: 元素设置浮动会从原始位置脱流,向左或向右依次停靠在其他元素边缘,在文档中不再占位 元素设置浮动,就具有块元素的特征,可以手动调整宽高 "文字环绕":浮动元素遮挡正常元素的位置,无法遮挡正常内容的显示,

《CSS3实战》笔记--溢出文本省略:text-overflow和文本换行显示:word-wrop

通过阅读和学习书籍<CSS3实战>总结 <CSS3实战>/成林著.-北京机械工业出版社2011.5 语法: text-overflow:clip | ellipsis | ellipsis-word 取值简单说明: clip属性值表示不显示标记,而是简单的裁切. ellipsis属性值表示当对象内文本溢出时显示省略标记,省略标记插入的位置是最后一个字符. ellipsis-word属性值表示当对象内文本溢出时显示省略标记,省略标记插入的位置是最后一个词(word). ?实际上,te

div中img依据不同分辨率居中显示,超出部分隐藏

在做banner居中时 碰到的问题,知道可以用背景图实现居中显示,但是内心是想深究下的,故找到几种办法收集一下,后面两种真的是奇技淫巧 来着下面两处 https://www.zhihu.com/question/39742237 https://www.v2ex.com/t/187544 flex position:absolute + negative margin background-image + background-size + background-position 4.父元素po