以Android Calculator源码为例,自定义一个ColorButton,这个ColorButton具有自定义的UI和事件响应能力:

/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.calculator2;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.widget.Button;import android.view.View.OnClickListener;import android.view.View;import android.view.MotionEvent;import android.content.res.Resources;/** * Button with click-animation effect. */class ColorButton extends Button implements OnClickListener {    int CLICK_FEEDBACK_COLOR;    static final int CLICK_FEEDBACK_INTERVAL = 10;    static final int CLICK_FEEDBACK_DURATION = 350;    float mTextX;    float mTextY;    long mAnimStart;    OnClickListener mListener;    Paint mFeedbackPaint;    public ColorButton(Context context, AttributeSet attrs) {        super(context, attrs);        Calculator calc = (Calculator) context;        init(calc);        mListener = calc.mListener;        setOnClickListener(this);    }    public void onClick(View view) {        mListener.onClick(this);    }    private void init(Calculator calc) {        Resources res = getResources();        CLICK_FEEDBACK_COLOR = res.getColor(R.color.magic_flame);        mFeedbackPaint = new Paint();        mFeedbackPaint.setStyle(Style.STROKE);        mFeedbackPaint.setStrokeWidth(2);        getPaint().setColor(res.getColor(R.color.button_text));        mAnimStart = -1;    }    @Override    public void onSizeChanged(int w, int h, int oldW, int oldH) {        measureText();    }    private void measureText() {        Paint paint = getPaint();        mTextX = (getWidth() - paint.measureText(getText().toString())) / 2;        mTextY = (getHeight() - paint.ascent() - paint.descent()) / 2;    }    @Override    protected void onTextChanged(CharSequence text, int start, int before, int after) {        measureText();    }    private void drawMagicFlame(int duration, Canvas canvas) {        int alpha = 255 - 255 * duration / CLICK_FEEDBACK_DURATION;        int color = CLICK_FEEDBACK_COLOR | (alpha << 24);        mFeedbackPaint.setColor(color);        canvas.drawRect(1, 1, getWidth() - 1, getHeight() - 1, mFeedbackPaint);    }    @Override    public void onDraw(Canvas canvas) {        if (mAnimStart != -1) {            int animDuration = (int) (System.currentTimeMillis() - mAnimStart);            if (animDuration >= CLICK_FEEDBACK_DURATION) {                mAnimStart = -1;            } else {                drawMagicFlame(animDuration, canvas);                postInvalidateDelayed(CLICK_FEEDBACK_INTERVAL);            }        } else if (isPressed()) {            drawMagicFlame(0, canvas);        }        CharSequence text = getText();        canvas.drawText(text, 0, text.length(), mTextX, mTextY, getPaint());    }    public void animateClickFeedback() {        mAnimStart = System.currentTimeMillis();        invalidate();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        boolean result = super.onTouchEvent(event);        switch (event.getAction()) {            case MotionEvent.ACTION_UP:                animateClickFeedback();                break;            case MotionEvent.ACTION_DOWN:            case MotionEvent.ACTION_CANCEL:                invalidate();                break;        }        return result;    }}

在main.xml中引用该自定义控件(
com.android.calculator2.ColorButton ):

<?xml version="1.0" encoding="utf-8"?><!--/* * Copyright (C) 2008, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  * *     http://www.apache.org/licenses/LICENSE-2.0  * * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. */--><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:background="#ff000000">    <LinearLayout         android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="2"         >        <com.android.calculator2.CalculatorDisplay             android:id="@+id/display"             android:layout_width="0dp"             android:layout_weight="5"             android:layout_height="match_parent"             maxDigits="@integer/max_digits">            <com.android.calculator2.CalculatorEditText                style="@style/display_style" />            <com.android.calculator2.CalculatorEditText                style="@style/display_style" />        </com.android.calculator2.CalculatorDisplay>        <ImageButton android:id="@+id/overflow_menu"            android:layout_width="48dip"            android:layout_height="match_parent"            android:src="@drawable/ic_menu_overflow"            android:background="@android:color/transparent"            android:layout_marginLeft="8dip"            android:visibility="gone"/>        <FrameLayout            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="match_parent">            <!-- marginRight has to be 0 to catch border-touch -->            <<com.android.calculator2.ColorButton                 android:id="@+id/clear"                 android:text="@string/clear"                 android:layout_width="match_parent"                 android:layout_height="match_parent"                 android:layout_marginRight="0dp"                 android:textSize="15dp"                 style="@style/button_style"                 />            <!-- marginRight has to be 0 to catch border-touch -->            <com.android.calculator2.ColorButton                 android:id="@+id/del"                 android:text="@string/del"                 android:layout_width="match_parent"                 android:layout_height="match_parent"                 android:layout_marginRight="0dp"                 android:textSize="15dp"                 style="@style/button_style"                 />        </FrameLayout>    </LinearLayout>    <android.support.v4.view.ViewPager         android:id="@+id/panelswitch"         android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="4"         /></LinearLayout>


通过自定义控件,能够很方便的实现较复杂的控件设计和复用。


官方教程:http://developer.android.com/guide/topics/ui/custom-components.html



更多相关文章

  1. Android(安卓)之 自定义控件用法介绍
  2. Android设置theme中的坑
  3. 【Android】下载Android源码的简明步骤
  4. Android中Fragment中启动一个Activity,实例化控件。
  5. 如何设置一个activity透明
  6. android UI设计器-droiddraw
  7. android源码下载与编译过程记录
  8. Ubuntu 12.04(64位)下载并编译 Android(安卓)4.1 源码[只有2条命令
  9. 【Android】自定义Dialog如何设置点击事件

随机推荐

  1. win10 64位 MySQL8.0下载和安装教程图解
  2. Mysql大型SQL文件快速恢复方案分享
  3. Mysql在线回收undo表空间实战记录
  4. MySQL关于ERROR 1290 (HY000)报错解决方
  5. MySQL使用Replace操作时造成数据丢失的问
  6. MySQL 数据库铁律(小结)
  7. MySQL版本低了不支持两个时间戳类型的值
  8. MySQL如何生成唯一的server-id
  9. MySQL主从同步中的server-id示例详解
  10. 如何在Windows中运行多个MySQL实例详解