package reco.frame.tv.view;
import reco.frame.tv.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetrics;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Message;
import android.renderscript.Int2;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
/**
* 跑马灯,专用于电视应用 无需焦点也能跑动
*
* @author reco
*
*/
public class TvMarqueeText extends TextView {
/** 是否停止滚动 */
private boolean mStopMarquee;
private String mText;
private float mCoordinateX;
private float mCoordinateY;
private float mTextWidth, mTextHeight;
/**
* 滚动周期
*/
private int period;
/**
* 边缘淡出
*/
private boolean vague;
/**
* 背景色 默认为透明色
*/
private int backgroundColor;
/**
* 字体
*/
private int textStyle;
public int getTextStyle() {
return textStyle;
}
public void setTextStyle(int textStyle) {
this.textStyle = textStyle;
}
private final static int STYLE_DEFAULT=0,STYLE_LTH=1;
private static Typeface type;
public int getPeriod() {
return period;
}
public void setPeriod(int period) {
this.period = period;
}
public boolean isVague() {
return vague;
}
public void setVague(boolean vague) {
this.vague = vague;
}
public void setText(String text) {
this.mText = text;
init();
}
public String getText(){
return mText;
}
public TvMarqueeText(Context context) {
this(context, null);
}
public TvMarqueeText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TvMarqueeText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray custom = getContext().obtainStyledAttributes(attrs,
R.styleable.TvMarqueeText);
this.mText = custom.getString(R.styleable.TvMarqueeText_text)+"";
this.period = custom.getInteger(R.styleable.TvMarqueeText_period, 30);
this.vague = custom.getBoolean(R.styleable.TvMarqueeText_vague, true);
this.textStyle=custom.getInt(R.styleable.TvMarqueeText_textStyle, STYLE_DEFAULT);
mCoordinateX = 3;
mCoordinateY = 15;
backgroundColor=Color.TRANSPARENT;
mTextWidth = getPaint().measureText(mText);
custom.recycle();
init();
}
private void init(){
mTextWidth = getPaint().measureText(mText);
if (textStyle==STYLE_LTH) {
changeStyle();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
if (changed) {
ColorDrawable colorDrawable=(ColorDrawable) getBackground();
if (colorDrawable!=null) {
backgroundColor=colorDrawable.getColor();
}
}
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
FontMetrics fontMetrics = getPaint().getFontMetrics();
mCoordinateY = getHeight()
- (getHeight() - (fontMetrics.bottom - fontMetrics.top)) / 2
- fontMetrics.bottom;
// 边缘淡出
if (vague) {
Shader shader = new LinearGradient(0, 0, getWidth(), 0, new int[] {
backgroundColor, getTextColors().getDefaultColor(),
getTextColors().getDefaultColor(), backgroundColor },
new float[] { 0, 0.15f, 0.85f, 1.0f },
Shader.TileMode.CLAMP);
getPaint().setShader(shader);
}
canvas.clipRect(new Rect(0, 0, getWidth(), getHeight()));
if (mText != null && !mText.equals(""))
canvas.drawText(mText, mCoordinateX, mCoordinateY, getPaint());
//Log.i(VIEW_LOG_TAG, mCoordinateX+"---"+mCoordinateY+"---"+mText.length()+"---"+getWidth()+"---"+getHeight());
}
private synchronized void changeStyle(){
if (type==null) {
try {
type=Typeface.createFromAsset(getContext().getAssets(), "fonts/lth.ttf");
} catch (RuntimeException e) {
e.printStackTrace();
}
}
if (type!=null) {
this.setTypeface(type);
}
}
/**
* 开启跑马灯
*/
public void startMarquee() {
mStopMarquee = false;
if (mText != null && !mText.equals(""))
mHandler.sendEmptyMessageDelayed(0, 300);
}
/**
* 停止跑马灯
*/
public void stopMarquee() {
mStopMarquee = true;
if (mHandler.hasMessages(0))
mHandler.removeMessages(0);
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
if (Math.abs(mCoordinateX) > (mTextWidth + 30)) {
mCoordinateX = getWidth() - 10;
invalidate();
if (!mStopMarquee) {
sendEmptyMessageDelayed(0, period);
}
} else {
mCoordinateX -= 1;
invalidate();
if (!mStopMarquee) {
sendEmptyMessageDelayed(0, period);
}
}
break;
}
super.handleMessage(msg);
}
};
}