热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CreatingCustomViews自定义View

虽然Android为我们提供了很多的内置控件,但是有时候我们的独特的业务需求可能这些内置控件仍然无法满足,那么此时,就需要我们自定义控件。这系列文章将向你展示如何创建一个功能强大且

虽然Android为我们提供了很多的内置控件,但是有时候我们的独特的业务需求可能这些内置控件仍然无法满足,那么此时,就需要我们自定义控件。这系列文章将向你展示如何创建一个功能强大且可重复的View控件。

目录:

  • 创建自定义View Class Creating a View Class
  • 自定义绘图 Custom Drawing
  • 控件交互 Making the View Interactive
  • 优化View控件 Optimizing the View

自定义View

一个良好的自定义View应该能和Android内置的View控件一样,具有良好的表现:具有自己的属性能与用户进行交互占据有效的内存空间。因此一个自定义的View的Class应该具备以下几个特征:

  1. 继承自View或者是View的子类,在Android中所有的View控件比如:Button,TextView都是View的子类。
  2. 符合Android的标准
  3. 通过xml文件提供自定义的属性
  4. 能与用户交互,能够响应事件,传递事件
  5. 兼容Android多个平台和版本

有了以上的标准,那么接下来就学习如何构造一个功能完整的自定义View吧:
大体上分为以下若干步骤:

  • 继承一个View或者View子类
  • 在res/values/attrs.xml文件中自定义属性
  • 应用我们的自定义属性
  • 添加属性和事件
  • 供外界调用
  1. 在Android的所有View体系中,所有的控件都是继承自View的,所以我们自定义控件的时候也应该是继承View或者是View的子类,比如Button,TextView。需要注意的是:大部分时候,我们自定义View是为了想在布局文件中xml调用,此时,我们的自定义View需要覆盖如下的构造方法来能在xml中被实例化,否则会报错。

    class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {//必须有此构造函数才能在xml文件中被实例化
    super(context, attrs); //调用父类的构造函数
    }
    }

    另外,我们之所以自定义View大多数是因为想实现业务需求的View,此时基本是需要在重写onDraw()方法来绘制我们的View。

    @Override
    protected void onDraw(Canvas canvas) { //自定义View中都会重写此onDraw()方法
    super.onDraw(canvas); //调用父类的onDraw();
    // Draw the shadow
    canvas.drawOval(mShadowBounds, mShadowPaint);

// Draw the label text
if (getShowText()) {
canvas.drawText(mData.get(mCurrentItem).mLabel, mTextX, mTextY, mTextPaint);
}
// If the API level is less than 11, we can’t rely on the view animation system to
// do the scrolling animation. Need to tick it here and call postInvalidate() until the scrolling is done.
if (Build.VERSION.SDK_INT <11) {
tickScrollAnimation();
if (!mScroller.isFinished()) {
postInvalidate();
}
}
}

  1. 自定义属性
    自定义属性后就能像Android内置的View控件一样通过属性标签来控制,我们自定义属性的时候需要在res/values/attrs.xml文件下以为根标签属性名和类型以键值对的方式存储。






        
       




    需要注意的地方是:我们在布局文件中使用自定义属性的时候需要加上命名空间,命名空间可以加在根标签也可以加在自定义View标签内,一般直接加在根标签里。命名空间的格式如下:
    http://schemas.android.com/apk/res/[yourpackagename],比如:
    xmlns:custom=&#8221;http://schemas.android.com/apk/res/com.example.android.customviews&#8220;
    还有特殊的情况:在你自定义的View中有一个内部的自定义innerView,如果希望在xml文件中使用innerView的属性,比如PieChart内有个PieView的内部类,那么应该这样:
    com.example.customviews.charting.PieChart$PieView。在xml引用自定义View布局需要使用全名,代码如下:


    xmlns:android=&#8221;http://schemas.android.com/apk/res/android&#8220;
    xmlns:custom=&#8221;http://schemas.android.com/apk/res/com.example.customviews&#8220;> //自定义属性命名空间
    custom:showText=&#8221;true&#8221;
    custom:labelPosition=&#8221;left&#8221;
    />

  2. 在代码中应用我们自定义的属性,使xml中的属性能够产生效果
    当一个view从xml布局中创建后,其使用的所有属性都会读取并传递到view 构造器函数的AttributeSet中。但是倘若直接使用AttributeSet会有一些缺点比如:styles不能生效,引用的资源不能解析。这时,我们使用另外一种方法会好很多,使用[obtainStyledAttributes()](http://developer.android.com/reference/android/content/res/Resources.Theme.html#obtainStyledAttributes(android.util.AttributeSet, int[], int, int))将在xml定义的属性封装到 TypedArray中去。代码如下:


    public PieChart(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PieChart, 0, 0);
    try {
    mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
    mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
    } finally {
    a.recycle(); //释放资源
    }
    }

  3. 添加属性事件
    添加属性事件暴露方法,使view可以动态改变


    public boolean isShowText() {
    return mShowText;
    }
    public void setShowText(boolean showText) {
    mShowText = showText;
    invalidate();//重绘
    requestLayout();
    }

    注意:invalidate()和requestLayout
    requestLayout:当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view重新调用他的onMeasure onLayout来对重新设置自己位置。
    特别的当view的layoutparameter发生改变,并且它的值还没能应用到view上,这时候适合调用这个方法。invalidate:View本身调用迫使view重画。
    另外:一个好的自定义View应该暴露接口,提供对业务有用的部分监听机制供自己调用。比如:OnCurrentItemChanged(),onColorChanged(),onSizeChanged().

小结:

  • 对于自定义View需要注意的大概就是这些,但是在实际自己写的时候仍然会有很多的问题,需要多实践,多学习别人的代码,再结合自己的业务区自定义。当然如果有第三方的控件可以满足我们的业务需求,我们亦可以引用。

Google给出的一个完整的自定义view的例子:点击下载Customview.zip


推荐阅读
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • [echarts] 同指标对比柱状图相关的知识介绍及应用示例
    本文由编程笔记小编为大家整理,主要介绍了echarts同指标对比柱状图相关的知识,包括对比课程通过率最高的8个课程和最低的8个课程以及全校的平均通过率。文章提供了一个应用示例,展示了如何使用echarts制作同指标对比柱状图,并对代码进行了详细解释和说明。该示例可以帮助读者更好地理解和应用echarts。 ... [详细]
  • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
  • 俗话说,好记性不如烂笔头,这些东西也都是我Google来的,做个笔记以后自己安装也方便些。因为官方wiki的BeginnersGuide讲的非常好,大部分步骤按照wiki一步一步来就 ... [详细]
author-avatar
fjkfjaslfjsal_577
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有