自定义列表数据数据跑马灯

文章介绍了一个在Android项目中实现横向跑马灯效果的自定义View——MuchMarqueeView。此视图可以处理单行显示且内容过长的情况,同时支持每个条目的点击事件。关键代码包括文本测量、滚动逻辑以及状态管理,还提供了开始和停止滚动的方法。
摘要由CSDN通过智能技术生成

最近项目中用到了 横向跑马灯 顺序显示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<Information> 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<Information> 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);

}

}

$PBExportComments$用数据窗口做跑马灯 release 7; datawindow(units=1 timer_interval=10 color=15780518 processing=0 HTMLDW=no print.documentname="" print.orientation = 0 print.margin.left = 24 print.margin.right = 24 print.margin.top = 24 print.margin.bottom = 24 print.paper.source = 0 print.paper.size = 0 print.prompt=no print.buttons=no print.preview.buttons=no ) summary(height=0 color="536870912" ) footer(height=0 color="536870912" ) detail(height=87 color="536870912" ) table(column=(type=char(10) updatewhereclause=yes name=s dbname="s" ) ) text(band=header alignment="1" text="S:" border="0" color="0" x="13" y="6" height="14" width="18" name=s_t font.face="宋体" font.height="-9" font.weight="400" font.family="0" font.pitch="2" font.charset="134" background.mode="1" background.color="536870912" ) column(band=detail id=1 alignment="0" tabsequence=10 border="0" color="0" x="2" y="32" height="1" width="16" format="[general]" name=s edit.limit=0 edit.case=any edit.focusrectangle=no edit.autoselect=yes edit.autohscroll=yes font.face="宋体" font.height="-9" font.weight="400" font.family="0" font.pitch="2" font.charset="134" background.mode="1" background.color="536870912" ) text(band=detail alignment="0" text="现在跑马灯可以用了!" border="0" color="8421376" x="0~t333 - (long(left(right(string(t),4),3))) /1.5" y="0" height="33" width="279" name=t_1 font.face="Arial" font.height="-20" font.weight="700" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="553648127" ) compute(band=summary alignment="0" expression="left(string(cpu()) + string(today(),'yyyymmdd'),len(string(cpu()) + string(today(),'yyyymmdd')) -8)"border="0" color="0" x="43" y="11" height="19" width="371" format="[general]" name=t visible="1~t0" font.face="Arial" font.height="-12" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="2" background.color="16777215" ) text(band=detail alignment="0" text="/*truncate((long(left(right(string(t),4),3)) /50),0) * 50* (rgb(255,255,255) /1000)*/rand(100)/100 * rgb(255,255,255)" border="0" color="16711935" x="1" y="44" height="14" width="1418" name=t_2 font.face="Arial" font.height="-8" font.weight="700" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="553648127" ) text(band=detail alignment="0" text="333 - (long(left(right(string(t),4),3))) /1.5" border="0" color="16711935" x="0" y="66" height="14" width="508" name=t_3 font.face="Arial" font.height="-8" font.weight="700" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="553648127" ) htmltable(border="1" ) htmlgen(clientevents="1" clientvalidation="1" clientcomputedfields="1" clientformatting="0" clientscriptable="0" generatejavascript="1" )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值