android自定义控件步骤_android如何自定义控件

android自定义控件步骤_android如何自定义控件,第1张

android自定义控件步骤_android如何自定义控件 在Android中,无论是熟知的布局,还是控件,统统全都继承自基类View。


自定义View实现有几种:① 自定义组合控件:多个控件组合成为一个新的控件,方便多处复用② 继承系统View控件:继承自TextView等系统控件,在系统控件的基础功能上进行扩展③ 继承View:不复用系统控件逻辑,继承View进行功能定义④ 继承系统ViewGroup:继承自LinearLayout等系统控件,在系统控件的基础功能上进行扩展⑤ 继承ViewGroup:不复用系统控件逻辑,继承ViewGroup进行功能定义

一、View的绘制流程View的绘制基本由measure()、layout()、draw()这个三个函数完成:measure:测量View的宽高,主要是View中的:measure(),setMeasuredDimension(),onMeasure()方法。


layout:计算当前View以及子View的位置,主要是View中的:layout(),onLayout(),setFrame()方法。


draw:视图的绘制工作,主要是View中的:draw(),onDraw()方法。



二、Android 屏幕坐标系在Android坐标系中,以屏幕左上角作为原点,这个原点向右是X轴的正轴,向下是Y轴正轴。


根据以上的坐标,结合View基类的相关API,涉及View的一些坐标方法,比如:getTop:View到其父布局顶边的距离getLeft:View到其父布局左边的距离getBottom:View到其父布局顶边的距离getRight:View到其父布局左边的距离结合以上的API,可以计算出视图的宽度和高度,可以使用如下方式计算:width = getRight – getLeft;height = getBottom – getTop

三、自定义View开发的步骤这里我们介绍最复杂的一种,自定义View。


3.1 构造函数无论是继承系统View还是直接继承View,都需要对构造函数进行重写,构造函数有多个,至少要重写其中一个才行。


public class CustomView extends View{ /** * 代码中New实例化时 调用该方法 */ public CustomView(Context context){ super(context); } /** * 在xml布局文件中使用时会自动调用该方法 */ public CustomView(Context context, AttributeSet attrs){ super(context, attrs); } ... //更多参数的构造函数}3.2 自定义属性Android系统的控件以android开头的都是系统自带的属性。


为了方便配置自定义View的属性,我们也可以自定义属性值。


Android自定义属性可分为以下几步:1、自定义一个View2、编写values/attrs.xml,在其中编写styleable和item等标签元素3、在布局文件中View使用自定义的属性(注意namespace)4、在View的构造方法中通过TypedArray获取attrs.xml文件示例如下:<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="test"> <attr name="text" format="string" /> <attr name="testAttr" format="integer" /> </declare-styleable></resources>代码实现示例如下:public class MyTextView extends View { private static final String TAG = MyTextView.class.getSimpleName(); //在View的构造方法中通过TypedArray获取 public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test); String text = ta.getString(R.styleable.test_testAttr); int textAttr = ta.getInteger(R.styleable.test_text, -1); Log.e(TAG, "text = " + text + " , textAttr = " + textAttr); ta.recycle(); }}布局文件使用示例如下:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res/com.example.test" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.test.MyTextView android:layout_width="100dp" android:layout_height="200dp" app:testAttr="520" app:text="helloworld" /></RelativeLayout>

四、Measure()MeasureSpecMeasureSpec是View的内部类,它封装了一个View的尺寸,在onMeasure()当中会根据这个MeasureSpec的值来确定View的宽高。


MeasureSpec的值保存在一个int值当中。


一个int值有32位,前两位表示模式mode后30位表示大小size。


即MeasureSpec = mode + size。


在MeasureSpec当中一共存在三种mode:UNSPECIFIED:无限制,View对尺寸没有任何限制,View设置为多大就应当为多大。


EXACTLY :精准模式,View需要一个精确值,这个值即为MeasureSpec当中的Size。


对应的是match_parent。


AT_MOST:最大模式,View的尺寸有一个最大值,View不可以超过MeasureSpec当中的Size值。


对应的是wrap_content。


常见的使用方式如下:// 获取测量模式(Mode)int specMode = MeasureSpec.getMode(measureSpec)// 获取测量大小(Size)int specSize = MeasureSpec.getSize(measureSpec)// 通过Mode 和 Size 生成新的SpecModeint measureSpec=MeasureSpec.makeMeasureSpec(size, mode);onMeasure整个测量过程的入口位于View的measure方法当中,该方法做了一些参数的初始化之后调用了onMeasure方法,这里我们主要分析onMeasure。


onMeasure源码如下:protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));}setMeasuredDimension(int measuredWidth, int measuredHeight) :该方法用来设置View的宽高,在我们自定义View时也会经常用到。


getDefaultSize(int size, int measureSpec):该方法用来获取View默认的宽高。


getSuggestedMinimumWidth():getHeight和该方法原理是一样的

五、Layout()layout()过程,对于View来说用来计算View的位置参数,对于ViewGroup来说,除了要测量自身位置,还需要测量子View的位置。


layout()方法是整个Layout()流程的入口,并在layout方法中调用了onLayout方法,主要是进行子View的计算。



六、Draw()draw流程也就是的View绘制到屏幕上的过程,整个流程的入口在View的draw()方法之中,而源码注释也写的很明白,整个过程可以分为6个步骤:绘制背景有过有必要,保存当前canvas绘制View的内容绘制子View根据需要,绘制边缘、阴影等效果绘制装饰,如滚动条等等

七、总结自定义View在Android的开发中的重要性还是很大的,因为仅仅靠系统提供的控件和组件,无论是美观度还是使用度,再或者是新特性上,都无法满足特定的业务场景。


因此,常常要用到自定义View,这就要求要在自己的项目自己完成特殊控件的自主开发。


自定义控件在开发过程中也属于重点和难点,应该多花时间进行学习和研究,重点有以下几个:控件属性的定义、设置和使用交互处理:事件交互和处理属于重中之重,常常要和事件分发结合在一起研究。


Canvas和Paint:在进行自定义View开发时,往往会通过画布自己使用画笔进行绘制,这就要求要对Paint、Path、Canvas要做着重的掌握。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/642695.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-17
下一篇 2022-04-17

发表评论

登录后才能评论

评论列表(0条)

保存