Android自定义view之基础知识

Android自定义view之基础知识

虽然Android已经自带了很多实用的view和layout,加以调教能实现很美观的界面,但是有一些情况下,需要实现特殊的界面效果,比如我们比较熟悉的各种播放器的滑动条环节音量的界面,不同的音量对应不同的格数,但是不必要为每个格都单独开辟一个ImageView,如果只使用一个ImageView,那么又需要准备很多的图片,这样显然是不划算的,这个时候就需要自己去实现一个自定义view。再比如侧滑菜单,之前的android并没有自带侧滑菜单(现在已经有了,是DrawerLayout),但各大应用已经有了侧滑菜单,显然都是自定义的。

1. 自定义view的分类

自定义view实际上就是继承特定的view或者layout,甚至干脆直接继承基类View或者ViewGroup,重写其中的一些方法来实现特定的效果。
自定义view从继承的类来说有以下四种分类。

  • 继承特定的view,重写其中的一些方法。
    通常是需求本身不复杂,往往一些现成的View稍加改动就可以实现。比如很简单的自动滚动的TextView,要设置text为跑马灯效果的循环滚动,在layout文件中要设置如下关键属性。
<TextView
    ...
    android:maxLine=1
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"/>

设置最大行数为1行,否则TextView会自动折行。然后设置当文字过长时文字的缩略方式,有缩略中间、末尾、无以及跑马灯效果,如果不设置则默认缩略末尾,也就是文字过长时会将多出的文字以...代替。最后设置跑马灯的循环次数为无限循环。但是这样还是不够的,因为TextView在获取到焦点的时候才会触发跑马灯效果,没有焦点的时候不会滚动。TextView中有个boolean isFocused()方法,来判断当前TextView是否获取了焦点,我们只要继承TextView并且让这个方法一直返回true就行了。

package com.example.zu.myapp.layout;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
public class AutoScrollTextView extends TextView
{
    public AutoScrollTextView(Context context) {
        super(context);
    }

    public AutoScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean isFocused() {
        return true;
    }
}

这样一来,在需要滚动的地方使用这个自定义的TextView来代替TextView即可。
这种方法通常是最省力的,因为只是修改了某些地方,至于View本身怎么布局怎么呈现,仍然没有改变。

  • 继承特定的Layout
    就像开头提到的侧滑菜单,显然无论LinearLayout还是RelativeLayout都无法满足要求,而需求本身更像是一种特殊布局,因此我们会选择继承一个Layout并重写一些方法。而Layout根据特点的不同,一般选择继承的会是RelativeLayout或者FrameLayout。

  • 直接继承View
    这种情况实际上用得比较少,毕竟View是所有视图空间的基类,只包含一些必要的方法。但是在处理一些相对比较简单的视图效果的时候,比如文字、特殊的图片显示效果,就可以选择直接继承View来实现,这样反而更能减少干扰。不过一些细枝末节的工作需要自己手动处理,你比如padding属性。

  • 直接继承ViewGroup
    ViewGroup是所楼Layout的基类,而View是它的基类。ViewGroup和View的主要区别就在于measure、layout和draw的不同,ViewGroup增加了对子View的布局考虑。和直接继承View的目的一样,如果不想特定的Layout的自身特点所带来的干扰,并且要实现的效果也不是很复杂,则可以直接继承ViewGroup。当然,像padding和wrap_content等这些工作就需要自己来处理。

以上是从继承的类来说,如果从目的和重写的重点方法来看,则可分为两类。
- 实现特殊的视图效果
这种最典型的就是需要实现一个有特殊显示效果的View,举例来说,小米的时钟界面的仪表盘,做得很精美。显然它是一个独立的控件,而不是Layout。这种情况更多的侧重点在绘制,也就是onDraw方法。这也是对应着上面所说的继承View。
- 实现特殊的布局效果
现在制作比较精美的应用随着点击、滑动等各种操作,界面会有各种非常漂亮的变化效果,这往往都是通过自定义layout实现的,通过控制子View的测量(measure)和布局(layout),来达到特殊的排版效果,最简单的例子就是侧滑菜单,,它通过控制菜单和主页的位置来达到侧滑的效果。这也对应着上面说的继承ViewGroup。

以上基本就概括了常用的自定义View的分类,而上面提到的一些自定义view的例子会在后面的实战环节中一一展示。

2. 自定义View的两条知识线

一个view它主要的作用有两个,一是显示内容,二是响应(操作)事件,自定义view也是如此。通常,如果功能不是太简单或者太复杂的话,基本都会涉及到这两方面,这就使得想要自定义view必须学会两方面知识,一个是view的显示流程,另外一个就是view的事件分发机制。

一个view显示出来,需要经过measure、layout和draw的过程,meausre负责确定view的大小;layout负责确定view本身以及子view的位置;draw则负责将view绘制出来。最后才是我们所看到的view。

而事件分发机制其实更多的是ViewGroup中的内容,毕竟ViewGroup中有子view,才需要分发事件。

由于这两方面的内容都比较繁杂(毕竟和视图扯上关系的工作量都比较大),因此会在后面的文章中分别详细讨论这两条线上的内容。

声明:本系列文章部分知识点来自于《Android开发艺术探索》,在此对作者表示感谢。部分内容可能会有错误和遗漏,欢迎大家留言讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值