TextView 有倒影效果

textView 有倒影效果

public class ReflectTextView extends TextView {

    private Matrix mMatrix;
    private Paint mPaint;

    private static int REFLECT_ALPHA;// 倒影透明度
    private static float REFLECT_HEIGHT_MULTIPLE;// 倒影的高度倍数
    private static int SPACING_VALUE;// 实体文字与倒影之间的空隙
    private static float OFF_Y;// Y轴偏移,由于倒影的高度倍数设置小于1时就会出现偏移,显示部分倒影

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

    }

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

        REFLECT_ALPHA = 100;
        REFLECT_HEIGHT_MULTIPLE = 0.5f;
        SPACING_VALUE = 0;

       TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.reflect, defStyleAttr, 0);

        int n = a.getIndexCount();
        for (int i = 0; i < n; i++)
        {
            int attr = a.getIndex(i);

            if (attr == R.styleable.reflect_reflectAlpha)
            {
                // 倒影透明度[1-255]
                REFLECT_ALPHA = a.getInteger(attr, 100);// 默认100
                if (REFLECT_ALPHA < 1)
                    REFLECT_ALPHA = 1;
                else if (REFLECT_ALPHA > 255)
                    REFLECT_ALPHA = 255;
            }
            else if (attr == R.styleable.reflect_reflectHeightMultiple)
            {
                // 倒影的高度倍数[0-1]
                REFLECT_HEIGHT_MULTIPLE = a.getFloat(attr, 1f);// 默认1
                if (REFLECT_HEIGHT_MULTIPLE < 0)
                    REFLECT_HEIGHT_MULTIPLE = 0;
                else if (REFLECT_HEIGHT_MULTIPLE > 1)
                    REFLECT_HEIGHT_MULTIPLE = 1;
            }
            else if (attr == R.styleable.reflect_spacingValue)
            {
                // 实体文字与倒影之间的空隙 默认10dp
                SPACING_VALUE = a.getDimensionPixelSize(attr, (int) TypedValue
                        .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0,
                                getResources().getDisplayMetrics()));
            }
        }
        a.recycle();

        init();
    }

    private void init()
    {

        mMatrix = new Matrix();
        mMatrix.preScale(1, -1);
        // 这句是关闭硬件加速,启用软件加速,如果报相关错误可以尝试注释这句代码
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

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

        int temp = (int) (getMeasuredHeight() - (getLineHeight() - getTextSize()) / 2);
        OFF_Y = temp - temp * REFLECT_HEIGHT_MULTIPLE;
        setMeasuredDimension(getMeasuredWidth(), Math.round(temp * 2 - OFF_Y)
                + SPACING_VALUE);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        int height = getMeasuredHeight();
        int width = getMeasuredWidth();
        setDrawingCacheEnabled(true);
        Bitmap originalImage = getDrawingCache();
        Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, 0,
                Math.min(width, originalImage.getWidth()), height, mMatrix,
                false);
        Paint paint = new Paint();
        paint.setAlpha(REFLECT_ALPHA);
        canvas.drawBitmap(reflectionImage, 0, OFF_Y, paint);
        if (mPaint == null)
        {
            mPaint = new Paint();
            // 阴影的效果可以自己根据需要设定
            if(height >100){
                Log.i("ReflectTextView","height = "+height);
                height =150;
            }
            LinearGradient shader = new LinearGradient(0, (height + OFF_Y) / 2,
                    0, height, 0xffffffff, 0x00ffffff, Shader.TileMode.CLAMP);
            mPaint.setShader(shader);
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        }
        canvas.drawRect(0, (height + OFF_Y) / 2, width, height, mPaint);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start,
                                 int lengthBefore, int lengthAfter)
    {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        try{
            buildDrawingCache();
            postInvalidate();
            // 每次更新TextView后遗留上次的残影,所以在这里每次刷新TextView后清楚DrawingCache
            destroyDrawingCache();
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FW_G8Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值