因为项目需要,做了一个自定义垂直跑马灯,分享给大家。

先上个效果图:

从图片中可以看到布局是由包含两个TextView的布局组成,一般的垂直跑马灯效果只支持单个TextView,水平方向的跑马灯更是不需要自定义,原生TextView就支持。

小编的需求不只于此,里面的布局复杂,网上的方案已经不满足我的需求,所以参考别人的垂直跑马灯,自己写了一个支持任意布局的跑马灯效果。

下面贴上View源码:

package com.verticalmarquee.maomao.verticalmarqueedemo;

import android.content.Context;

import android.os.Handler;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.view.animation.AnimationUtils;

import android.widget.ViewAnimator;

import java.util.List;

public class VerticalMarqueeLayout extends ViewAnimator {

private static final long DEFAULT_TIMER = 2000L;

private long delayTime = DEFAULT_TIMER;

private int viewIndex;

private List views;

private static Handler handler = new Handler();

private boolean started;//是否已经开始轮播

public VerticalMarqueeLayout(Context context) {

super(context);

this.init();

}

public VerticalMarqueeLayout(Context context, AttributeSet attrs) {

super(context, attrs);

this.init();

}

private void init() {

this.setInAnimation(AnimationUtils.loadAnimation(this.getContext(), R.anim.vertical_marquee_in));

this.setOutAnimation(AnimationUtils.loadAnimation(this.getContext(), R.anim.vertical_marquee_out));

}

protected void onFinishInflate() {

super.onFinishInflate();

}

private void startMarquee() {

if (this.views != null) {

if (this.views.size() > 1) {

handler.postDelayed(new Runnable() {

public void run() {

VerticalMarqueeLayout.this.viewIndex++;

if (VerticalMarqueeLayout.this.viewIndex >= VerticalMarqueeLayout.this.views.size()) {

VerticalMarqueeLayout.this.viewIndex = 0;

}

showNext();

VerticalMarqueeLayout.handler.postDelayed(this, delayTime);

}

}, delayTime);

started = true;

} else if (this.views.size() > 0) {

this.viewIndex = 0;

} else {

this.viewIndex = 0;

}

} else {

this.viewIndex = 0;

}

}

/**

* 获取当前显示的View

* 修改方法名,避免与父类方法重名

*

* @return View

*/

public View getCurView() {

if (this.views != null && this.viewIndex >= 0 && this.viewIndex < this.views.size()) {

return this.views.get(this.viewIndex);

}

return null;

}

/**

* 获取当前显示View的index

*

* @return index

*/

public int getCurIndex() {

return this.viewIndex;

}

/**

* 设置轮播的View列表,该方法会自动轮播

*

* @param views view列表

*/

public void setViewList(List views) {

setViewList(views, DEFAULT_TIMER);

}

/**

* 设置轮播的View列表,该方法会自动轮播

*

* @param views view列表

* @param delayTime 间歇时间

*/

public void setViewList(final List views, long delayTime) {

if (views == null || views.size() == 0) {

return;

}

if (delayTime >= 100) {

//最少100毫秒,否则为默认值

this.delayTime = delayTime;

}

this.views = views;

handler.removeCallbacksAndMessages(null);

started = false;

post(new Runnable() {

@Override

public void run() {

for (View view : views) {

addView(view);

}

startMarquee();

}

});

}

//开始倒计时(轮播),在页面可见并且需要自动轮播的时候调用该方法

public void startTimer() {

if (started || views == null || views.size() <= 1) {

return;

}

stopTimer();

startMarquee();

Log.d("VerticalMarqueeLayout", "VerticalMarqueeLayout startTimer!");

}

//停止倒计时(轮播),如果调用过startTimer();在页面不可见的时候调用该方法停止自动轮播

public void stopTimer() {

if (handler != null) {

handler.removeCallbacksAndMessages(null);

started = false;

Log.d("VerticalMarqueeLayout", "VerticalMarqueeLayout stopTimer!");

}

}

}

源码解析:

init():初始化跑马灯效果(可以修改此处代码,改成水平跑马灯);

startMarquee():开始倒计时刷新页面;

getCurrentView():获取当前显示的View;

getCurrentIndex():获取当前显示的View对应的index;

setViewList(List views):设置跑马灯View列表,间歇时间为默认时间;

setViewList(List views, long delayTime):设置跑马灯View列表,间歇时间为传入的时间,单位为毫秒;

startTimer():开始倒计时,与stopTimer()配套使用;

stopTimer():停止倒计时,与startTimer()配套使用;

使用时直接调用setViewList方法,即可开始倒计时。

startTimer()和stopTimer()方法一般在activity的onResume和onPuase里面调用,为了Activity跳转之后能暂停动画;

原理

其实整个代码的核心点在于继承了ViewAnimator,ViewAnimator里面有自带的子view管理机制,通过调用showNext()可以直接显示下一个子View。这对于轮播效果很有帮助。

使用示例:

xml代码:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

android:id="@+id/marquee_root"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

Activity代码:

package com.verticalmarquee.maomao.verticalmarqueedemo;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.TextView;

import java.util.ArrayList;

import java.util.List;

public class MainActivity extends AppCompatActivity {

private VerticalMarqueeLayout marqueeRoot;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

marqueeRoot = findViewById(R.id.marquee_root);

initData();

}

private void initData() {

int count = 5;

List views = new ArrayList<>();

LayoutInflater inflater = LayoutInflater.from(this);

for (int i = 0; i < count; i++) {

views.add(inflateView(inflater, marqueeRoot, "这是标题" + i, "这里是第" + i + "条内容"));

}

marqueeRoot.setViewList(views);

}

private View inflateView(LayoutInflater inflater, VerticalMarqueeLayout marqueeRoot, String name, String desc) {

if (inflater == null) {

inflater = LayoutInflater.from(this);

}

View view = inflater.inflate(R.layout.marquee_item, marqueeRoot, false);

TextView viewName = view.findViewById(R.id.marquee_name);

TextView viewDesc = view.findViewById(R.id.marquee_desc);

viewName.setText(name);

viewDesc.setText(desc);

return view;

}

}

最后修改于2019年5月20日,修改点如下:

修复因getCurrentView方法与父类方法重名导致被调用时出现空指针异常。

开始启动轮播动画和addView操作添加到post的Runnable里面,为避免在页面未显示前调用导致的异常。这样可以放心在任意地点调用setViewList方法。

android布局跑马灯,Android自定义跑马灯效果(适合任意布局)相关推荐

  1. android stuido拨打电话,Android Studio3.5开发电话拨号器

    Android开发之电话拨号器实例详解.本人用的是Android Studio 3.5版本 首先要理清思路.思路大概是: 1.画UI  user interface 画界面   layout-> ...

  2. android 字体跑马灯,Android文字跑马灯功能的实现(自定义跑马灯控件)

    文字跑马灯效果这个功能挺常见的,网上也有很多的介绍,大多是说使用普通的TextView加上几条属性即可实现.不过我在使用时发现并不能实现滚动,可能是因为我的页面中使用到的布局及控件比较复杂,被别的控件 ...

  3. android文字自动滚动,Android TextView文字横向自动滚动(跑马灯)

    TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true" 2.设置可滚到,或显示样式:android:elli ...

  4. android上垂直跑马灯,android textview 垂直滚动and水平跑马灯

    垂直滚动的话就挺简单的.当然了不是自动的垂直滚动.如果是自动的垂直滚动的话还需要自定义.所以如果有需求需要textview 可以垂直滚动的话,那你来这里就对了. 直接贴 代码.就是这么任性. andr ...

  5. Android TextView文字横向自动滚动(跑马灯)

    TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true" 2.设置可滚到,或显示样式:android:elli ...

  6. android:ellipsize = marquee 跑马灯,Android-单行跑马灯(一直循环)效果

    [声明:]本文是作者(蘑菇v5)原创,版权归作者 蘑菇v5所有,侵权必究.本文首发在简书.如若转发,请注明作者和来源地址!未经授权,严禁私自转载! 前言: 提示的效果,要求一直循环. 1.跑马灯效果( ...

  7. android自动跑马灯,Android-最强跑马灯

    Android--最强跑马灯 Android 跑马灯已经有很多版本,从最基本的TextView,到重写TextView使TextView取消焦点限制,还有重写TextView利用ScrollTo方法写 ...

  8. Android 循环滚动控件ViewFlipper,可实现跑马灯或轮播图效果

    ViewFlipper--Android循环滚动控件 1.效果如下: 2.实现方法 (1)创建进出动画 上下滚动动画 y_in.xml <?xml version="1.0" ...

  9. Android TextView设置多样式文本,跑马灯以及霓虹灯效果

    1.设置TextView字体颜色 1)使用Html标签方式设置 代码如下: tvTest1.setText(Html.fromHtml("电影<font color = blue> ...

  10. android paint跑马灯,Android使用Canvas实现跑马灯

    网上的很多的教程都是通过更改TextView的属性进行跑马灯的设计.这样做有很多的缺点: 1.如果TextView没有获取焦点,那么跑马灯的效果无法实现. 2.如果文本长度小于TextView的宽度, ...

最新文章

  1. 浅谈MAXIMO项目实施(转)
  2. 少年开始学习c#编程,过路的大神请担待!
  3. linux 关闭redis 命令_面试必问的 Redis:RDB、AOF、混合持久化
  4. hdu2642二维树状数组单点更新+区间查询
  5. OpenSSH学习笔记(安装配置openssh-4.6p1)[zz]
  6. classloader隔离练习
  7. 面向对象三大特性之——封装
  8. 网页设计软件列表HTML,十种网页设计软件
  9. MYSQL UPDATE使用子查询
  10. 学习笔记75—方差分析(主效应和交互效应)
  11. Android APK安装后资源文件(res/assets)位置
  12. python蜂鸣器_Python与硬件学习笔记:蜂鸣器(转)
  13. 内核特征码搜索 获取未导出函数
  14. Visual Studio Code安装及设置
  15. 4、Gantt 任务节点部分
  16. 博阳全渠道会员营销平台-升级通知
  17. 万字长文---手把手教你加固内核安全配置
  18. 近三十而立的我们,到底是先成家后立业还是先立业再成家?
  19. 一起看 I/O | Android 开发者不能错过的 13 件事
  20. [论文总结]:faster cnns with direct sparse convolutions and guided pruning 直接稀疏卷积和引导剪枝

热门文章

  1. python绘制折线图显示单位_如何使用python语言pygal模块创建折线图并显示
  2. 埃氏筛法求区间内素数并输出
  3. 把咖啡这桩生意放进独立站,总共分几步?(上)
  4. 0x8000FFFF(0X8000FFFF,WPS)
  5. Android——TextView实现真正的跑马灯效果
  6. 安装AutoCAD 2015提示net 4.5错误的解决方法
  7. 计算机中的没有文件怎么处理方法,电脑重启后桌面上文件没有了怎么办
  8. iphone7p配置参数详情_iPhone12系列最全的详细参数,参数党可以看看
  9. 苹果涨价就衰,iPhoneSE3再次证明这一规律
  10. Importing the numpy C-extensions failed.