之前在做收音机的频率数字的时候,需要用到TextView的倒影效果,到网上找了一些帖子,发现效果是有的,但是或多或少有些问题。今天在一篇博文的基础上做一些小小的修改,有需要的朋友可以拿来用用。
下面贴上原帖的地址,尊重原创(http://www.cnblogs.com/shang53880/p/3549513.html)
当初我用这段代码的时候主要有两个问题,一个是报硬件加速相关的错。另一个错误是,如果我在动态设置TextView的文字时,倒影会遗留一些上个字符的部分倒影,总结起来就是倒影的错乱问题,但是我在直接执行尚弦月的源码时没有这个问题,原因未深究。而且原帖中自定义的TextView是根据时间来设置自动内容的,我把原来的父类扒掉,只留一个纯粹的TextView,在布局文件中引入后可以自定义其text。最后,还是感谢尚弦月前辈的成果。
下面贴代码:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
public class ReflectionTextView extends TextView {
private Matrix mMatrix;
private Paint mPaint;
public ReflectionTextView(Context context, AttributeSet attrs) {
super(context, attrs);
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);
setMeasuredDimension(getMeasuredWidth(),
(int) (getMeasuredHeight() * 1.67));
}
@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(100);
canvas.drawBitmap(reflectionImage, 0, 0, paint);
if (mPaint == null) {
mPaint = new Paint();
//阴影的效果可以自己根据需要设定
LinearGradient shader = new LinearGradient(0, height /2, 0,
height, 0x7fffffff, 0x0fffffff, TileMode.CLAMP);
mPaint.setShader(shader);
mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
}
canvas.drawRect(0, height / 2f, width, height, mPaint);
}
@Override
protected void onTextChanged(CharSequence text, int start,
int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
buildDrawingCache();
postInvalidate();
//每次更新TextView后遗留上次的残影,所以在这里每次刷新TextView后清楚DrawingCache
destroyDrawingCache();
}
}
布局文件中的调用:
<com.example.pcatzj.reflectiontextview.ReflectionTextView
android:id="@+id/rtv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/hello_world"
android:textSize="60sp"/>
这就是一个TextView,TextView的所有方法它都适用,而且并没有新的方法。
最后贴上一张效果图:
这里还有个小问题,就是TextView不应当让其超过一行显示,因为超过一行以后其阴影会有显示效果上的问题,可以自行调节,而且这种TextView一般都用作Logo形式,也不应该使其超过一行。
有问题欢迎留言雅正!