热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Android编程实现类似天气预报图文字幕垂直滚动效果的方法

这篇文章主要介绍了Android编程实现类似天气预报图文字幕垂直滚动效果的方法,涉及Android基于布局及事件响应实现图文滚动效果的相关操作技巧,需要的朋友可以参考下

本文实例讲述了Android编程实现类似天气预报图文字幕垂直滚动效果的方法。分享给大家供大家参考,具体如下:

在很多天气或者新闻的应用中,我们都能看到一些字幕滚动的效果,最简单的实现为跑马灯效果,用系统提供的属性即可实现. 复杂一些的就需要自己去用自定义控件实现. 比如 让TextView 实现垂直滚动. 这里我要讲的是垂直滚动的字幕效果,并且内容并不仅为文字,还可以加入图片或者其他元素. 废话不多说,还是直接上效果图:

首先还是看一下核心的实现:

目前我的做法是重写了ScrollView,对外提供几个重要的方法:

isScrolled()方法判断当前是否为滚动状态
setScrolled(boolean flag)设置滚动的开关
setPeriod(long period)设置从开始滚动到结束的时间
setSpeed(long speed)设置滚动的速度

下面说一些需要注意的地方:

1.由于是定时操作,所以需要在Activity的对应生命周期进行处理: 当界面由不可见到可见时,设置setScrolled(true)打开滚动开关,由可见到不可见时,setScrolled(false)关闭开关

2. 可根据自己需要调用setPeriod(long period)setSpeed(long speed)控制滚动的速度

3. 由于是ScrollView实现的,中间放置的内容同ScrollView,不仅仅可以设置文字,还可以添加图片等其他元素,实现复杂的UI

4. 图文混排, 目前这个DEMO我还没做细致处理. 最主要的部分就是文字的处理,需要考虑中英文,全角半角,字体大小,段落处理,计算对应的字符宽高等进行排版

图片等资源处理的部分就相对要简单,主要处理分辨率与计算宽高

关于这些部分,之后我会慢慢做细致讲解.

这个Demo是我临时写的,UI和图文混排包括具体的滚动部分处理都相对简单,大家可以在这个例子的基础上进行扩展,根据需求做出自己想要的效果:

demo示例代码点击此处本站下载

下面是对应的代码:

首先是自定义View:

package com.tony.autoscroll;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;
/**
 * @author Tony
 *
 */
public class AutoScrollView extends ScrollView {
  private final Handler handler = new Handler();
   private long duration   = 50;
   private boolean isScrolled  = false;
  private int currentIndex = 0;
  private long period = 1000;
  private int currentY = -1;
  private double x;
  private double y;
  private int type = -1;
  /**
   * @param context
   */
   public AutoScrollView(Context context) {
    this(context, null);
  }
   /**
   * @param context
   * @param attrs
   */
  public AutoScrollView(Context context, AttributeSet attrs) {
     this(context, attrs, 0);
  }
  /**
   * @param context
    * @param attrs
    * @param defStyle
    */
  public AutoScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
   }
  public boolean onTouchEvent(MotionEvent event) {
     int Action = event.getAction();
    switch (Action) {
      case MotionEvent.ACTION_DOWN:
        x=event.getX();
        y=event.getY();
         if (type == 0) {
           setScrolled(false);
         }
         break;
       case MotionEvent.ACTION_MOVE:
        double moveY = event.getY() - y;
         double moveX = event.getX() - x;
        if ((moveY>20||moveY<-20) && (moveX <50 || moveX > -50) && getParent() != null) {
           getParent().requestDisallowInterceptTouchEvent(true);
         }
         break;
      case MotionEvent.ACTION_UP:
         if (type == 0) {
           currentIndex = getScrollY();
          setScrolled(true);
        }
        break;
      default:
        break;
     }
     return super.onTouchEvent(event);
  }
  @Override
  public boolean onInterceptTouchEvent(MotionEvent p_event)
  {
    return true;
  }
  /**
   * 判断当前是否为滚动状态
   *
   * @return the isScrolled
   */
   public boolean isScrolled() {
    return isScrolled;
   }
   /**
   * 开启或者关闭自动滚动功能
   *
   * @param isScrolled true为开启,false为关闭
   */
   public void setScrolled(boolean isScrolled) {
    this.isScrolled = isScrolled;
    autoScroll();
   }
   /**
   * 获取当前滚动到结尾时的停顿时间,单位:毫秒
   *
   * @return the period
   */
   public long getPeriod() {
    return period;
   }
   /**
   * 设置当前滚动到结尾时的停顿时间,单位:毫秒
   *
   * @param period
   * the period to set
   */
   public void setPeriod(long period) {
     this.period = period;
   }
   /**
   * 获取当前的滚动速度,单位:毫秒,值越小,速度越快。
    *
   * @return the speed
   */
   public long getSpeed() {
    return duration;
   }
   /**
   * 设置当前的滚动速度,单位:毫秒,值越小,速度越快。
   *
   * @param speed
   *      the duration to set
   */
   public void setSpeed(long speed) {
     this.duration = speed;
   }
   public void setType(int type){
     this.type = type;
   }
   private void autoScroll() {
     handler.postDelayed(new Runnable() {
      @Override
       public void run() {
        boolean flag = isScrolled;
         if (flag) {
          if (currentY == getScrollY()) {
             try {
              Thread.sleep(period);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
            currentIndex = 0;
             scrollTo(0, 0);
            handler.postDelayed(this, period);
          } else {
            currentY = getScrollY();
            handler.postDelayed(this, duration);
            currentIndex++;
            scrollTo(0, currentIndex * 1);
          }
        } else {
            //currentIndex = 0;
            //scrollTo(0, 0);
        }
      }
    }, duration);
  }
}

MainActivity:

package com.tony.autoscroll;
import com.example.testautoscroll.R;
import android.os.Bundle;
import android.app.Activity;
/**
 * link: blog.csdn.net/t12x3456
 * @author Tony
 *
 */
public class MainActivity extends Activity {
  private AutoScrollView scrollView;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    scrollView = (AutoScrollView) findViewById(R.id.auto_scrollview);
  }
  @Override
  protected void onStart() {
    // TODO Auto-generated method stub
    if(!scrollView.isScrolled()){
      scrollView.setScrolled(true);
    }
    super.onStart();
  }
  @Override
  protected void onStop() {
    // TODO Auto-generated method stub
    if(scrollView.isScrolled()){
      scrollView.setScrolled(false);
    }
    super.onStop();
  }
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android Service组件使用技巧总结》、《Android编程之activity操作技巧总结》、《Android资源操作技巧汇总》、《Android文件操作技巧汇总》、《Android操作SQLite数据库技巧总结》、《Android操作json格式数据技巧总结》、《Android数据库操作技巧总结》、《Android开发入门与进阶教程》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。


推荐阅读
  • MySQL 8.0 新特性详解:免费视频教程上线
    本文介绍了一套在慕课网上发布的免费视频教程,深入解析 MySQL 8.0 的核心新功能,包括增强的安全性、用户管理、新的索引类型、CTE 和窗口函数等。 ... [详细]
  • 本文介绍了基于Java的在线办公工作流系统的毕业设计方案,涵盖了MyBatis框架的应用、源代码分析、调试与部署流程、数据库设计以及相关论文撰写指导。 ... [详细]
  • 本文基于最新版SQLite 3.33.0(发布于2020年8月20日),详细介绍如何使用ORDER BY语句进行数据排序,包括单列和多列排序的方法。 ... [详细]
  • 本文探讨了Android系统中联系人数据库的设计,特别是AbstractContactsProvider类的作用与实现。文章提供了对源代码的详细分析,并解释了该类如何支持跨数据库操作及事务处理。源代码可从官方Android网站下载。 ... [详细]
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文通过具体示例详细介绍了 Python 中的装饰器和装饰类的使用方法,包括带参数的装饰器和装饰类的应用场景。 ... [详细]
  • RabbitMQ 核心组件解析
    本文详细介绍了RabbitMQ的核心概念,包括其基本原理、应用场景及关键组件,如消息、生产者、消费者、信道、交换机、路由键和虚拟主机等。 ... [详细]
  • 本文探讨了如何在Sitecore 9环境中通过Postman使用API密钥发送请求,包括解决常见错误的方法。 ... [详细]
  • iOS 小组件开发指南
    本文详细介绍了iOS小部件(Widget)的开发流程,从环境搭建、证书配置到业务逻辑实现,提供了一系列实用的技术指导与代码示例。 ... [详细]
  • 本文提供了一个SQL脚本,用于在Microsoft SQL Server中创建一个数据字典视图,该视图详细列出了表名、表描述、字段名称、字段描述、字段类型、字段大小、字段精度、是否可为空、默认值以及是否为标识或主键等信息。 ... [详细]
  • MyBatis入门指南:环境搭建与基础配置详解
    本文详细介绍了MyBatis的基础配置流程,包括在Maven项目中添加MyBatis依赖、IDEA中配置数据库连接、导入SQL脚本以及编写mybatis-config.xml配置文件等关键步骤。 ... [详细]
  • Kubernetes Services详解
    本文深入探讨了Kubernetes中的服务(Services)概念,解释了如何通过Services实现Pods之间的稳定通信,以及如何管理没有选择器的服务。 ... [详细]
  • 本文详细介绍了如何在VSCode环境中配置Prettier工具以支持TypeScript项目,同时结合ESLint实现代码风格的一致性和自动化格式化。 ... [详细]
  • 本文详细介绍了在MyBatis框架中如何通过#和$两种方式来传递SQL查询参数。使用#方式可以提高执行效率,而使用$则有助于在复杂SQL语句中更好地查看日志。此外,文章还探讨了不同场景下的参数传递方法,包括实体对象、基本数据类型以及混合参数的使用。 ... [详细]
  • This article explores the process of integrating Promises into Ext Ajax calls for a more functional programming approach, along with detailed steps on testing these asynchronous operations. ... [详细]
author-avatar
you是was的was
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有