自定义列表数据数据跑马灯
创始人
2025-05-29 22:06:16

最近项目中用到了 横向跑马灯 顺序显示list 中的数据,并且增加每个的点击事件

ViewFlipper 虽然能很好的实现跑马灯功能,但是如果只显示一行,设置 singleLine = true时,只要内容过长,就会显示不全,所有最后在我以前写的基础上做了部分修改。

废话不多说,上代码:

public class MuchMarqueeView extends AppCompatTextView {

private float textLength = 0f;// 文本长度

private float viewWidth = 0f;

private float step = 0f;// 文字的横坐标

private float y = 0f;// 文字的纵坐标

private float temp_view_plus_text_length = 0.0f;// 用于计算的临时变量 ,第一条数据要划出屏幕的长度

private float temp_view_plus_two_text_length = 0.0f;// 用于计算的临时变量,第二跳数据开始滑动进入屏幕的长度

public boolean isStarting = false;// 是否开始滚动

private Paint paint = null;// 绘图样式

private String text = "";// 文本内容

private float currentScrollX;// 当前滚动的位置

private float lastIndex = 0f;//上一次滚动的位置

private List informationList = new ArrayList<>();

private int marqueeIndex = 0;

private WindowManager windowManager;

private OnMarqueeItemListener marqueeItemListener;

//由第一个item 切换到第二个item 的时间,

private long switchSecondTime = 0;

public void setWindowManager(WindowManager windowManager) {

this.windowManager = windowManager;

}

//更新list后,从第1条重新开始

public void setStrings(List strings) {

this.informationList = strings;

marqueeIndex = 0;

}

public void setMarqueeItemListener(OnMarqueeItemListener marqueeItemListener) {

this.marqueeItemListener = marqueeItemListener;

}

public MuchMarqueeView(Context context) {

this(context, null);

}

public MuchMarqueeView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public MuchMarqueeView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

setOnClickListener(v -> {

if (marqueeItemListener != null) {

marqueeItemListener.onItemListener(marqueeIndex);

}

});

}

/**

* 开始滚动

*/

public void startScroll() {

if (!isStarting) {

try {

isStarting = true;

setViewText();

invalidate();

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

* 停止滚动

*/

public void stopScroll() {

if (isStarting) {

try {

isStarting = false;

invalidate();

} catch (Exception e) {

e.printStackTrace();

}

}

}

private void setViewText() {

if (marqueeIndex == informationList.size()) {

marqueeIndex = 0;

}

setTextContent(informationList.get(marqueeIndex).informationTitle);

}

public void setTextContent(String text) {

setText(text);

init();

}

/**

* 文本初始化,每次更改文本内容或者文本效果等之后都需要重新初始化一下

*/

public void init() {

try {

paint = getPaint();

paint.setColor(Color.parseColor("#424242"));

paint.setTextSize(UIUtils.dip2px(getContext(), 16));

text = getText().toString();

textLength = paint.measureText(text);

viewWidth = getWidth();

if (viewWidth == 0) {

if (windowManager != null) {

Display display = windowManager.getDefaultDisplay();

viewWidth = display.getWidth();

}

}

if (marqueeIndex == 0) {

step = textLength;

temp_view_plus_text_length = textLength;

temp_view_plus_two_text_length = textLength * 2;

} else {

step = textLength;

temp_view_plus_text_length = viewWidth + textLength;

temp_view_plus_two_text_length = viewWidth + textLength * 2;

}

y = getTextSize() + getPaddingTop();

} catch (Exception e) {

e.printStackTrace();

}

}

@Override

public void onDraw(Canvas canvas) {

try {

lastIndex = currentScrollX;

canvas.drawText(text, temp_view_plus_text_length - step, y, paint);

currentScrollX = temp_view_plus_text_length - step;

//重点,通过滚动的坐标,来判断一条数据是否完全消失,

//由于第一条数据是据靠左显示并移动的,所以当第一条切换到第二条数据时,

// lastIndex < 0 和 currentScrollX >= 0 本身就成立,所以增加一个时间判断

if (lastIndex < 0 && currentScrollX >= 0 && System.currentTimeMillis() - switchSecondTime > 200) {

marqueeIndex++;

setViewText();

}

if (step - temp_view_plus_text_length * 2 == 0) {

marqueeIndex++;

switchSecondTime = System.currentTimeMillis();

setViewText();

}

if (!isStarting) {

return;

}

step += 3;// 速度

if (step > temp_view_plus_two_text_length) {

step = textLength;

}

invalidate();

} catch (Exception e) {

e.printStackTrace();

}

}

@Override

public boolean isFocused() {

return true;

}

@Override

protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {

if (focused) {

super.onFocusChanged(focused, direction, previouslyFocusedRect);

}

}

@Override

public void onWindowFocusChanged(boolean hasWindowFocus) {

if (hasWindowFocus) {

super.onWindowFocusChanged(hasWindowFocus);

}

}

public interface OnMarqueeItemListener {

void onItemListener(int position);

}

}

相关内容

热门资讯

春节后资金面前瞻:首周超2.2... 春节前央行通过逆回购、买断式逆回购等多种公开市场工具加大资金投放,呵护流动性保持宽松。面对节后大量逆...
公募密集调研,机构:春晚对人形... 来源:环球网【环球网财经综合报道】今年春晚,机器人相关话题热度居高不下。节前,多家相关企业已成为公募...
中国顶流私募Q4调仓大转向:集... 财联社2月20日讯(编辑刘蕊)随着美国证券交易委员会(SEC)2025年第四季度13F持仓报告披露收...
美股科技股拉升,谷歌涨超4%,... 记者丨张嘉钰编辑丨曾静娇周五(2月20日),欧美股市全线收涨,道指涨0.47%,标普500指数涨0....
Anthropic发布Clau... Anthropic推出AI代码扫描工具引发行业忧虑,网络安全股集体重挫。2月20日,Anthropi...