Android之自定义TextView

对于自定义,我也是最近才开始学习,所以有些自定义的控件也都是在学习中,今天先来写一个简单的自定义控件TextView,这个模仿已经简单的不能再简单了。

对于自定义控件,一般来说,我们首先有以下几个步奏

  1. 自定义的属性
  2. 获取自定义属性
  3. 重写常用的方法onDraw() onMeasure() onTouchEvent()等,这些是我们一些基本的方法,具体重写哪些方法根据具体需求重写即可
  4. 开始自定义实现

首先在res ——values下自定义一个自己的myStyles属性,或者直接在styles下定义即可。

myStyles.xml

<?xml version="1.0" encoding="utf-8"?><resources>        <declare-styleable name="CustomViewNet1">                <attr name="titleName" format="string"/>        <attr name="titleColor" format="color"/>        <attr name="titleSize" format="dimension"/>    declare-styleable>resources>

activity_main.xml

<?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-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="cn.itrealman.customview.MainActivity">    <cn.itrealman.customview.net.CustomViewNet1        android:layout_width="wrap_content"        android:layout_height="wrap_content"        app:titleColor="#00f"        android:layout_centerInParent="true"        app:titleName="自定义文字"        app:titleSize="30sp"        />RelativeLayout>

上面不要忘记添加xmlns:app="http://schemas.android.com/apk/res-auto"代码,这句代码表示的意思类似于我们Java中import java.lang.*,表示将某个包中的所有类导入进来。所以这里就是自动将所有自定义的控件导进来。
CustomViewNet1.java

public class CustomViewNet1 extends View {    //文字标题    private String mTitleName;    //文字颜色    private int mTitleColor;    //文字大小    private int mTitleSize;    //控制绘制文字时的范围    private Rect mBound;    //画笔    private Paint mPaint;    public CustomViewNet1(Context context) {        this(context, null);    }    /**     * 一般会默认先执行带两个参数的构造方法     * @param context 上下文     * @param attrs 属性值     */    public CustomViewNet1(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    /**     * 这个方法也需要调用     * @param context 上下文     * @param attrs 属性值     * @param defStyleAttr 默认的属性风格     */    public CustomViewNet1(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //获取所有自定义的属性值        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomViewNet1, defStyleAttr, 0);        //获取属性值的个数        int count = typedArray.getIndexCount();        Log.d("IT_Real", "CustomViewNet1: count = " + count);        //遍历获取的属性值个数        for (int i = 0; i < count; i++) {            //根据下标获取对应的属性类型            int attr = typedArray.getIndex(i);            Log.d("IT_Real", "CustomViewNet1: attr = " + attr);            //设置将布局中的值设置该方法中的变量中            switch (attr) {                case R.styleable.CustomViewNet1_titleColor:                    //文字默认值为黑色                    mTitleColor = typedArray.getColor(attr, Color.BLACK);                    break;                case R.styleable.CustomViewNet1_titleName:                    mTitleName = typedArray.getString(attr);                    break;                case R.styleable.CustomViewNet1_titleSize:                    //默认设置为16sp,关于TypeValue.applyDimension方法的使用可以参考我博客中的介绍                    mTitleSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                    break;            }        }        //释放资源        typedArray.recycle();        //创建一个画笔        mPaint = new Paint();        //设置字体大小        mPaint.setTextSize(mTitleSize);        //创建一个保存文字大小的容器        mBound = new Rect();        //获取文字的大小        mPaint.getTextBounds(mTitleName, 0, mTitleName.length(), mBound);    }    @Override    protected void onDraw(Canvas canvas) {        //设置画笔的颜色为红色        mPaint.setColor(Color.RED);        //先画一个布局        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);        //设置画文字的颜色        mPaint.setColor(mTitleColor);        //绘制文字,这里是先获取布局的宽和高,然后进行一些简单运算,将文字居中        canvas.drawText(mTitleName, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);    }    /**     * 测量用户定义控件的宽高度     * @param widthMeasureSpec     * @param heightMeasureSpec     */    @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;        /**         * 首先要了解以下的几个模式         * EXACTLY:一般是设置了明确的值或者是MATCH_PARENT         * AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT         * UNSPECIFIED:表示子布局想要多大就多大,很少使用         */        if (widthMode == MeasureSpec.EXACTLY) {            width = widthSize;        } else {            mPaint.setTextSize(mTitleSize);            mPaint.getTextBounds(mTitleName, 0, mTitleName.length(), mBound);            //文字的宽度            float textWidth = mBound.width();            //获取设置了边距的值            int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());            //设置宽的布局大小            width = desired + desired / 10;        }        if (heightMode == MeasureSpec.EXACTLY) {            height = heightSize;        } else {            mPaint.setTextSize(mTitleSize);            mPaint.getTextBounds(mTitleName, 0, mTitleName.length(), mBound);            float textHeight = mBound.height();            int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());            //设置高的布局大小            height = desired + desired / 2;        }        setMeasuredDimension(width, height);    }}

效果图如下:

修改一下布局:

.itrealman.customview.net.CustomViewNet1        android:layout_width="match_parent"        android:layout_height="match_parent"        app:titleColor="#00f"        app:titleName="自定义文字    "        android:layout_centerInParent="true"        app:titleSize="30sp"        />

效果图如下:

在设置一下布局具体的值:

 .itrealman.customview.net.CustomViewNet1        android:layout_width="300dp"        android:layout_height="200dp"        app:titleColor="#0ff"        app:titleName="自定义文字    "        android:layout_centerInParent="true"        app:titleSize="40sp"        />

效果图如下:

简单的布局就完成了,当然,这个布局只是简单的模仿TextView而已,具体的其他属性,可以尝试这去学习自定义一下。

更多相关文章

  1. Android(安卓)studio 下创建menu布局文件和xml文件
  2. Android(安卓)中使用代码动态网格布局
  3. Android(安卓)开发技术周报 Issue#288
  4. Android(安卓)SystemProperties设置/取得系统属性的用法总结
  5. Android(安卓)资源(Resources)访问
  6. android textview滚动条
  7. Android(安卓)ORC文字识别之识别身份证号等(附源码)
  8. android中activity动画切换
  9. 在配置文件(manifest file)中声明activity的一点理解

随机推荐

  1. 最新: 运用机器学习和合成控制法研究武汉
  2. Ubuntu系统网络配置及shell脚本编程之函
  3. 阿里云_弹性公网IP地址(EIP)切换到新的EC
  4. GO进阶训练营
  5. JavaEE在线就业班2.0【最新升级版】
  6. 单位em和rem区别,box-sizing定义边界,VW和V
  7. 0325作业-flex项目上的三个属性及手机端
  8. 苏宁首页仿写,及grid布局相关属性预习
  9. django使用utf8mb4字符集
  10. 软件架构-zookeeper集群部署与快速入门