自定义控件之对现有控件拓展(一)

来源:互联网 发布:淘宝助理模板数据包 编辑:程序博客网 时间:2024/06/10 01:55

原文:http://blog.csdn.net/guiman/article/details/51163245


Android自定义控件对我来说,一直以来感觉很难,不敢去碰,虽然官方提供了很多的UI控件,但有时候看见其他应用做出来的控件相当的漂亮,心里痒痒的,期望自己也能做出类似牛叉的控件,再加上想进入中级程序猿自定义View是必备的本领,好吧,为了前途,狠狠心,陷进去吧。

android自定义控件分为两类,一类是继承View,一类是继承ViewGroup。由于直接继承ViewGroup是在子View的基础上进行测量和定位的,所以咱这种菜鸟一开始还是从最简单的入手。自定义View大体上可以分类三类:

  • 在现有控件的基础上进行拓展,可以修改UI显示及功能添加。
  • 创建组合控件,实现功能的服用
  • 直接继承View实现全新的控件,可以定义UI显示及功能实现

今天就先从最简单的自定义View之对现有控件进行拓展开始,实现一个自定义按钮控件。首先我们先定义一个类,并且继承Buttom类,还有重写他们的构造方法。代码如下:

<pre name="code" class="java">public class CustomViewExtendsButton extends Button{    public CustomViewExtendsButton(Context context) {        this(context,null);    }    public CustomViewExtendsButton(Context context, AttributeSet attrs) {        this(context, attrs,0);    public CustomViewExtendsButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }}


同时,我们还需要两个不同的画笔,用来画出我们定义的View形状,因此,我们在代码中加上两个画笔,并在构造方法中给它们进行初始化一些属性,比如画笔颜色,大小,消除锯齿等,看需要而定:

<pre name="code" class="java">private TextPaint mButtonPaint;private TextPaint mTextPaint;private void initPaint() {    mButtonPaint = new TextPaint();    mButtonPaint.setColor(Color.BLUE);    mButtonPaint.setAntiAlias(true);    mTextPaint = new TextPaint();    mTextPaint.setColor(Color.RED);    mTextPaint.setAntiAlias(true);}


ok,进行到这一步我们的初始工作已完成,接下来就是重点的部分了。在android中,所有呈现出来的UI控件,都是被系统画出来的,而这个画的过程就是在View类中的onDraw()方法中实现的,所以我们想让系统按照我们的设计来完成UI显示,我们必须重新onDraw()方法,来告诉系统怎么取绘制。由此,我们先来继承父类的onDraw()方法。并在该方法中利用画笔分别画出一个矩形和一行文字,并且让文字居中于矩形中间,代码如下所示:

<pre name="code" class="java">@Overrideprotected void onDraw(Canvas canvas) {    int width = getMeasuredWidth();    int height = getMeasuredHeight();    //drawRect 方法中5个参数,分别代表的是left,top,right,bottom边距及画笔    Rect mRect = new Rect(0,0,width / 2,height / 4);    canvas.drawRect(mRect,mButtonPaint);    //FontMetrics里是字体图样的信息,有float型和int型的版本,都可以从Paint中获取    Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();    int baseLine = (mRect.bottom + mRect.top - fontMetricsInt.bottom - fontMetricsInt.top) / 2;    mTextPaint.setTextAlign(Paint.Align.CENTER);    mTextPaint.setTextSize(20);    //drawText 方法中4个参数,分别代表的是文本,left,bottom距及画笔    canvas.drawText("按钮",mRect.centerX(),baseLine,mTextPaint);}


好了,我们把自定义View添加到布局文件中:

<pre name="code" class="java"><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.sanhuimusic.mycustomview.MainActivity">    <com.sanhuimusic.mycustomview.view.CustomViewExtendsButton        android:layout_width="match_parent"        android:layout_height="match_parent"        /></LinearLayout>


并在MainActivity中把布局加载出来:

<pre name="code" class="java">public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}


ok,来到这里我们第一个最简单的自定义View已完成了,当然它还没有任何得功能实现,来先让我们跑下,看看成果吧。

这里写图片描述

好了,我们定义出来的控件已显示出来了。很简单吧,但是有没有注意到,我们在布局文件中使用的是android:layout_width=”match_parent” 和 android:layout_height=”match_parent”这两个属性值呢?那现在我们尝试着改下 android:layout_width=”wrap_content” 和 android:layout_height=”wrap_content”,运行下,结果是不是你想要的呢?当然不是,这是因为,在继承Button中,系统是不对wrap_content处理的。针对这种情况,处理方法是,

  • 直接设置固定大小 如:android:layout_width=”300dp”和android:layout_height=”200dp”

另外使用自定义控件一方面是为了修改UI的显示,另一方面是为了实现特有的功能。这里就不在写多述。

0 0
原创粉丝点击