• 【android自己定义控件】自己定义View属性


    1、自己定义View的属性

    2、在View的构造方法中获得我们自己定义的属性

    3、重写onMesure

    4、重写onDraw

    3这个步骤不是必须,当然了大部分情况下还是须要重写的。

    1、自己定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <attr name="txtName" format="string"/>
        <attr name="txtColor" format="color"/>
        <attr name="txtSize" format="dimension" />
        
        <declare-styleable name="titleStyle">
            <attr name="txtName"/>
            <attr name="txtColor"/>
            <attr name="txtSize"/>
        </declare-styleable>
    </resources>

    定义了字体,字体颜色,字体大小3个属性,format是值该属性的取值类型:

    一共同拥有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;

    编写的时候工具会提醒你使用哪种,不知道也能够Google搜索下


    接下来就自己定义View

    public class CustomTitleView extends View{
    
        private  String txtName;
        private int txtColor,txtSize;
        private  Paint mPaint;
        private Rect mBounds;
    
    
        public CustomTitleView(Context context) {
            this(context, null);
        }
    
        public CustomTitleView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
    
    
        }
    
        public CustomTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
               //详细操作
        }
    }

    定义完自己定义的View ,就该调用我们自己定义的View了。

    <?xml version="1.0" encoding="utf-8"?>
    
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:title="http://schemas.android.com/apk/res/com.example.androidDemo"  《》
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.example.androidDemo.View.CustomTitleView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:padding="5dp"
            title:txtName="你好"
            title:txtColor="#ffffff"
            title:txtSize="16sp"/>
    </RelativeLayout>
    
    

    注意代码中的这行,自己定义命名空间,com.example.androidDemo是项目包路径

    xmlns:title="http://schemas.android.com/apk/res/com.example.androidDemo"


    使用自己定义命名空间:
            title:txtName="你好"
            title:txtColor="#ffffff"
            title:txtSize="16sp"

    
    在View的构造方法中,获得我们的自己定义的样式
    

    public class CustomTitleView extends View{
    
        private  String txtName;
        private int txtColor,txtSize;
        private  Paint mPaint;
        private Rect mBounds;
    
    
        public CustomTitleView(Context context) {
            this(context, null);
        }
    
        public CustomTitleView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
    
    
        }
    
        public CustomTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs,R.styleable.titleStyle,defStyleAttr,0);
    
            int n = typedArray.getIndexCount();
    
            for (int i = 0; i < n; i++){
                int attr = typedArray.getIndex(i);
                switch (attr){
    
                    case 0:
    
                        txtName = typedArray.getString(attr);
                        break;
                    case 1:
    
                        txtColor = typedArray.getColor(attr, Color.BLACK);
                        break;
                    case 2:
                        txtSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                                TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                        break;
    
                }
            }
            typedArray.recycle();
    
            /**
             * 获得绘制文本的宽和高 
             */
            mPaint = new Paint();
            mPaint.setTextSize(txtSize);
            // mPaint.setColor(mTitleTextColor);
            mBounds = new Rect();
            mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
        }
    
        @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
                {
                    mPaint.setTextSize(txtSize);
                    mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
                    float textWidth = mBounds.width();
                    int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
                    width = desired;
                }
    
                if (heightMode == MeasureSpec.EXACTLY)
                {
                    height = heightSize;
                } else
                {
                    mPaint.setTextSize(txtSize);
                    mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
                    float textHeight = mBounds.height();
                    int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
                    height = desired;
                }
    
    
    
                setMeasuredDimension(width, height);
    
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            mPaint.setColor(Color.YELLOW);
            canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
    
            mPaint.setColor(txtColor);
            canvas.drawText(txtName, getWidth() / 2 - mBounds.width() / 2, getHeight() / 2 + mBounds.height() / 2, mPaint);
    
        }
    }
    


    当中

    MeasureSpec.EXACTLY推断你传人的宽,高是不是精确赋值
    android:layout_width="wrap_content"
     android:layout_height="wrap_content"


    假设是wrap_content,

     mPaint.setTextSize(txtSize);
                    mPaint.getTextBounds(txtName, 0, txtName.length(), mBounds);
                    float textWidth = mBounds.width();
                    int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
                    width = desired;

    假设是200dp这类精确的宽高值,

    if (widthMode == MeasureSpec.EXACTLY)
                {
                    width = widthSize;
                } 

    效果图 ,是不是非常好用呢


  • 相关阅读:
    java学习笔记 --- 面向对象3
    java学习笔记 --- 面向对象2
    Idea代码生成插件制作
    口罩检测比赛
    公开人脸检测库dlib的使用介绍
    VS工程中image watch的安装和卸载
    mysql导入导出sql文件
    git 本地项目推送至远程仓库
    mysql 操作提示 1366 Incorrect string value
    python入门
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3952228.html
Copyright © 2020-2023  润新知