1. 程式人生 > >android 自定義TextView 流光字,彩色text

android 自定義TextView 流光字,彩色text

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:inks="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    tools:context="com.inks.mytest.MainActivity">

    <!--<com.inks.mytest.MyView-->
        <!--android:layout_width="300dp"-->
        <!--android:layout_height="300dp"-->
    <!--&gt;-->
    <!--</com.inks.mytest.MyView>-->

    <com.inks.mytest.MyText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        inks:text="這是一個text"
        app:startColor="#ffff0000"
        app:midColor="#ff00ff00"
        app:endColor="#ff0000ff"
        android:layout_margin="80dp"
        app:textSize="55dp"/>

    <com.inks.mytest.MyText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        inks:text="這是一個text"
        app:startColor="#ff555555"
        app:midColor="#ff777777"
        app:endColor="#ffcccccc"
        android:layout_margin="80dp"
        app:textSize="25dp"/>
    <com.inks.mytest.MyText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        inks:text="這是一個text"
        app:startColor="#ffff0000"
        app:midColor="#ff880000"
        app:endColor="#ffff5533"
        android:layout_margin="80dp"

        app:textSize="60dp"/>
    <com.inks.mytest.MyText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        inks:text="這是一個text"
        app:startColor="#ffff0000"
        app:midColor="#ff00ff00"
        app:endColor="#ff0000ff"
        android:layout_margin="80dp"

        app:textSize="15dp"/>

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name = "MyText">
        <attr name = "textSize" format = "dimension" />
        <attr name = "startColor" format = "color" />
        <attr name = "midColor" format = "color" />
        <attr name = "endColor" format = "color" />
        <attr name = "text" format = "string" />
    </declare-styleable>

</resources>
package com.inks.mytest;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

/**
 * Created by inks on 2018/9/21 0021.
 */

public class MyText extends View {
    private LinearGradient mGradient;//漸變色
    private Paint mPaint;//文字的畫筆
    private int[] mGradientColors;
    private Matrix mMatrix;
    private int mGradientIndex;
    private static final int STEP_LENGTH = 10;//速度


    private int width,height ;
    private String textString = " ";
    private  float textSize;
    private int startColor,midColor,endColor;


    public MyText(Context context) {
        this(context, null);
    }

    public MyText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyText(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public MyText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MyText);
        textSize =typedArray.getDimension(R.styleable.MyText_textSize,22);
        startColor =  typedArray.getColor(R.styleable.MyText_startColor,Color.argb(255, 120, 120, 120));
        midColor =  typedArray.getColor(R.styleable.MyText_midColor,  Color.argb(255, 120, 120, 120));
        endColor = typedArray.getColor(R.styleable.MyText_endColor, Color.argb(255, 255, 255, 255));

        textString= typedArray.getString(R.styleable.MyText_text);
        typedArray.recycle();

        mPaint = new Paint();
        mPaint.setTextSize(textSize);
        Rect rect = new Rect();
        mPaint.getTextBounds(textString,0,textString.length(), rect);
        width = rect.width();
        height = rect.height();
        mMatrix = new Matrix();
        mGradientColors = new int[]{startColor,midColor
              ,endColor };
        mGradient = new LinearGradient(0, 0, width, 0, mGradientColors,
                new float[]{0, 0.7f, 1}, Shader.TileMode.MIRROR);

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        mHandler.removeMessages(1);
        mHandler.sendEmptyMessageDelayed(1, 500);

        setMeasuredDimension(width, height);



    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setShader(mGradient);
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float top = fontMetrics.top;//為基線到字型上邊框的距離
        float bottom = fontMetrics.bottom;//為基線到字型下邊框的距離
        int baseLineY = (int) (height / 2 - top / 2 - bottom / 2);//基線中間點的y軸計算公式
        canvas.drawText(textString, 0, baseLineY, mPaint);

    }


    private Handler mHandler = new Handler() {

        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    if (mMatrix == null) {
                        mMatrix = new Matrix();

                    }
                    mMatrix.setTranslate(mGradientIndex, 0);

                    if (mGradient == null) {
                        mGradientColors = new int[]{startColor,midColor
                                ,endColor };

                        mGradient = new LinearGradient(0, 0, width, 0, mGradientColors,
                                new float[]{0, 0.7f, 1}, Shader.TileMode.MIRROR);
                    }

                    mGradient.setLocalMatrix(mMatrix);
                    invalidate();
                    mGradientIndex += STEP_LENGTH;
                    if (mGradientIndex >= Integer.MAX_VALUE) {
                        mGradientIndex = 0;
                    }
                    mHandler.sendEmptyMessageDelayed(1, 50);
                    break;
            }
        }
    };


    //getReflectedBitmap
    private Bitmap getReflectedBitmap( Bitmap mBitmap) {

        int width = mBitmap.getWidth();
        int height = mBitmap.getHeight();

        Matrix matrix = new Matrix();
        // 圖片縮放,x軸變為原來的1倍,y軸為-1倍,實現圖片的反轉
        matrix.preScale(1, -1);

        //建立反轉後的圖片Bitmap物件,圖片高是原圖的一半。
        //Bitmap mInverseBitmap = Bitmap.createBitmap(mBitmap, 0, height/2, width, height/2, matrix, false);
        //建立標準的Bitmap物件,寬和原圖一致,高是原圖的1.5倍。
        //注意兩種createBitmap的不同
        //Bitmap mReflectedBitmap = Bitmap.createBitmap(width, height*3/2, Config.ARGB_8888);

        Bitmap mInverseBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height, matrix, false);
        Bitmap mReflectedBitmap = Bitmap.createBitmap(width, height*2, Bitmap.Config.ARGB_8888);

        // 把新建的點陣圖作為畫板
        Canvas mCanvas = new Canvas(mReflectedBitmap);
        //繪製圖片
        mCanvas.drawBitmap(mBitmap, 0, 0, null);
        mCanvas.drawBitmap(mInverseBitmap, 0, height, null);

        //新增倒影的漸變效果
        Paint mPaint = new Paint();
        Shader mShader = new LinearGradient(0, height, 0, mReflectedBitmap.getHeight(), 0x70ffffff, 0x00ffffff, Shader.TileMode.MIRROR);
        mPaint.setShader(mShader);
        //設定疊加模式
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //繪製遮罩效果
        mCanvas.drawRect(0, height, width, mReflectedBitmap.getHeight(), mPaint);

        return mReflectedBitmap;
    }

}