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

}

}

相关内容

热门资讯

释放内需潜能,提振消费向深而行... 中央经济工作会议在部署明年经济工作重点任务时提出,坚持内需主导,建设强大国内市场。在一系列具体任务安...
互联网平台不得“亏本卖”,香港... 国家发展改革委、市场监管总局、国家网信办12月20日联合发布的《互联网平台价格行为规则》(下称《规则...
国投白银LOF涨疯了!11则风... 白银LOF的狂热仍在持续。12月20日,国投瑞银基金发布溢价风险提示公告,并指出为保护投资者利益,国...
南博很可能是背锅的?前院长曾昭... 又有新料爆出,南京博物院很可能是背锅的。之前有一件事一直想不明白,南京博物院说1961年组成了张珩、...
长三角A股市值首超30万亿 2025.12.22本文字数:2953,阅读时长大约5分钟作者 |第一财经 魏中原从一杯白酒到一束“...