要做什么

最近在做“叮咚钱包”时,有这样的一个需求,类似“招商银行掌上生活”小贴士如下图(红色框):

再来一张更清楚动态图(这个动态gif可是研究了半天才制作完成,如有人感兴趣就分享)


构建思路

一开始是想用View来绘制,考虑到有图片和文字,单用view来绘制难度过大。最后采用LinearLayout布局,滚动用动画来实现。如果封装成一个类最好不过了。let do it!


步骤一:layout布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="44dp"android:orientation="horizontal"><ImageView
        android:id="@+id/iv_icon"android:layout_width="wrap_content"android:layout_height="44dp"android:layout_centerVertical="true"android:layout_marginLeft="9.3dp"android:layout_marginRight="10dp"android:src="@mipmap/tips_title" /><TextView
        android:id="@+id/tv_line"style="@style/SingleLineVertical"android:layout_marginBottom="8dp"android:layout_marginTop="8dp"android:layout_toRightOf="@+id/iv_icon" /><LinearLayout
        android:id="@+id/ll_tips"android:layout_width="wrap_content"android:layout_height="88dp"android:layout_toRightOf="@+id/tv_line"android:orientation="vertical"><LinearLayout
            android:layout_width="wrap_content"android:layout_height="44dp"android:orientation="horizontal"><TextView
                android:id="@+id/tv_title1"android:layout_width="wrap_content"android:layout_height="24dp"android:layout_gravity="center"android:layout_marginLeft="11dp"android:background="@drawable/tips_text"android:gravity="center"android:paddingLeft="9dp"android:paddingRight="9dp"android:text="累计成交额"android:textColor="#eb1212"android:textSize="12dp" /><TextView
                android:id="@+id/tv_content1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginLeft="13dp"android:text="10000元"android:textColor="#313131"android:textSize="14.6dp" /></LinearLayout><LinearLayout
            android:layout_width="wrap_content"android:layout_height="44dp"android:orientation="horizontal"><TextView
                android:id="@+id/tv_title2"android:layout_width="wrap_content"android:layout_height="24dp"android:layout_gravity="center"android:layout_marginLeft="11dp"android:background="@drawable/tips_text"android:gravity="center"android:paddingLeft="9dp"android:paddingRight="9dp"android:text="累计成交额"android:textColor="#eb1212"android:textSize="12dp" /><TextView
                android:id="@+id/tv_content2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginLeft="13dp"android:text="20000元"android:textColor="#313131"android:textSize="14.6dp" /></LinearLayout></LinearLayout>
</LinearLayout>


我们很快就能完成布局。从上面代码23~89行,可以看出是使用两个44dp高度的LinearLayout组合而成。一个可以显示,一个则被限制隐藏着。被隐藏的我们将会使用动画效果来实现滚动。


步骤二:优化layout布局

一般我们是不会去做这样的事,既然闲来无事。那就研究研究。我们使用android自带工具hierarchyviewer.bat,这个是在模拟器上使用,现在很多真机很难root成功。

红色框是系统生成的,从后面LinearLayout开始才是我们绘制的。优化空间还是有的,我们可以用merge来优化 LinearLayout-》TipsView-》LinearLayout。


后面的两个LinearLayout可以考虑定义一个xml布局后,使用include同样再用merge。考虑到实际项目中,不应该切得太碎片了,文件多也未必是好事。就先暂时这样。

下面是优化后的布局,在布局代码中外最外层的LinearLayout改为merge即可

这是对改后对比,很明显红框1三个变成红框2两个。

这是讲解merge的链接:http://www.infoq.com/cn/articles/android-optimise-layout


步骤三:编写控制类

public class TipsView extends LinearLayout {private static final int INTERVAL = 3000;private Context context;private LinearLayout ll_tips;private TextView tv_title1, tv_content1, tv_title2, tv_content2;private List<TipsBean> list = new ArrayList<>();private int cursor = 0;private Handler handler = new Handler();private Timer timer;public TipsView(Context context) {super(context);this.context = context;initView(context);}public TipsView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;initView(context);}private void initView(Context context) {LayoutInflater.from(context).inflate(R.layout.tips_ll, this);ll_tips = (LinearLayout) findViewById(R.id.ll_tips);tv_title1 = (TextView) findViewById(R.id.tv_title1);tv_content1 = (TextView) findViewById(R.id.tv_content1);tv_title2 = (TextView) findViewById(R.id.tv_title2);tv_content2 = (TextView) findViewById(R.id.tv_content2);timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {if (list != null && list.size() != 0) {handler.post(new Runnable() {@Overridepublic void run() {startRolling();}});}}}, 0, INTERVAL);}public void destroy() {if (timer != null) {timer.cancel();}}public void setContext(List<TipsBean> list) {if (list.size() < 2) return;// 复位数据this.list.clear();this.list.addAll(list);cursor = 0;// 设置数据tv_title1.setText((this.list.get(0).getTips()));tv_content1.setText((this.list.get(0).getContent()));tv_title2.setText((this.list.get(1).getTips()));tv_content2.setText((this.list.get(1).getContent()));}private void startRolling() {Animation animation = AnimationUtils.loadAnimation(context, R.anim.tips_roll);animation.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {ll_tips.clearAnimation();cursor++;if (cursor > list.size() - 1) cursor = 0;tv_title1.setText((list.get(cursor).getTips()));tv_content1.setText((list.get(cursor).getContent()));tv_title2.setText((list.get(cursor + 1 >= list.size() ? 0 : cursor + 1).getTips()));tv_content2.setText((list.get(cursor + 1 >= list.size() ? 0 : cursor + 1).getContent()));}@Overridepublic void onAnimationRepeat(Animation animation) {}});ll_tips.startAnimation(animation);}
}

我们是使用Timer 和 Handler结合来实现定时轮播的。这里有一个非常重要需要注意一下,在使用完Timer后必须cancel()如果没有的话,那么你的定时器将一直执行,直到应用退出。这里将存在内存泄漏的可能。

public void onAnimationEnd(Animation animation) {ll_tips.clearAnimation();cursor++;if (cursor > list.size() - 1) cursor = 0;tv_title1.setText((list.get(cursor).getTips()));tv_content1.setText((list.get(cursor).getContent()));tv_title2.setText((list.get(cursor + 1 >= list.size() ? 0 : cursor + 1).getTips()));tv_content2.setText((list.get(cursor + 1 >= list.size() ? 0 : cursor + 1).getContent()));
}

我们是使用list来循环,大于后则置0.
ll_tips.clearAnimation();在动画执行完后要清除,不然会有卡顿的现象。

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:fromYDelta="0%p"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:toYDelta="-100%p">
</translate>

这是动画xml,从以下图我们可以知道是向上移动。动画时间是500ms。
想学习动画的同学,可以参考以下链接。
http://blog.csdn.net/scyatcs/article/details/26764641


步骤四:还有哪些可以做的?

这样代码似乎看似没有什么问题了。不过也确实一般我也只做到这步骤,上班时没有我们多余时间去总结优化。现在我们不妨多多考虑内存,性能方面。大家可以发散性思维讨论,做测试。

  • 如果多个线程调用setContext()来设置播报内容,会不会出问题?是否考虑线程安全?
  • 我们试着加快滚动速度,看下内存是否泄漏,cpu是否正常。能否优化?
  • 视图是否过度渲染?

Android 小贴士播报相关推荐

  1. 切图小贴士-手机Android平台“点九”的切图

    用户手中看到的产品界面,并非设计师呕心沥血创作的效果图,而是一个个单独的切图经由开发同学技术实现.切图作为设计师与开发者之间的桥梁,它的作用很关键,合适的切图.精准的位置可以最大限度的还原效果图的设计 ...

  2. Android小项目之--前台界面与用户交互的对接 进度条与拖动条(附源码)

    都知道水果公司(苹果)是己尊重用户体验著称的公司,其设计的产品人性化十足,不得不令后来者赞叹,竞相模仿.iphone的成功就是其典型的案例,做为其移动系统的死对头 Google 想要在市场上分得一杯羹 ...

  3. 带android小绿人的屏保相册,盘点:那些年我们追过的Android

    Android小绿人将在今年十一月份度过第五个生日.而在最新的Android操作系统果冻豆到来之前,还是让我们来回顾一下以前的版本,追忆Android已经走过的岁月. 在正式形成规模效应之前,Andr ...

  4. 重置linux桌面,Ubuntu 18.04小贴士:重置Gnome桌面与使用隐藏的屏幕录像工具

    原标题:Ubuntu 18.04小贴士:重置Gnome桌面与使用隐藏的屏幕录像工具 1.如何在Ubuntu 18.04中重置Gnome桌面 本快速教程将向您展示如何在Ubuntu 18.04 LTS中 ...

  5. Android小项目源码汇总

     Android小应用源码之贪吃蛇 Android小应用源码之CamMonitor Android小应用源码之SpeakMessageService Android小应用源码之mediaplayer ...

  6. 13个代码注释的小贴士

    下面的13条小贴士可以帮助你写出更规范.更容易维护的代码注释. 1.逐层注释 使用统一格式对每一个语句块进行注释,如: 类:简单描述.作者.最后修改时间等 方法:关于该方法的目的.函数.参数.返回值的 ...

  7. python编程小知识_分享Python开发中要注意的十个小贴士

    大家请注意:这篇文中假设我们都用的是Python 3 1. 列表推导式 你有一个list:bag = [1, 2, 3, 4, 5] 现在你想让所有元素翻倍,让它看起来是这个样子:[2, 4, 6, ...

  8. 【小贴士】虚拟键盘与fixed带给移动端的痛!

    前言 今天来公司的主要目的就是研究虚拟键盘与fixed的问题,期间因为同事问起闭包与事件委托(阻止冒泡)相关问题,便穿插了一篇别的: [小贴士]工作中的"闭包"与事件委托的&quo ...

  9. 掌握这 25 条小贴士,快速提升数据可视化能力!

    英文:Katy French,翻译:优设 可视化不是单纯的数据展示,其真正价值是设计出可以被读者轻松理解的数据展示.设计过程中的每一个选择,最终都应落地于读者的体验,而非设计者个人. 本文提到了一些常 ...

最新文章

  1. 3d stroke插件下载_推荐一款好用的PS 3D地图插件,PS插件3D Map Generator ,一键生成地图神器...
  2. static使用方法小结
  3. shell-init: error
  4. OpenGL 镜面反射 IBL
  5. 使用基本身份验证来保护Spring Boot REST API
  6. 如何判断链表有环并计算环的长度
  7. 无心剑中译奥修《性、爱与慈悲》
  8. [golang]如何看懂调用堆栈
  9. Codeforces Round #202 (Div. 1): D. Turtles(Lindström–Gessel–Viennot lemma定理+DP)
  10. 小辣椒android密码怎样开,小辣椒手机忘记密码怎么恢复出厂设置
  11. 前端的小玩意(9.4)——做一个仿360工具箱的web页面(自动生成所有图标,对图标添加响应逻辑)
  12. vivo Z1的USB调试模式在哪里,打开vivo Z1USB调试模式的经验
  13. xlsx模块 前端_React读取Excel——js-xlsx 插件的使用
  14. 富文本框wangEditor
  15. linux运行直播软件,在Linux下可用Wine安装和运行虎牙直播、斗鱼直播
  16. 一些基于新闻表示和用户表示的新闻推荐模型总结:NPA/ NAML/ LSTUR/ NRMS
  17. 外贸电商erp哪个好
  18. Analytics Zoo 入门
  19. e5430支持服务器内存,手贱!入手了逆天护舒宝771四核E5430平台,再战IGAME GTX650TI BOOST...
  20. 创业就失败的12种人

热门文章

  1. 怎么在CAD三维图面上添加一长段说明文字?
  2. dakai微信小程序 ios_【iOS】微信小程序打开APP到底是怎么回事?
  3. 【Luogu P1151】子数整数
  4. 北大清华联手开设通用人工智能实验班,「顶级AI科学家」朱松纯领衔
  5. ArcGIS,CC(Smart3D),ENVI....工作中常用软件的汉化包都在这,随你下载
  6. mixamo骨骼_Mixamo——在线三维人物角色骨骼自动绑定,上千动作库直接生成人物动画...
  7. 论文阅读笔记:Layer Normalization
  8. BZOJ3161: 孤舟蓑笠翁
  9. 【Java实战篇】SpringBoot+MyBatis快速实现登录注册
  10. 堆米微信H5页面怎么制作?易企秀微信H5页面制作,微信简历制作,