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

先上个效果图:

从图片中可以看到布局是由包含两个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(Listviews):设置跑马灯View列表,间歇时间为默认时间;

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

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

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

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

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

原理

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

使用示例:

xml代码:<?xml version="1.0" encoding="utf-8"?>

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 跑马灯带图片,Android自定义跑马灯效果(适合任意布局)相关推荐

  1. 通过 MarqueeFactory 来提供各种样式的跑马灯 View, 支持自定义跑马灯 ItemView

    MarqueeViewLibrary 项目地址:gongwen/MarqueeViewLibrary 简介:跑马灯 更多:作者   提 Bug    标签: 跑马灯- 通过 MarqueeFactor ...

  2. Android 系统自带图片裁剪功能(适配7.0、8.0、对了还有小米手机)

    前段时间写了如何获取相册和拍照之后的照片并且进行显示和上传,这一次是如何进行圆形图像制作,经常看我写的笔记的人会知道,我很懒.那么我就懒的自定义了,目前需求就用原生的就好了,大神的轮子,我会在后面进行 ...

  3. android文本框带图片格式,android 带图片的文本框

    基本原理 自定义一个IconTextView类继承自TextView,添加iconsrc属性,表示图片. 重新onDraw方法,将图片绘制到textVIew前面,然后将textView右移. 废话不多 ...

  4. Android学习之带图片的Button

    在手机应用中,往往会看到这样子的图片: Button中有属性是可以带入图片,并设置位置的,但是偏偏Drawable Left,Drawable Top,Drawable Right,Drawable ...

  5. android glide 4旋转图片,Android 效率开发之图片---Glide 旋转图片处理

    事实上Glide会对旋转的图片正确处理,比如你在三星手机上拍照旋转了90度,用Glide 加载的话,会正确显示. 通过Glide 强大的图片变换功能,我们也可以旋转图片,关于Glide 的图片变换请参 ...

  6. android手机自带表情符号,android系统自带Emoji表情与表情描述互相转换

    前言 Emoji表情几乎都是有表情描述的,如愤怒的表情会有[愤怒],这样的描述,这里就是举了个列子,至于是什么样的表现形势,这是可以自己定义的.那么这样,一个表情带一个表情描述的好处就是,当我们发送信 ...

  7. 【Android 安装包优化】Android 中使用 SVG 图片 ( Android 5.0 以下的矢量图方案 | 矢量图生成为 PNG 图片 )

    文章目录 一.Android 5.0 以下的矢量图方案 二.矢量图生成为 PNG 图片 三.完整的 build.gradle 构建脚本 四.编译效果 五.参考资料 一.Android 5.0 以下的矢 ...

  8. Android之点击图片底部出现灰色圆圈效果

    1 需求 点击图片底部出现灰色圆圈效果 2 代码实现 1.num_oval_gray_def.xml <?xml version="1.0" encoding="u ...

  9. android 查看多个图片,android提取视频多张图片和视频信息

    android提取视频多张图片和视频信息 话说2016年的直播比较火,2017年短视频又火了.但对于开发者来说隐藏在这背后的技术才是我们所关心的,毕竟我们是靠技术吃饭的. 现在在安卓中多媒体服务比较强 ...

  10. android工程换背景图片,Android初学者:用知乎Matisse开源项目制作更换应用背景图片功能...

    前言 我搜索了下关于知乎Matisse的使用教程甚少,于是我就想着来做一个教程,这个教程是针对初学者的,因为我自己也是一个初学者,希望对各位刚刚接触Android开发的小伙伴有帮助! 关于Matiss ...

最新文章

  1. 单细胞转录组单飞第二期开课啦!!
  2. 使用阿里云OSS上传文件
  3. FD.io/VPP — VPP Agent — Telemetry Plugin
  4. 2010最值得关注的10款小众互联网产品
  5. MYSQL 时间计算的 3 种函数
  6. linux C++怎么转java?从云计算切入容易么?
  7. CentOS下ZooKeeper单机模式、集群模式安装
  8. python查看文档的软件_Python __doc__属性:查看文档
  9. OpenShift 4 - 设置集群节点和Pod容器的时间和时区
  10. 使用Spring的Property文件存储测试数据 - 初始化
  11. iis6.0渗透实战笔记
  12. Android fastboot下载模式或reboot流程解析
  13. 【台达 PLC - 1】 - 编程软件(WPL)
  14. phpStrom连接MySQL数据库
  15. 叉乘点乘混合运算公式_运算定律和简便计算的说课稿
  16. ARM嵌入式主板在激光雕刻机领域的应用
  17. 升腾c10,华为ct3100安装nextcloud,KodExplorer网盘
  18. win10cmd切换目录
  19. 树立感恩心态 追求卓越人生
  20. 字符串去重的5种方式

热门文章

  1. js获取浏览器内核版本信息
  2. java高级实训输出张三李四_假设某数据库表中有一个姓名字段,查找姓名为张三和李四的条件是...
  3. 酷安uwp版|酷安uwp版客户端
  4. Android 7.1 设置不支持遥控操作?
  5. 图像坐标球面投影_一种将球面图像投影至平面图像的方法与流程
  6. mysql case when in_MySQL case when 使用
  7. 【Matlab元胞自动机】元胞自动机双边教室疏散【含源码 1208期】
  8. 【合宙GSM模块Air202 烧录iRTU固件连接阿里云】
  9. 针对于Vins-Mono中的评价工具evo中的评价参数的理解
  10. sketch怎么把psd导出为HTML,如何巧妙将sketch文档完美转换成PSD