Android进阶之绘制-自定义View完全掌握(五)

在自定义类继承View实现自定义控件的过程中,我们还应该对一些自定义属性有所了解。
我们通过一个案例来学习一下。
新建一个android项目,然后我们创建一个类MyAttributeView继承View。
贴出MyAttributeView的代码。

package com.itcast.test0501;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 *  自定义属性
 */
public class MyAttributeView extends View {

    public MyAttributeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

}

然后我们在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="com.itcast.test0501.MainActivity">

    <com.itcast.test0501.MyAttributeView
        app:my_age="100"
        app:my_name="Android0501"
        app:my_bg="@drawable/a"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

发现没有,my_age,my_name,my_bg都是我们自定义的属性,前面的命名空间我们可以随意命名,不一定非得叫app。那现在运行项目的话显然是不行的,因为我们属性还没去定义呢。
那么接下来我们就去定义我们的属性。
在values文件夹下新建attrs.xml文件。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--定义名字为MyAttributeView的属性集合-->
    <declare-styleable name="MyAttributeView">
        <!--定义名字为my_name,并且类型为string的属性-->
        <attr name="my_name" format="string" />
        <!--定义名字为my_age,并且类型为integer的属性-->
        <attr name="my_age" format="integer" />
        <!--定义名字为my_bg,并且类型为reference|color的属性-->
        <attr name="my_bg" format="reference|color" />
    </declare-styleable>
</resources>

这样我们的属性就定义好了。
我们可以思考一下,一个类在布局文件中使用,它是如何被呈现到屏幕上的,我们知道,在java中,一个类要想被使用,该类就必须被实例化,那么在android中,它是如何对这个自定义的View类进行实例化显示的呢?它使用的是反射技术。它会把所有属性封装到AttributeSet类中,那么你会发现,在自定义类中重写的构造方法的参数里就存在这么一个属性的集合类。所以我们就可以知道为什么自定义的控件需要写类的全路径,因为反射是需要一个类的完整路径的。在编译的时候,会对布局文件进行pull解析,遇到类,就利用类路径通过反射技术封装属性。
那接下来就是获取属性了,获取属性我们有三种方式。

1、用命名空间去获取

2、遍历属性集合

3、使用系统工具,获取属性

修改MyAttributeView类的代码。

package com.itcast.test0501;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 *  自定义属性
 */
public class MyAttributeView extends View {

    private int myAge;
    private String myName;
    private Bitmap myBg;

    public MyAttributeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        //获取属性三种方式
        //1、用命名空间去获取
        String age = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "my_age");
        String name = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "my_name");
        String bg = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "my_bg");
        Log.d("TAG1","age==" + age + ",name==" + name + ",bg==" + bg);

        //2、遍历属性集合
        for(int i = 0;i < attrs.getAttributeCount();i++){
            Log.d("TAG2",attrs.getAttributeName(i) + "==" + attrs.getAttributeValue(i));
        }

        //3、使用系统工具,获取属性

    }
}

运行项目,查看日志。

这样就把我们设置的属性值拿出来了。
但是,不知道大家发现了没有,这两种方法拿到的图片值都是地址值吧,我们要想将设置的图片属性值通过某种方法显式到屏幕上,对于地址值,我们有办法操作吗?应该是没有的,所以,我们采用第三种方式,使用系统工具来获取属性值。
我们修改MyAttributeView的代码。

package com.itcast.test0501;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 *  自定义属性
 */
public class MyAttributeView extends View {

    private int myAge;
    private String myName;
    private Bitmap myBg;

    public MyAttributeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        //获取属性三种方式
        //1、用命名空间去获取
        String age = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "my_age");
        String name = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "my_name");
        String bg = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "my_bg");
        Log.d("TAG1","age==" + age + ",name==" + name + ",bg==" + bg);

        //2、遍历属性集合
        for(int i = 0;i < attrs.getAttributeCount();i++){
            Log.d("TAG2",attrs.getAttributeName(i) + "==" + attrs.getAttributeValue(i));
        }

        //3、使用系统工具,获取属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MyAttributeView);
        for(int i = 0;i < typedArray.getIndexCount();i++){
            int index = typedArray.getIndex(i);

            switch (index){
                case R.styleable.MyAttributeView_my_age:
                    myAge = typedArray.getInt(index,0);
                    break;
                case R.styleable.MyAttributeView_my_name:
                    myName = typedArray.getString(index);
                    break;
                case R.styleable.MyAttributeView_my_bg:
                    Drawable drawable = typedArray.getDrawable(index);
                    BitmapDrawable drawable1 = (BitmapDrawable) drawable;
                    myBg = drawable1.getBitmap();
                    break;
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        canvas.drawText(myName + "---" + myAge,50,50,paint);
        canvas.drawBitmap(myBg,60,60,paint);
    }
}

通过系统工具,我们可以把图片的属性值转换为Bitmap,然后在onDraw()方法中将位图绘制出来。
我们运行项目,预览效果。

我们设置的属性信息都被成功绘制上来了。
由此,我们必须得掌握第三种获取属性值的方法,前两种有能力去掌握的也可以去理解一下。
源码我已上传至GitHub,感兴趣的同学可以下载阅读一下。
点击下载源码

原文地址:https://www.cnblogs.com/blizzawang/p/11411749.html

时间: 2024-10-11 05:48:41

Android进阶之绘制-自定义View完全掌握(五)的相关文章

Android进阶之绘制-自定义View完全掌握(二)

这是自定义View系列的第二篇博客,我们继续来学习关于自定义View的知识. 今天我们来实现一下广告条案例. 我们要实现的是这样的一个效果. 要想实现这样的效果,我们可以借助ViewPager控件,然后加上自定义的一些控件即可完成.那么现在就开始吧. 新建一个android项目. 修改activity_main.xml文件. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:a

Android进阶之绘制-自定义View完全掌握(四)

前面的案例中我们都是使用系统的一些控件通过组合的方式来生成我们自定义的控件,自定义控件的实现还可以通过自定义类继承View来完成.从该篇博客开始,我们通过自定义类继承View来实现一些我们自定义的控件. 我们通过一个案例来学习,现在来实现这样一个效果. 我们新建一个类MyToggleButton,让它继承View. 注意,一定要重写带两个参数的构造方法,因为如果我们在布局文件使用该类,将会用这个构造方法实例该类,如果没有就崩溃. 介绍一下一个控件从创建到显示过程中的主要方法. 执行构造方法实例化

Android进阶之绘制-自定义View完全掌握(三)

自定义View系列的第三篇博客,我们来学习如何实现自定义下拉框. 今天的程序,我们来实现这样的一个效果. 布局非常简单,我们直接开始编码. 修改activity_main.xml文件的代码. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:

Android进阶之绘制-自定义View完全掌握(一)

Android的UI设计可以说是决定一个app质量的关键因素,因为人们在使用app的时候,最先映入眼帘的就是app的界面了,一个美观.充实的界面能够给用户带来非常好的体验,会在用户心中留下好的印象. 对于UI设计,Android原生的控件加上一些开源库的使用,已经能够满足大部分的UI需求,但是,某些比较新颖.花哨的控件效果,我们只能通过自定义View来实现,那么,从该篇博客开始,我将记录关于Android自定义View的学习内容,并将其整理呈现给大家. 我们来实现一个优酷菜单案例,在案例中会涉及

Android 如何 画 柱状图 -------自定义View

实现了 柱状图 根据 SeekBar的滑动 改变的效果: 图示效果: 自定义View的代码: package com.example.coustomviewdemo; import android.R.color; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.g

Android属性动画与自定义View——实现vivo x6更新系统的动画效果

晚上好,现在是凌晨两点半,然后我还在写代码.电脑里播放着<凌晨两点半>,晚上写代码,脑子更清醒,思路更清晰. 今天聊聊属性动画和自定义View搭配使用,前面都讲到自定义View和属性动画,但是一起用的还是不多,刚巧今晚手机提示我更新系统,我看到那个更新的动画还不错,仔细的分析了一下,于是我也决定写一个,不是一模一样的,但是效果和原理是一样的. 先看看图: 这是一张静态的图,这里有三个波浪线,当下载完之后,波浪线会往上活动,一直到消失. 所以难点也是在这个波浪线上.这个波浪线类似于一个水波纹,也

Android知识梳理之自定义View

虽然android本身给我们提供了形形色色的控件,基本能够满足日常开发的需求,但是面对日益同质化的app界面,和不同的业务需求.我们可能就需要自定义一些View来获得比较好的效果.自定义View是android开发者走向高级开发工程师必须要走的一关. 转载请标明出处:http://blog.csdn.net/unreliable_narrator/article/details/51274264 一,构造函数: 当我们创建一个类去继承View的时候,会要求我们至少去实现一个构造函数. publi

Android ——利用OnDraw实现自定义View(转)

自定义View的实现方式大概可以分为三种,自绘控件.组合控件.以及继承控件.本文将介绍自绘控件的用法.自绘控件的意思是,这个控件上的内容是用onDraw函数绘制出来的.关于onDraw函数的介绍可参看 Android视图绘制流程完全解析,带你一步步深入了解View(二) . 例子1:在layout文件中使用自绘控件 出处:http://blog.csdn.net/guolin_blog/article/details/17357967 下面我们准备来自定义一个计数器View,这个View可以响应

【Android 应用开发】 自定义 View 组件 -- 圆形进度条

转载著名出处 : http://blog.csdn.net/shulianghan/article/details/40351487 代码下载 : -- CSDN 下载地址 : http://download.csdn.net/detail/han1202012/8069497 ; -- GitHub 地址 : https://github.com/han1202012/CircleProcess.git ; -- 工程示例 : 一. 相关知识点解析 1. 自定义 View 组件构造方法 构造方