1.attrs属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">EX_templete</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <declare-styleable name="SmoothButton">
        <attr name="transitionDrawable" format="reference" />
        <attr name="transitionDrawableLength" format="integer" />
        <attr name="transitionTextColorUp" format="color" />
        <attr name="transitionTextColorDown" format="color" />
    </declare-styleable>
</resources>


2.layout设置:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:misc="http://schemas.android.com/apk/res/com.example.ex_templete"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <com.example.ex_templete.SmoothButton
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/red_button"
        android:text="smooth button 1"
        misc:transitionDrawable="@drawable/red_transition_list"
        misc:transitionDrawableLength="8"
        misc:transitionTextColorDown="#aaa"
        misc:transitionTextColorUp="#eee" />
</RelativeLayout>


3.自定义控件SmoothButton类:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LevelListDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.Button;
public class SmoothButton extends Button
{
                     
    private static final long DELAY = 25;
                     
    private int transitionDrawableLength;
    private int level;
                     
    private int[] colors;
                     
    private boolean wasPressed;
                     
    private Drawable background;
                     
    public SmoothButton(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SmoothButton);
        LevelListDrawable transitionDrawable = (LevelListDrawable) a.getDrawable(R.styleable.SmoothButton_transitionDrawable);
                         
        transitionDrawableLength = a.getInt(R.styleable.SmoothButton_transitionDrawableLength, 0);
        int useTextColors = 0;
        int c0 = 0;
        if (a.hasValue(R.styleable.SmoothButton_transitionTextColorUp))
        {
            c0 = a.getColor(R.styleable.SmoothButton_transitionTextColorUp, 0);
            useTextColors++;
        }
        int c1 = 0;
        if (useTextColors == 1 && a.hasValue(R.styleable.SmoothButton_transitionTextColorDown))
        {
            c1 = a.getColor(R.styleable.SmoothButton_transitionTextColorDown, 0);
            useTextColors++;
        }
        a.recycle();
                         
        if (transitionDrawable == null)
        {
            throw new RuntimeException("transitionDrawable must be defined in XML (with valid xmlns)");
        }
        if (transitionDrawableLength == 0)
        {
            throw new RuntimeException("transitionDrawableLength must be defined in XML (with valid xmlns)");
        }
        if (useTextColors == 2)
        {
            setTextColor(c0);
            int a0 = Color.alpha(c0);
            int r0 = Color.red(c0);
            int g0 = Color.green(c0);
            int b0 = Color.blue(c0);
            int a1 = Color.alpha(c1);
            int r1 = Color.red(c1);
            int g1 = Color.green(c1);
            int b1 = Color.blue(c1);
            colors = new int[transitionDrawableLength];
            for (int i = 0; i < transitionDrawableLength; i++)
            {
                int ai = a0 + i * (a1 - a0) / transitionDrawableLength;
                int ri = r0 + i * (r1 - r0) / transitionDrawableLength;
                int gi = g0 + i * (g1 - g0) / transitionDrawableLength;
                int bi = b0 + i * (b1 - b0) / transitionDrawableLength;
                colors[i] = Color.argb(ai, ri, gi, bi);
            }
        }
                         
        int[] viewAttrs =
        { android.R.attr.background };
        a = context.obtainStyledAttributes(attrs, viewAttrs);
        boolean has a.hasValue(0);
         a.recycle();
        if (!hasBackground)
        {
            int l = getPaddingLeft();
            int t = getPaddingTop();
            int r = getPaddingRight();
            int b = getPaddingBottom();
            setBackgroundDrawable(transitionDrawable);
            setPadding(l, t, r, b);
        }
                         
        background = getBackground();
        level = 0;
        background.setLevel(level);//通过此方法设置一组图片为背景**************************************
    }
                     
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        boolean rc = super.onKeyDown(keyCode, event);
        if ((keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) && event.getRepeatCount() == 0
                && level + 1 < transitionDrawableLength)
        {
            handler.removeMessages(-1);
            handler.sendEmptyMessageDelayed(1, DELAY);
        }
        return rc;
    }
                     
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event)
    {
        boolean rc = super.onKeyUp(keyCode, event);
        if ((keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) && event.getRepeatCount() == 0 && level > 0)
        {
            handler.removeMessages(1);
            handler.sendEmptyMessageDelayed(-1, DELAY);
        }
        return rc;
    }
                     
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        wasPressed = isPressed();
        boolean rc = super.onTouchEvent(event);
        post(checkPressed);
        return rc;
    }
                     
    Runnable checkPressed = new Runnable()
    {
        public void run()
        {
            if (!wasPressed && isPressed())
            {
                if (level + 1 < transitionDrawableLength)
                {
                    handler.removeMessages(-1);
                    handler.sendEmptyMessageDelayed(1, DELAY);
                }
            }
            else if (wasPressed && !isPressed())
            {
                if (level > 0)
                {
                    handler.removeMessages(1);
                    handler.sendEmptyMessageDelayed(-1, DELAY);
                }
            }
        }
    };
                     
    private Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            int what = msg.what;
            level += what;
            if (level >= 0 && level < transitionDrawableLength)
            {
                background.setLevel(level);
                if (colors != null)
                {
                    setTextColor(colors[level]);
                }
                sendEmptyMessageDelayed(what, DELAY);
            }
            else
            {
                level = Math.max(0, level);
                level = Math.min(transitionDrawableLength - 1, level);
            }
        }
    };
}



4.MainActivity

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}