385841539 / marqueeview Goto Github PK
View Code? Open in Web Editor NEW自定义跑马灯MarqueeView,用TextView 出现了各种坑啊 , 尤其是在页面中同时存在EditText 的时候,简单的用法,完善的功能,希望您能喜欢!
自定义跑马灯MarqueeView,用TextView 出现了各种坑啊 , 尤其是在页面中同时存在EditText 的时候,简单的用法,完善的功能,希望您能喜欢!
Can we use bold text style like android:textStyle="bold"?
onDraw方法一直在打印日志,很影响查看其它日志,建议关闭。
😄
考虑一下用两个画笔,一个画笔开始滚动绘制的时候另个画笔的xLocation设置成控件宽度,并禁止绘制;当第一个画笔绘制到需要的位置,启动第二个画笔绘制,然后根据需要重置第一个画笔并停止绘制,以此循环。这个方法还没有验证。
如题
请指教
E/MarqueeView: onDraw: ---5802--------1165486.0------200
E/MarqueeView: onDraw: ---5802--------1165492.0------200
E/MarqueeView: onDraw: ---5802--------1165494.0------200
辛苦作者大大
如何实现那 ,大佬
有bug。在当前这个页面启动滚动后,然后跳转下一个页面。当关闭下一个页面时,OnDestroy将出现延迟调用的问题。
能增加修改字体的功能吗,Typeface
public class MarqueeView extends View {
private String string;//最终绘制的文本
private float speed = 1;//移动速度
private int textColor = Color.BLACK;//文字颜色,默认黑色
private float textSize = 12;//文字颜色,默认黑色
private float startLocationDistance = 0.5f;//开始的位置选取,百分比来的,距离左边,0~1,0代表不间距,1的话代表,从右面,1/2代表中间。
private int itemDistance = 4; //默认item间隔4个空格
private boolean hasShadow = false;
private float shadowDy = 0f;
private float shadowDx = 0f;
private float shadowRadius = 0f;
private int shadowColor = Color.BLACK;
private boolean isResetLocation = true;//默认为true
private float xLocation = 0;//文本的x坐标
private int contentWidth;//内容的宽度
private volatile boolean isRoll = false;//是否继续滚动
private TextPaint paint;//画笔
private Rect rect;
private boolean resetInit = true;
private String content = "";
private float textHeight;
private Handler mHandler = new Handler(new Handler.Callback() { //替换Thread,采用handler,推荐使用 WeakHandler,这里就不更换了
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1) {
if (isRoll && !TextUtils.isEmpty(content)) {
xLocation = xLocation - speed;
postInvalidate();//每隔10毫秒重绘视图
mHandler.sendEmptyMessageDelayed(1, 30);
}
return true;
}
return false;
}
});
public MarqueeView(Context context) {
this(context, null);
}
public MarqueeView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MarqueeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs);
initPaint();
}
@SuppressLint("RestrictedApi")
private void initAttrs(AttributeSet attrs) {
TintTypedArray tta = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
R.styleable.MarqueeView);
textColor = tta.getColor(R.styleable.MarqueeView_marqueeview_text_color, textColor);
isResetLocation = tta.getBoolean(R.styleable.MarqueeView_marqueeview_is_resetLocation, isResetLocation);
speed = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_speed, speed);
textSize = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_size, textSize);
startLocationDistance = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_startlocationdistance, startLocationDistance);
itemDistance = tta.getInt(R.styleable.MarqueeView_marqueeview_text_distance, itemDistance);
hasShadow = tta.getBoolean(R.styleable.MarqueeView_marqueeview_text_shadow, false);
shadowDx = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_shadow_dx, 0);
shadowDy = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_shadow_dy, 0);
shadowRadius = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_shadow_radius, 0);
shadowColor = tta.getColor(R.styleable.MarqueeView_marqueeview_text_shadow_color, shadowColor);
tta.recycle();
}
/**
* 刻字机修改
*/
private void initPaint() {
rect = new Rect();
paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);//初始化文本画笔
paint.setStyle(Paint.Style.FILL);
paint.setColor(textColor);//文字颜色值,可以不设定
paint.setTextSize(PixelUtil.sp2px(textSize));//文字大小
if (hasShadow) {
paint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (resetInit) {
if (startLocationDistance < 0) {
startLocationDistance = 0;
} else if (startLocationDistance > 1) {
startLocationDistance = 1;
}
xLocation = startLocationDistance;
resetInit = false;
}
if (isRoll) {
if (xLocation <= -(contentWidth + getBlankWidth() * itemDistance)) {
xLocation = xLocation + contentWidth + getBlankWidth() * itemDistance;
string = string + content;
//调用pattern.quote ,防止replaceFirst中含有特殊字符比如完整的(),导致的crash
string = string.replaceFirst(pattern.quote(""+content), ""); //修改内存问题,防止文字长度不断增加导致内存溢出的情况,
}
}
//把文字画出来
if (string != null) {
canvas.drawText(string, xLocation, getHeight() / 2 + textHeight / 2, paint);
}
}
/**
* 继续滚动
*/
public void continueRoll() {
postInvalidate();
mHandler.removeMessages(1);
isRoll = true;
mHandler.sendEmptyMessage(1);
}
/**
* 停止滚动
*/
public void stopRoll() {
isRoll = false;
resetInit = true;
mHandler.removeMessages(1);
postInvalidate();
}
public void setTextColor(int color) {
textColor = color;
paint.setColor(color);
postInvalidate();
}
private float getContentWidth(String black) {
if (TextUtils.isEmpty(black)) {
return 0;
}
if (rect == null) {
rect = new Rect();
}
paint.getTextBounds(black, 0, black.length(), rect);
textHeight = getContentHeight();
return rect.width();
}
/**
* http://blog.csdn.net/u014702653/article/details/51985821
* 详细解说了
*
* @param
* @return
*/
private float getContentHeight() {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
return Math.abs((fontMetrics.bottom - fontMetrics.top)) / 2;
}
/**
* 计算出一个空格的宽度
*/
private float getBlankWidth() {
String text1 = "en en";
String text2 = "enen";
return getContentWidth(text1) - getContentWidth(text2);
}
/**
* 添加文字
* @param content 显示文字的内容
* @param needRoll 是否需要滚动,如果不需要,就把文字定位到startLocationDistance的位置,而且不重复
*/
public void setContent(String content, boolean needRoll) {
if (TextUtils.isEmpty(content)) {
return;
}
isResetLocation = true;
resetInit = true;
if (needRoll) {
for (int i = 0; i < itemDistance; i++) {
content = content + " ";
}
this.content = content;
contentWidth = (int) (getContentWidth(content));//可以理解为一个单元内容的长度
int contentCount = (getWidth() / contentWidth) + 2;
this.string = "";
for (int i = 0; i <= contentCount + 2; i++) {
this.string = String.format("%s%s", this.string, this.content);//根据重复次数去叠加。
}
postInvalidate();
} else {
stopRoll();
resetInit = true;
getContentWidth(content);
this.content = content; //如果不需要滚动,就直接走这里了
this.string = content;
postInvalidate();
}
}
}
========================== attrs.xml================
<attr name="marqueeview_text_speed" format="float" /><!--播放速度 也就是文字滚动速度-->
<attr name="marqueeview_text_color" format="color|reference" /><!-- 文字颜色 -->
<attr name="marqueeview_text_size" format="float" /><!-- 文字大小 -->
<attr name="marqueeview_is_resetLocation" format="boolean" /><!--重新改变内容的时候 , 是否初始化 位置,默认为true,改变-->
<attr name="marqueeview_text_shadow" format="boolean" /> <!---是否设置阴影-->
<attr name="marqueeview_text_shadow_radius" format="float" /> <!---是否设置阴影-->
<attr name="marqueeview_text_shadow_dx" format="float" /> <!---是否设置阴影-->
<attr name="marqueeview_text_shadow_dy" format="float" /> <!---是否设置阴影-->
<attr name="marqueeview_text_shadow_color" format="color" /> <!---是否设置阴影-->
</declare-styleable>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.