二.自定义View 基础知识attr


前言:
自定义view是android自定义控件的核心之一,那么在学习自定义view之前,我们先来了解下自定义view的自定义属性的attr的用法。

1.attr

1.1 概念

(1)attr 的简单理解就是一个属性约束,约束具体属性字段的属性的数据类型(boolean、string、float…)

(2)attr的文件名称不是固定的,只是方便理解和规范,也可以是其他名称,创建attr 文件在res/values 下

2.attr 作用

attr 作用就是约束属性数据类型,xml资源文件中定义各种attr,指定attr的数据类型。

3.attr 使用方式

(1)通过 为自定义View添加属性
(2) 在xml中为相应的属性声明属性值
(3)在运行时(一般为构造函数)获取属性值
(4)将获取到的属性值应用到View

2.attr的简单创建

(1)我们在res/values目录下新建了一个名为attrs.xml文件,文件名是什么不重要,只要是xml文件就行。
(2)在该文件中定义我们自定义view所支持的xml 属性。

例如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="sext" format="string|integer"/>  公共属性
    <attr name="isSignal" format="boolean"/>

    <declare-styleable name="View1">
        <attr name="viewBg" format="reference"/>
        <attr name="cirColor" format="color|integer"/>
        <attr name="txtVisibility" format="string"/>
        <attr name="isSignal"/>                    直接引用公共属性
    </declare-styleable>>
</resources>

declare-styleable name: 是自定义view 的名字
attr name : 是自定义的属性
format :自定义属性支持的类型 enum、boolean、color、dimension、flag、float、fraction、integer、reference、string。

注意
如果定义多个<declare-styleable name 中的attr name不能相同,否则会报错,那么就把相同的提取到<declare-styleable外部,定义成公共属性,例如 "<“attr name=“isSignal”/>”

3.format 数据类型具体参考

1.reference :参考某一资源ID

1)属性定义:
    <declare-styleable name = "名称">
          <attr name = "background" format = "reference" />
    </declare-styleable>2)属性使用:
     <ImageView
         android:layout_width = "42dip"
         android:layout_height = "42dip"
         android:background = "@drawable/图片ID"/> 

2.color:颜色值

1)属性定义:
    <declare-styleable name = "名称">
         <attr name = "textColor" format = "color" />
    </declare-styleable>2)属性使用:
   <TextView
         android:layout_width = "42dip"
         android:layout_height = "42dip"
          android:textColor = "#00FF00"/> 

3. boolean:布尔值

1)属性定义:
    <declare-styleable name = "名称">
        <attr name = "focusable" format = "boolean" />
    </declare-styleable>2)属性使用:
    <Button
       android:layout_width = "42dip"
       android:layout_height = "42dip"
       android:focusable = "true"/> 

4. dimension:尺寸值

1)属性定义:
    <declare-styleable name = "名称">
           <attr name = "layout_width" format = "dimension" />
    </declare-styleable>2)属性使用:
   <Button
          android:layout_width = "42dip"
          android:layout_height = "42dip"/> 

5. float:浮点值

1)属性定义:
     <declare-styleable name = "AlphaAnimation">
         <attr name = "fromAlpha" format = "float" />
         <attr name = "toAlpha" format = "float" />
      </declare-styleable>2)属性使用:
     <alpha
         android:fromAlpha = "1.0"
         android:toAlpha = "0.7"/> 

6. integer:整型值

1)属性定义:
     <declare-styleable name = "AnimatedRotateDrawable">
          <attr name = "visible" />
          <attr name = "frameDuration" format="integer" />
          <attr name = "framesCount" format="integer" />
          <attr name = "pivotX" />
          <attr name = "pivotY" />
          <attr name = "drawable" />
     </declare-styleable>2)属性使用:
   <animated-rotate
     xmlns:android = "http://schemas.android.com/apk/res/android"  
        android:drawable = "@drawable/图片ID"  
        android:pivotX = "50%"  
        android:pivotY = "50%"  
        android:framesCount = "12"  
        android:frameDuration = "100" /> 

7. string:字符串

1)属性定义:
    <declare-styleable name = "MapView">
       <attr name = "apiKey" format = "string" />
    </declare-styleable>2)属性使用:
   <com.google.android.maps.MapView
        android:layout_width = "fill_parent"
        android:layout_height = "fill_parent"
                    android:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"
     /> 

8. fraction:百分数

1)属性定义:
    <declare-styleable name="RotateDrawable">
        <attr name = "visible" />
        <attr name = "fromDegrees" format = "float" />
        <attr name = "toDegrees" format = "float" />
        <attr name = "pivotX" format = "fraction" />
        <attr name = "pivotY" format = "fraction" />
        <attr name = "drawable" />
   </declare-styleable>2)属性使用:

   <rotate
    xmlns:android = "http://schemas.android.com/apk/res/android" 
             android:interpolator = "@anim/动画ID"
             android:fromDegrees = "0" 
             android:toDegrees = "360"
             android:pivotX = "200%"
             android:pivotY = "300%" 
             android:duration = "5000"
             android:repeatMode = "restart"
             android:repeatCount = "infinite"  /> 

9. enum:枚举值

1)属性定义:
      <declare-styleable name="名称">
         <attr name="orientation">
            <enum name="horizontal" value="0" />
            <enum name="vertical" value="1" />
         </attr>            
       </declare-styleable>2)属性使用:
        <LinearLayout
          xmlns:android = "http://schemas.android.com/apk/res/android"
          android:orientation = "vertical"
          android:layout_width = "fill_parent"
          android:layout_height = "fill_parent">
        </LinearLayout> 

10. flag:位或运算

1)属性定义:
   <declare-styleable name="名称">
      <attr name="windowSoftInputMode">
            <flag name = "stateUnspecified" value = "0" />
            <flag name = "stateUnchanged" value = "1" />
            <flag name = "stateHidden" value = "2" />
            <flag name = "stateAlwaysHidden" value = "3" />
            <flag name = "stateVisible" value = "4" />
            <flag name = "stateAlwaysVisible" value = "5" />
            <flag name = "adjustUnspecified" value = "0x00" />
            <flag name = "adjustResize" value = "0x10" />
            <flag name = "adjustPan" value = "0x20" />
            <flag name = "adjustNothing" value = "0x30" />
     </attr>         
   </declare-styleable>2)属性使用:
     <activity
        android:name = ".StyleAndThemeActivity"
        android:label = "@string/app_name"
        android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
        <intent-filter>
            <action android:name = "android.intent.action.MAIN" />
               <category android:name = "android.intent.category.LAUNCHER" />
                   </intent-filter>
             </activity> 

注意:
属性定义时可以指定多种类型值

1)属性定义:
     <declare-styleable name = "名称">
        <attr name = "background" format = "reference|color" />
     </declare-styleable>2)属性使用:
     <ImageView
        android:layout_width = "42dip"
        android:layout_height = "42dip"
        android:background = "@drawable/图片ID|#00FF00" /> 

4.attr 的使用

自定义view简单实现步骤:
(1)首先创建attrs自定义属性文件名称,定义属性以及相关数据类型
(2)再次创建自定义view,然后读取相关属性完成需要的view相关布局、绘制等工作
(3)最后在xml布局文件中引用或者直接在代码中new一个相关对象进行使用

例如:自定义一个textview在屏幕上显示出来
attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="viewText" format="string|integer"/>
    <attr name="isSignal" format="boolean"/>
    <attr name="viewBg" format="color"/>

    <declare-styleable name="YText">
        <attr name="viewText"/>
        <attr name="isSignal"/>
        <attr name="viewBg" />
        <attr name="viewTextBg" format="color"/>
        <attr name="viewSize" format="integer"/>
    </declare-styleable>
</resources>

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout   
    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=".MainActivity">
    <com.example.demo.YText
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:isSignal="false"
        app:viewText="自定义View"
        app:viewBg="@color/colorYellow"
        app:viewTextBg="@color/colorRed"
        app:viewSize="80">
    </com.example.demo.YText>
    
</androidx.constraintlayout.widget.ConstraintLayout>

注意: res/android 和 res-auto

xmlns:android=http://schemas.android.com/apk/res/android
xmlns:app=http://schemas.android.com/apk/res-auto
这2个实际上前者是就是让你引用系统自带属性的,后者是让你使用attrs库里自定义属性的。

YText.java

public class YText extends View {
    private String mText;
    private boolean isSignal;
    private int viewTextbg;
    private int viewBg;
    private int mTextSize;
    private Paint paint;
    public YText(Context context) {
        this(context,null); //手动new 调用
    }

    public YText(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0); //xml 中调用
        parseXmlAttributes(context,attrs);
    }
    public YText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public void parseXmlAttributes(Context context,AttributeSet attributeSet) {
        TypedArray typedArray = context.obtainStyledAttributes(attributeSet,R.styleable.YText);
        for (int i=0;i<typedArray.getIndexCount();i++) {
                switch (typedArray.getIndex(i)) {
                    case R.styleable.YText_viewText:
                        mText = typedArray.getString(R.styleable.YText_viewText);
                        break;
                    case R.styleable.YText_isSignal:
                        isSignal = typedArray.getBoolean(R.styleable.YText_isSignal,true);
                        break;
                    case R.styleable.YText_viewBg:
                        viewBg  = typedArray.getColor(R.styleable.YText_viewBg, Color.YELLOW);
                        break;
                    case R.styleable.YText_viewTextBg:
                        viewTextbg  = typedArray.getColor(R.styleable.YText_viewTextBg, Color.YELLOW);
                        break;
                    case R.styleable.YText_viewSize:
                        mTextSize = typedArray.getInt(R.styleable.YText_viewSize,38);
                        break;
                }
            }
        typedArray.recycle();
        paint = new Paint();
        paint.setTextSize(mTextSize);

    }
    @Override
    protected void onDraw(Canvas canvas) {
        paint.setColor(viewBg);
        canvas.drawRect(0,0,getMeasuredWidth(), getMeasuredHeight(), paint);
        paint.setColor(viewTextbg);
       canvas.drawText(mText,100,100,paint);
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值