Android读取系统控件的自定义属性

解析:TypedArray 为什么需要调用recycle() 在 Android 自定义 View 的时候,需要使用 TypedArray 来获取 XML layout 中的属性值,使用完之后,需要调用 recyle() 方法将 TypedArray 回收。那么问题来了,这个TypedArray是个什么东西?为什么需要回收呢?TypedArray并没有占用IO,线程,它仅仅是一个变量而已,为什么需要 recycle? 为了解开这个谜,首先去找官网的 Docu 阅读详情

读取自定义属性

通常读取自定义控件的自定义属性是在自定义控件的构造函数中用context的obtainStyledAttributes方法获取TpyeArray对象,通过TpyeArray对象获取个自定义属性,最后别忘了recycle()。

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyViewGroup" >
        <attr name="x_in" format="float"/>
        <attr name="y_in" format="float"/>

    </declare-styleable>
</resources>
自定义控件
public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.MyViewGroup);
        x_in=array.getFloat(R.styleable.MyViewGroup_x_in,0);
        y_in=array.getFloat(R.styleable.MyViewGroup_y_in,0);
        array.recycle();
    }

当系统控件中带有自定义属性如何读取?

<ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            vg:x_in="0.2"
            vg:y_in="0.3"
            />

方法一:利用LayoutParams

当自定义控件是ViewGroup的子控件时且带有自定义属性的系统控件是其内,如下布局

 <com.znvoid.blogs.MyViewGroup
        android:id="@+id/myview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            vg:x_in="0.2"
            vg:y_in="0.3"
            />
    </com.znvoid.blogs.MyViewGroup>

首先了解下generateLayoutParams()方法,为父容器生成 子view 的布局LayoutParams在Layoutinflater.rInflate()中被调用

public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new LayoutParams(getContext(), attrs);
}

如果一个View想要被添加到这个容器中,这个view可以调用此方法生成和容器类匹配的布局LayoutParams;

那么可以在自定义控件中重写generateLayoutParams()方法生成自定义的LayoutParams类对象从而达到读取自定义属性。

  @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MyLayoutParams(getContext(), attrs);
    }

    class MyLayoutParams extends LayoutParams{
        public float x_in;
        public float y_in;


        public MyLayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            TypedArray array=c.obtainStyledAttributes(attrs,R.styleable.MyViewGroup);
            x_in=array.getFloat(R.styleable.MyViewGroup_x_in,0);
            y_in=array.getFloat(R.styleable.MyViewGroup_y_in,0);
            //System.out.println("x_in"+x_in);
            array.recycle();
        }
        
    }
方法二 LayoutInflater

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        app:x_in="1.2"
        app:y_in="2.3"/>

</RelativeLayout>
先看LayoutInflater.inflate()源码

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
    return inflate(resource, root, root != null);
}
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
    final Resources res = getContext().getResources();
    if (DEBUG) {
        Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
                + Integer.toHexString(resource) + ")");
    }

    final XmlResourceParser parser = res.getLayout(resource);
    try {
        return inflate(parser, root, attachToRoot);
    } finally {
        parser.close();
    }
}
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
    synchronized (mConstructorArgs) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");

       //省略代码......
            
                // Temp is the root view that was found in the xml
                final View temp = createViewFromTag(root, name, inflaterContext, attrs);

        
	//省略代码...... 
}}
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
        boolean ignoreThemeAttr) {  
//省略代码...... 
try { View view; if (mFactory2 != null) { view = mFactory2.onCreateView(parent, name, context, attrs); } else if (mFactory != null) { view = mFactory.onCreateView(name, context, attrs); } else { view = null; } if (view == null && mPrivateFactory != null) { view = mPrivateFactory.onCreateView(parent, name, context, attrs); }
//省略代码......        
}

通过源码看出LayoutInflater.inflate()方法会调用createViewFromTag()---->mFactory.onCreateView(name,context,attrs)

只要重写Factory.onCreateView()就能得到控件的AttributeSet属性对象

*
 * 自定义布局加载器
 */

public class MyLayoutInflater extends LayoutInflater {

    public MyLayoutInflater( Context newContext) {
        super( newContext);

        setFactory(new MyFatory());
    }



    public MyLayoutInflater(LayoutInflater original, Context newContext) {
        super(original, newContext);
        setFactory2(new MyFactory2());
    }

    @Override
    public LayoutInflater cloneInContext(Context newContext) {
        return new MyLayoutInflater(this, newContext);
    }

    public class MyFatory implements LayoutInflater.Factory {

        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            return doCreateView(name,context,attrs);
        }

//
    }
    public View doCreateView(String name, Context context, AttributeSet attrs) {
        View view = null;
        if (name.contains(".")) {//自定义控件生成
            view = doCreateViewWithPackage(name, null, context, attrs);

        } else {//系统控件的生成

            if ((view = doCreateViewWithPackage(name, "android.view.", context, attrs)) == null)
                view = doCreateViewWithPackage(name, "android.widget.", context, attrs);


        }
        if (view != null) {//自定义属性的读取
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyViewGroup);
            float x_in = array.getFloat(R.styleable.MyViewGroup_x_in, 0);
            float y_in = array.getFloat(R.styleable.MyViewGroup_y_in, 0);
            System.out.println("x_in的值:" + x_in);

            array.recycle();
        }

        return view;
    }
    private View doCreateViewWithPackage(String name, String prefix, Context context, AttributeSet attrs) {//根据控件名创建控件对象
        try {
            return MyLayoutInflater.this.createView(name, prefix, attrs);
        } catch (ClassNotFoundException e) {
            //e.printStackTrace();
        }
        return null;

    }

    class MyFactory2 implements Factory2 {

        @Override
        public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
            return onCreateView(name,context,attrs);
        }

        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {

            return doCreateView(name,context,attrs);
        }


    }

}
用自定义布局加载器去加载带有自定义属性的系统控件的布局就能读取其中的自定义属性






Android自定义倒计时控件开发实战 在移动应用开发中,原生控件往往难以满足复杂多变的UI需求。随着用户体验要求的不断提升,自定义控件已成为构建高性能、高可维护性Android应用的重要手段之一。倒计时功能广泛应用于电商抢购、活动促销、任务倒计等场景,而系统并未提供原生的倒计时视图组件,因此开发一个可复用、易扩展的自定义倒计时控件显得尤为必要。Android自定义控件主要分为三类:继承View进行深度定制、组合多个控件形成复合控件、重写ViewGroup实现特殊布局逻辑。其核心流程包括测量(onMeasure) 阅读详情

相关推荐

线性代数知识点整理

线性代数基础知识点摘要整理

cuguanren的博客 3万+

TypedArray类获取属性

AttributeSet AttributeSet是xml文件中元素属性的一个集合。其中提供了各种Api,供我们从已编译好的xml文件获取属性值,如getAttributeIntValue,getAttributeBooleanValue,getAttributeFloatValue等,会返回对应类型的属性值,传入的参数一般有两种形式,如下: getAttributeXXXValue(int in...

weixin_45830683的博客 1024

prometheus 从入门到精通(史上最全)

Prometheus(由go语言开发)是一套开源的监控&报警&时间序列(按照时间排序)数据库的组合。因为kubernetes(俗称k8s)的流行带动了prometheus的发展。它可以监控主机,服务,容器,支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上万台规模的集群。原文链接:https://blog.youkuaiyun.com/qq_45277554/article/details/130917620时间序列数据。

流水_鱼鱼的博客 1万+

Android obtainStyledAttributes获取属性值

obtainStyledAttributes是干什么的有过自定义属性或者查看过系统View相关子类源码的人可能对这个方法都不会陌生。 该方法是Context类为我们提供的获取style中特定属性值的方法。通过这个方法,我们就可以获取在style中定义的各种属性值,然后根据获取到的不同的属性值实现差异化的效果。一种典型的使用方式是: //TextView 构造方法片选代码

FengShanChuiChui的博客 1万+

Python实战:用jieba和WordCloud打造电商评论情感分析工具(附完整代码)

本文详细介绍了如何使用Python的jieba分词和WordCloud库构建电商评论情感分析工具,涵盖数据预处理、情感分析、可视化展示等关键步骤,并提供完整代码实现。通过该工具,开发者可以高效分析电商评论数据,挖掘消费者情感倾向,为产品改进和决策提供数据支持。

weixin_30316097的博客 415

别再卡在Google验证了!用Header Editor插件5分钟搞定TryHackMe注册(附最新.json规则)

本文提供了使用Header Editor插件快速解决TryHackMe注册时Google验证失败问题的详细指南。通过导入特定的JSON规则文件,用户可以轻松绕过网络限制,5分钟内完成账号注册,无需复杂设置。文章包含完整的配置步骤、常见问题解决方案以及安全使用建议。

weixin_30736301的博客 464

Android自定义属性TypedArray详解

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!可以扫码获取!!(备注:Android)**

2401_84132479的博客 1216

STM32 A/B分区OTA升级实战:从原理到避坑指南

本文详细解析STM32 A/B分区OTA升级的核心原理与实战实现,涵盖双分区设计、Bootloader开发、固件传输验证及常见问题解决方案。重点介绍通过A/B分区实现无缝升级与安全回滚的机制,帮助开发者规避典型陷阱,提升嵌入式系统远程更新的可靠性与效率。

qqq44的博客 1109

Android-自定义AttributeSet属性

一般是当项目中遇到这样的场景需要自定义控件的AttributeSet属性:一个自定义控件的有些属性内容是随着外部条件而动态改变的,for example:一个自定义的ListView控件,需要在底部添加一个View,而这个View在不同的模块使用中传入的

qq1377399077的专栏 713

ads传统功放设计笔记(3)

传统功放设计的流程一般包括以下这些步骤: 1、明确设计目标 2、选择功放管子 3、确定静态工作点 4、设计偏置电路 5、判断稳定性 6、负载与源牵引 7、输入输出阻抗匹配 8、原理图优化 9、大信号仿真 10、版图设计 11、版图联合仿真 12、pcb设计 第二节我们设计仿真了功放的原理图。之后我们需要对版图进行设计和仿真。 10、版图设计 首先将S参数控件都打叉,还要去掉电源、源负载阻抗、地、芯片、电容。在原先电容和芯片的位置加上gap,设置好长度和间隔。之后在电源引脚、输入输出引脚和隔离的两端加上端口。

qq_40995480的博客 6029

手把手教你解决COLMAP编译中的Ceres CUDA支持问题(附详细配置步骤)

本文详细解析了COLMAP编译中Ceres CUDA支持问题的完整解决方案,包括环境准备、Ceres Solver的CUDA编译配置、COLMAP的CUDA集成配置等关键步骤。通过优化CMake参数和解决常见错误,帮助技术人员充分利用GPU加速优势,提升三维重建效率。

vodka的博客 861

【Android】自定义View

本文介绍了Android中自定义View的三种类型:自定义View、自定义ViewGroup和自定义组合控件。重点讲解了继承系统控件(如TextView)和继承View的自定义View实现方法,通过InvalidTextView和RectView两个示例,详细说明了如何重写onDraw()方法进行绘制、处理padding属性以及wrap_content属性的注意事项。在继承View的自定义View中,需要注意在onDraw()中获取正确尺寸、处理padding,并考虑wrap_content时的默认尺寸设置

fufu428的博客 214

如何学习总线技术

如何学习总线技术 以形象生动的比喻来描绘了总线技术的基本思想,指出了总线的基本分类和总线传输的基本原理,以及在学习过程中应当掌握的最基本的知识,对初学者有起到抛砖引入的作用。 0引言   如果一座只能容一个人来往的独木桥,两端的人都想要过桥,为了不拥挤、阻塞,那我们就得采取有效的办法。比如规定某段时间哪端的人过桥,另一端的人就等着该他过桥的时间段的到来,同时也还可以规定人多时要按先来后到或年

ce123的技术博客 8528

android面试自定义view,资深面试官:自定义View的实现方式,你知道几种?

前提为什么要自定义View?怎么自定义View?当 Android SDK 中提供的系统 UI 控件无法满足业务需求时,我们就需要考虑自己实现 UI 控件。而且自定义View在面试时是很经典的一道Android面试题,对其的理解程度决定面试官看你的高度。PS:关于我本人是一个拥有6年开发经验的帅气Android工程师,记得看完点赞,养成习惯,微信搜一搜「 程序猿养成中心 」关注这个喜欢写干货的程序...

weixin_29054195的博客 1108

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android 自定义控件与布局学习笔记

这篇文章总结了Android自定义控件的两种主要实现方式: 布局复用方式:通过include和merge标签复用XML布局,适合简单UI复用,但逻辑仍需在Activity中处理。merge标签可以减少布局层级嵌套。 自定义ViewGroup方式:通过继承ViewGroup类实现更完整的封装,包含以下关键步骤: 创建布局XML文件 继承RelativeLayout等布局类 在init中加载布局 绑定子控件和事件 对外暴露方法 文章还提供了完整的代码示例,包括自定义Toolbar的实现,展示了如何定义回调接口、

zzb1580的博客 387

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

[Android自定义控件] Android自定义控件

开发自定义控件的步骤: 1、了解View的工作原理 2、 编写继承自View的子类 3、 为自定义View类增加属性 4、 绘制控件 5、 响应用户消息 6 、自定义回调函数 一、View结构原理 Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类。 View定义了绘图的基本操...

weixin_30896763的博客 64

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android 相关

1.通过typeface设置使用字体 http://www.cnblogs.com/bravestarrhu/archive/2012/07/17/2595598.html 2.

wslixb的专栏 666

Android系统控件获取自定义属性

我们如果想在ImageView,Button,TextView等系统控件中在XML中配置自定义属性该如何实现呢?例如我们有一个scrollView,在ScrollView里面有上述的一些控件的自定义属性,实现在滑动Scrollview时,里面的控件根据滑动的距离执行各自的动画进度。scrollivew里包含的这些控件可以是任意常用的控件,如 ImageView,Button,TextView等。我...

王温暖的博客 1288

Android自定义控件终极指南

Android自定义控件开发指南摘要:Android应用可通过两种方式实现自定义控件:1)继承现有控件扩展功能(如TextView),适合外观修改;2)继承View类完全自定义(如仪表盘),需重写onDraw等方法。开发步骤包括:创建子类、实现构造方法、重写核心方法(onDraw/onMeasure)、添加自定义属性(通过attrs.xml)。使用时需注意wrap_content支持、性能优化和复合控件实现。官方推荐优先继承现有控件,完全自定义时需掌握Canvas绘图技术。两种方式均需在XML布局中声明完整

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1337

Android 自定义属性与数据绑定(以一个自定义简单GIF控件为例)

首先完成基本的内容,自定义GIF控件,主要使用到的就是帧动画init();init();startGif();在xml文件中这样就可以使用这个自定义控件这是我最开始写的版本,仅仅完成了播放动画的要求,图片也是写死在里面的,当然我也可以选择在MainActivity使用findViewByID,再调用GifView中的setGifResourceIds去设置图片,但是如果我想用MVVM框架的话,这就是一个不合适的写法,所以我考虑使用自定义属性。创建一个XML文件,通常命名为。

嘴巴吃糖了 1063

android自定义view获取控件,android中如何使用自定义view,自定义控件属性,及动态自定义控件...

如何自定义View好处:特殊的效果,满足个性的需求流程:1) 创建一个类,继承View或它的子类2) 添加构造方法一个参数:在代码中创建对象两个参数:在布局文件中使用3) 重写onDraw()方法 一个矩形区域,画布Canvas 画笔Paint设置画笔属性// 创建画笔Paint paint = new Paint();paint.setColor(Color.RED);pa...

weixin_29408705的博客 287

Android 为系统控件添加属性

转载出处:https://www.cnblogs.com/setsailwu/p/3852261.html 这篇文章挺好,但是按照里面的步骤实际操作时,有些步骤对于新手来说会不懂为什么这么做。所以记录一下,我实际有效的操作步骤: Android 系统开发时,比如想给系统的EditText新增一个xml属性,新增后,其他app都可以调用这个属性。 比如新增一个,点击返回键时,不删除字符串,删除字符串的功能由其他按键控制,返回键只做返回作用。 <EditText andro.

qq_36749859的博客 617

Android中自定义属性的使用

自定义属性: 是指定义可以在布局文件的标签中使用的属性。如TextView控件中的Text属性,但是它是由系统提供的,现如今是由我们自己定义。 使用自定义视图属性的好处: 这样就可以通过布局xml的方式给视图对象指定自己定义的任意属性值, 而不是仅仅只能使用系统中内定的属性啦。 属性值的类型(format)有如下几种:              1、reference 引用类型值 : @id

liu_xi_xin的博客 9604

android 自定义控件 使用declare-styleable进行配置属性(源码角度)

最近在模仿今日头条,发现它的很多属性都是通过自定义控件并设定相关的配置属性进行配置,于是便查询了解了下declare-styleable,下面我把自己的使用感受和如何使用进行说明下。 declare-styleable:declare-styleable是给自定义控件添加自定义属性用的。 官方的相关内部控件的配置属性文档:http://developer.android.com

ysh06201418的专栏 827

Android自定义控件开发指南

继承现有控件:在现有控件的基础上,通过重写绘制方法或添加自定义属性,实现个性化需求。组合现有控件:将多个现有控件组合在一起,形成一个全新的控件。全新控件:完全从头开始,创建一个全新的控件。自定义属性是自定义控件的重要部分。设计合理的自定义属性,可以让开发者更方便地使用控件。属性命名规范:遵循Java命名规范,使用驼峰命名法。属性类型:支持多种类型,如颜色、尺寸、字符串等。属性描述:在属性文件中,对每个属性进行详细描述,方便开发者理解。

2501_92487643的博客 410

Android实例-手机安全卫士(九)-自定义组合控件的属性

一、目标。   在布局文件中使用自定义控件时,直接在属性中设置值,类似于在TextView控件中设置text属性来显示文本。 效果如图: 属性设置: 二、代码实现。   1、自定义命名空间,类似于TextView控件里面android:text属性前的android。在需要放置自定义控件的布局文件的布局方式(LinearLayout、RelativeLayo...

diouke4154的博客 160
znvoid
博客等级 码龄10年 0粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值