android自定义view控件之一圆角背景TextView

来源:互联网 发布:平板电脑无法加入网络 编辑:程序博客网 时间:2024/05/21 12:50

继昨天写了一个TextView可以包括两种不同的风格字体,而保证可以换行的情况下的自定义View。今天的正文还是写一个自定义的TextView。

一惯风格首先亮出实现效果,这最是直接不过的了。看下图:


其实不通过写一个自定义view的方式也可以实现这个效果,但是就需你在你class文件中堆更多的代码了,这从软件工程的思想是不可取的。所以还是为了不省事,去写一个自定义的TextView控件吧。相信大家都会写这种比较简单的自定义view了。


首先给出这个自定义view的类RadioTextView,代码如下:

package com.example.yuzhuo.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.RectF;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import com.example.yuzhuo.R;/** * Created by yuzhuo on 16/9/4. */public class RadioTextView extends View{    /**     * title文本     */    private String mTitleText;    /**     * title文本的颜色     */    private int mTitleTextColor;    /**     * titel文本的大小     */    private int mTitleTextSize;    /**     * background     * @param context     * @param attrs     */    private int background;    /**     * 圆角大小     */    private int mCornerSize;    /**     * 绘制时控制文本绘制的范围     */    private Rect mtitleBound;    private Paint mtitlePaint;    public RadioTextView(Context context, AttributeSet attrs)    {        this(context, attrs, 0);    }    public RadioTextView(Context context)    {        this(context, null);    }    /**     * 获得我自定义的样式属性     *     * @param context     * @param attrs     * @param defStyle     */    public RadioTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        /**         * 获得我们所定义的自定义样式属性         */        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RaidoTextView, defStyle, 0);        int n = a.getIndexCount();        for (int i = 0; i < n; i++)        {            int attr = a.getIndex(i);            switch (attr)            {                case R.styleable.RaidoTextView_titleText:                    mTitleText = a.getString(attr);                    break;                case R.styleable.RaidoTextView_titleTextColor:                    // 默认颜色设置为黑色                    mTitleTextColor = a.getColor(attr, Color.BLACK);                    break;                case R.styleable.RaidoTextView_titleTextSize:                    // 默认设置为16sp,TypeValue也可以把sp转化为px                    mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                    break;                case R.styleable.RaidoTextView_background:                    //默认为白色                    background = a.getColor(attr, Color.WHITE);                    break;                case R.styleable.RaidoTextView_mCornerSize:                    //默认圆角为0                    mCornerSize = a.getInteger(attr,0);                    break;            }        }        a.recycle();        /**         * 获得绘制文本的宽和高         */        mtitlePaint = new Paint();        mtitlePaint.setTextSize(mTitleTextSize);        mtitleBound = new Rect();        mtitlePaint.getTextBounds(mTitleText, 0, mTitleText.length(), mtitleBound);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int width;        int height ;        if (widthMode == MeasureSpec.EXACTLY)        {            width = widthSize;        } else        {            mtitlePaint.setTextSize(mTitleTextSize);            mtitlePaint.getTextBounds(mTitleText, 0, mTitleText.length(), mtitleBound);            int desired = getPaddingLeft() + mtitleBound.width() + getPaddingRight();            width = desired<=widthSize?desired:widthSize;        }        if (heightMode == MeasureSpec.EXACTLY)        {            height = heightSize;        } else        {            mtitlePaint.setTextSize(mTitleTextSize);            mtitlePaint.getTextBounds(mTitleText, 0, mTitleText.length(), mtitleBound);            int desired = getPaddingTop() + mtitleBound.height() + getPaddingBottom();            height = desired<=heightSize?desired:heightSize;        }        setMeasuredDimension(width, height);    }    @Override    protected void onDraw(Canvas canvas) {        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);        paint.setAntiAlias(true);        paint.setColor(background);        RectF rec = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());        canvas.drawRoundRect(rec, mCornerSize, mCornerSize, paint);        mtitlePaint.setColor(mTitleTextColor);        Paint.FontMetricsInt fontMetrics = mtitlePaint.getFontMetricsInt();        int baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;        canvas.drawText(mTitleText,getPaddingLeft(), baseline, mtitlePaint);    }}


下面再给出在attrs.xml文件中定义的styleable:

<declare-styleable name="RaidoTextView">        <attr name="titleText" format="string" />        <attr name="background" format="color"/>        <attr name="titleTextSize" format="dimension"/>        <attr name="titleTextColor" format="color"/>        <attr name="mCornerSize" format="integer"/>    </declare-styleable>


最后给出layout.xml中如何写义的布局文件代码:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    <span style="color:#ff6666;">xmlns:radiostyle="http://schemas.android.com/apk/res-auto"</span>    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.yuzhuo.MainActivity" >    <com.example.yuzhuo.view.RadioTextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:padding="10dp"        <span style="color:#ff0000;">radiostyle:titleText = "我是中国人"        radiostyle:titleTextColor = "#ffffff"        radiostyle:titleTextSize = "18sp"        radiostyle:background ="#00ffff"        radiostyle:mCornerSize = "18"/</span>>    <com.example.yuzhuo.view.RadioTextView        android:id="@+id/textView2"        android:layout_marginTop="30dp"        android:layout_below="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:padding="10dp"        radiostyle:titleText = "我是中国人"        radiostyle:titleTextColor = "#ffffff"        radiostyle:titleTextSize = "18sp"        radiostyle:background ="#ff00ff"        radiostyle:mCornerSize = "12"/>    <com.example.yuzhuo.view.RadioTextView        android:id="@+id/textView3"        android:layout_marginTop="30dp"        android:layout_below="@+id/textView2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:padding="10dp"        radiostyle:titleText = "我是中国人"        radiostyle:titleTextColor = "#ffffff"        radiostyle:titleTextSize = "18sp"        radiostyle:background ="#ffff00"        radiostyle:mCornerSize = "6"/></RelativeLayout>


<span style="color:#ff6666;">xmlns:radiostyle="http://schemas.android.com/apk/res-auto"</span>
上面代码红色标注出来的是,为你自定义的styleabe这义的标签模式,这个名字可以随意,只是需要与下面使用的时候保持一致,否则layout布局加载的时候会造成识别不出来,而导致出错。


这是一个特别简单的自定义view控件,实现了个圆角背景的textview,但是通过最简单的自定义view的编写,可以很轻松的去了解和掌握自定义view控件的原理。

还是那句话,欢迎大家批评指正。手下点赞。需要项目工程的可以在github上面下载到,这个是链接点击打开链接




2 0