• View 自定义 - 属性 xml


    一、重写构造

    没有空参构造必须重写,一共有四种(四参构造在 API21 加入)对应不同的创建方式。一般只需要重写前三个,通过 this 调用到三参构造中统一进行处理。

    单参构造

    View(Context context)

    代码中 new 创建实例的时候调用。

    双参构造

    View(Context context, AttributeSet attrs)

    xml中使用时调用(xml转java代码的时候反射),attrs是xml中的属性。

    三参构造

    View(Context context, AttributeSet attrs, int defStyleAttr)

    使用主题Style的时候调用。

    1. class MyView : View {
    2. //改成this调用2个参数的构造
    3. constructor(context: Context?) : this(context, null)
    4. //改成this调用3个参数的构造
    5. constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    6. //在3个参数的构造里统一进行处理
    7. constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
    8. //TODO...
    9. }
    10. }

    二、加载布局文件

    public View inflate(int resource, ViewGroup root)

    底层调用下面三参的重载,root != null 则 attachToRoot = true。

    public View inflate(int resource, ViewGroup root, boolean attachToRoot)

    参数resource:要加载的xml布局文件。

    参数root:添加到哪个父容器中。若为null则resource布局文件最外层设置的属性都无效。

    参数attachToRoot:是否将resource添加到root内。若为false,root显示的时候是没有resource的。

    1. LayoutInflater.from(context).inflate(R.layout.drawer4,this)
    2. //等价于
    3. LayoutInflater.from(context).inflate(R.layout.drawer4,this, true)
    4. //等价于
    5. val view = LayoutInflater.from(context).inflate(R.layout.drawer4, this, false)
    6. addView(view)

    三、自定义属性

    在 xml 中为控件设置的属性。自定义属性名称如果使用系统已定义的,例如 textSize 会在编译时报错,想使用需要定义为

    格式类型定义/使用

    string 字符串

    android:myContent = "Hello Word!"

    color 颜色

    android:myTextColor = "#00FF00"

    dimension 尺寸

    单位:px、dp、sp。

    android:myTextSize = "12.sp"

    reference 引用资源

    android:myBackground = "@drawable/图片ID"

    boolean 布尔

    android:myEnable = "true"

    float 浮点

    android:myAlpha = "0.5F"

    integer 整型

    android:myMaxLines = "3"

    fraction 百分比

    android:myOffset = "10%"

    enum 枚举

    枚举类型的属性在使用时不能使用多个值

           

            

    android:myOrientation = "vertical"

    错误用法 android:myOrientation = “vertical|horizontal”

    flag 位运算

    位运算类型的属性在使用的过程中可以使用多个值

           

            

            

    android:myGravity = "top|left"

    混合类型

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

    android:myBackground = "@drawable/图片ID"

    android:myBackground = "#00FF00"

    3.1 创建资源文件(属性声明)

    右键 values 目录 -> New File文件 -> 一般取名attrs.xml。

    1. <resources>
    2. <declare-styleable name="MyView">
    3. <attr name="myText" format="string" />
    4. <attr name="myTextColor" format="color" />
    5. <attr name="myTextSize" format="dimension" />
    6. <attr name="myMaxLength" format="integer" />
    7. <attr name="myBackground" format="reference|color" />
    8. <attr name="myInputType">
    9. <enum name="number" value="1"/>
    10. <enum name="text" value="2"/>
    11. attr>
    12. declare-styleable>
    13. resources>

    3.2 构造函数中配置

    重写一参、二参、三参构造,通过 this 调用到三参构造中统一处理。

    1. class MyView : View {
    2. private var text: String? = null
    3. private var textSize: Int? = null
    4. private var textColor: Int? = null
    5. private var maxLength: Int? = null
    6. private var background: Int? = null
    7. private var inputType: Int? = null
    8. //改成this调用2个参数的构造
    9. constructor(context: Context?) : this(context, null)
    10. //改成this调用3个参数的构造
    11. constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    12. //在这里统一进行处理
    13. constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
    14. context?.let {
    15. //返回一个与attrs中列举出的属性相关的数组,数组里面的值由样式属性指定
    16. val attributes = it.obtainStyledAttributes(attrs, R.styleable.MyView)
    17. //获取自定义属性(格式:属性名称_条目名称)
    18. text = attributes.getString(R.styleable.MyView_myText)
    19. textSize = attributes.getDimensionPixelSize(R.styleable.MyView_myTextSize, 0)
    20. textColor = attributes.getColor(R.styleable.MyView_myTextColor, Color.BLACK)
    21. maxLength = attributes.getInt(R.styleable.MyView_myMaxLength,1)
    22. background = attributes.getResourceId(R.styleable.MyView_myBackground,R.drawable.ic_launcher_foreground)
    23. inputType = attributes.getInt(R.styleable.MyView_myInputType,0)
    24. //回收资源
    25. attributes.recycle()
    26. }
    27. }
    28. }

    3.3 布局中使用(属性使用)

    只有引入了命名空间,XML文件才知道下面使用的属性应该去哪里找(哪里定义的,不能凭空出现,要有根据。

    • 根布局添加命名空间(只需要输入app,IDE会自动补全)。
    • 控件名称使用完整路径(只需要输入自定义View的类名,IDE会自动补全)。
    • 未自定义的属性View会去处理(继承自View),使用自定义的属性就是 app: 开头的。
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. xmlns:app="http://schemas.android.com/apk/res-auto"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. android:orientation="vertical">
    6. <com.example.kotlindemo.view.MyView
    7. android:layout_width="match_parent"
    8. android:layout_height="wrap_content"
    9. app:myBackground="@drawable/ic_launcher_foreground"
    10. app:myInputType="number"
    11. app:myText="Hello Word!"
    12. app:myTextColor="@color/black"
    13. app:myTextSize="20sp"
    14. app:myMaxLength="20"/>
    15. LinearLayout>
  • 相关阅读:
    安卓开发--如何将onPostExecute方法结果返回给调用方?
    【LLM模型篇】LLaMA2 | Vicuna | EcomGPT等
    经典排序算法
    保研笔记四 软件工程与计算卷二(8-12章)
    网络是怎样连接的--TCP大致控制流程
    分享丨写在工作13年后,个人的一点软件测试经历及感想……
    [计算机组成原理] 指令的完成过程
    Swagger简单使用
    git硬重置(hard reset)重找回
    项目完成小结:使用Blazor和gRPC开发大模型客户端
  • 原文地址:https://blog.csdn.net/HugMua/article/details/134300157