自定义列表数据数据跑马灯
创始人
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);

}

}

相关内容

热门资讯

重大通报“阳光岛牌乐汇可以开挂... 您好:阳光岛牌乐汇这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5951795】很多玩家在阳光...
最新消息“决战卡五星究竟是有挂... 您好:决战卡五星这款游戏可以开挂,确实是有挂的,需要软件加微信【8487422】很多玩家在这款游戏中...
分享实测“天天休闲透视辅助软件... 您好:天天休闲这款游戏可以开挂,确实是有挂的,需要软件加微信【6355786】,很多玩家在天天休闲这...
重磅.通报“中至鹰潭是不是有挂... 您好:中至鹰潭这款游戏可以开挂,确实是有挂的,需要了解加客服微信【6676724】很多玩家在这款游戏...
科普实测“白金岛跑得快到底是不... 您好:白金岛跑得快这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5951795】很多玩家在白金...