最近无意间看到了涉及到跑马灯效果的代码,于是在网上查阅了很多资料,在这里对自己看的一些文章进行一下总结,顺便加上自己的一些体会。

让我们一步步逐渐向下。

首先我们要实现走马灯这样一个效果,通常来说都是在TextView这个控件中来实现的,而且其中的文字一定是单行显示,如果多行显示,那走马灯效果

也就失去了存在的意义。另外,在EditText中使用走马灯没有必要,也不合理,实际上对于EditText来说android:ellipsize这个属性只有对于设置在android:hint中的文字

的时候是有用的,而且android:ellipsize="marquee"这个用法不能用在EditText控件上。对于在EditText用户输入的文字,android:ellipsize这个属性没有用处。关于EditText

设置android:ellipsize的相关用法以后再讲,在这里也算留个标记,以防自己忘了。

在TextView中实现我们的走马灯效果,需要两个属性android:singleLine="true",以及android:ellipsize="marquee",我们来看下面的代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="100dip"
  8. android:layout_height="wrap_content"
  9. android:layout_gravity="center"
  10. android:text="走马灯效果的演示"
  11. android:singleLine="true"
  12. android:ellipsize="marquee"/>
  13. </LinearLayout>

运行这段代码之后,我们会发现走马灯效果并没有显示出来,显示出的文字是不动的,实际效果如下:

这其中的原因在于跑马灯效果需要TextVIew获得当前的焦点(focus)。然而对于TextView这个控件来说,他的默认的Clickable,LongClickable,Focusable,

FocusableInTouchMode这四个属性的值都是false,所以跑马灯效果也就不会出来了,即使你用手触摸TextView或者按下手机上的导航按键(现在的手机没这

个东东了都。。。)也是无法显示跑马灯的效果的。

解决这个问题我们就需要让我们的TextView得到焦点,这里主要涉及android:focusable和android:focusableInTouchMode这两个属性,简单来说把这两个属性都设置成

true,那么在运行程序以后跑马灯效果就显示出来了,这里就不再贴这两行代码了。

但是细细品味这两个属性之后发现其中其实还是有一些玄机的:

1.。如果这两个属性设置成android:focusable="true"以及android:focusableInTouchMode="false",那么会发现程序运行之后,走马灯效果没有出现,

这个时候需要用户按下手机或者模拟器上的上下导航键,才能让走马灯的效果出现,这说明android:focusable是针对于手机按键有效的,然而根据api的解释,

android:focusableInTouchMode是根据屏幕触摸决定的。

2。如果这两个属性设置成android:focusable="false"与android:focusableInTouchMode="true",那么无论如何走马灯都出现不了了,就算加上android:clickable="true"

也不行,这说明 android:focusable="true"是android:focusableInTouchMode="true"能有效的先决条件,我推测可能是在源码实现中,android:focusableInTouchMode

的逻辑是嵌套在android:focusable中的,这个有待于以后进一步的研究,路漫漫其修远兮。。。

3。在把这两个属性都设置成true以后,会发现程序运行之后,走马灯效果自动就显现了出来,这说明应用在运行后,会自动地按照某种顺序(在这里应该是自上而下),

寻找第一个android:focusableInTouchMode="true"这个属性有效的第一个控件,当然要使这个属性有效按照前面的讨论android:focusable="true"也必须具备。根据测试,

LinearLayout的Clickable,LongClickable,Focusable,FocusableInTouchMode这四个属性默认也都是false,因此,在上面的例子中TextView就率先获得了焦点,

走马灯也就走了起来了。

这里我们做一下验证,首先将代码修改为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. android:focusable="true">
  7. <TextView
  8. android:layout_width="100dip"
  9. android:layout_height="wrap_content"
  10. android:layout_gravity="center"
  11. android:text="走马灯效果的演示"
  12. android:singleLine="true"
  13. android:ellipsize="marquee"
  14. android:focusable="true"
  15. android:focusableInTouchMode="true"
  16. ></TextView>
  17. </LinearLayout>

也就是为LinearLayout加上了android:focusable="true"然后运行应用,会发现TextView的走马灯照走不误:

然后我们为LinearLayout加上android:focusableInTouchMode="true"然后再运行,会发现走马灯失效了。

这里也就验证了我们总结的第三条结论。

但是稍等,我们在这里又发现问题了!现在无论我们怎么点击导航按钮,又或是点击屏幕上的TextView走马灯死活都走不出来了。这是怎么回事呢?

让我们理顺一下思路,按照我们前面的总结,走马灯要想有效,TextView必须要得到焦点,现在走马灯出不来,说明TextView没有得到焦点。

这里有两个情况,一是导航按钮无法让TextView或得焦点,二是屏幕点击无法让TextView获得焦点。

先看第一种情况,第一种情况的原因在于使用导航按钮切换焦点默认的的方式会跳过内部控件,说白了,上面例子里面的TextView在LinearLayout里面,现在

LinearLayout有焦点,如果你按导航按钮上下按键,焦点只会在LinearLayout同层次的控件之间切换,不会进入到Linearlayout内部,为了验证这个结论,我们使用

下面的代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. >
  7. <LinearLayout android:layout_width="fill_parent"
  8. android:layout_height="100dip"
  9. android:focusable="true"
  10. android:focusableInTouchMode="true"/>
  11. <TextView
  12. android:layout_width="100dip"
  13. android:layout_height="wrap_content"
  14. android:layout_gravity="center"
  15. android:text="走马灯效果的演示"
  16. android:singleLine="true"
  17. android:ellipsize="marquee"
  18. android:focusable="true"
  19. android:focusableInTouchMode="true"
  20. ></TextView>
  21. </LinearLayout>

然后我们运行程序,会发现开始的时候走马灯没有自动运行,因为这时候焦点在代码里面的第二个LinearLayout那里,然后我们按下导航下按键,会发现走马灯效果出来了,

这里我就不贴图了。

但是稍等,再重新运行应用,不要按导航按键,然后我们这个时候用手指或者说模拟器里的鼠标继续点击TextView,会发现走马灯还是没有出现。

这个时候我们来到了第二种情况了。

这里的问题可以总结为,除了应用第一次开启的时候,应用自动寻找到android:focusableInTouchMode="true"属性有效的控件冰赋予焦点,我们要如何

自行通过点击屏幕的方式使一个控件获得焦点,在这种情况之下控件想要获得焦点的流程是什么。

这方面的资料我没有查到,所以只能自己做一些试验,然后总结。有盲人摸象的嫌疑,但是我认为在某种程度上是管用的,继续。

首先我们将代码修改为如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. >
  7. <LinearLayout android:layout_width="fill_parent"
  8. android:layout_height="100dip"
  9. android:focusable="true"
  10. android:focusableInTouchMode="true"
  11. />
  12. <TextView
  13. android:layout_width="100dip"
  14. android:layout_height="wrap_content"
  15. android:layout_gravity="center"
  16. android:text="走马灯效果的演示"
  17. android:singleLine="true"
  18. android:ellipsize="marquee"
  19. android:clickable="true"
  20. android:focusable="true"
  21. android:focusableInTouchMode="true"
  22. ></TextView>
  23. </LinearLayout>

也就是给TextView加上了一个android:clickable="true"属性,然后运行之后发现,现在通过触摸的方式点击TextView可以让走马灯初显也就是可以让

TextView获得焦点了。

看起来问题解决了,但是仔细想想其中还是有一些值得思考的地方:

android:clickable与android:focusableInTouchMode之间是一种什么关系?是说一个空间如果要想能获得焦点就必须可点击吗?又或者说一个空间只要可以点击

就一定可以获得焦点?这二者之间是充要条件还是充分条件还是必要条件?

我们来做一下验证:

首先运行如下代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. >
  7. <LinearLayout android:layout_width="fill_parent"
  8. android:layout_height="100dip"
  9. android:clickable="true"
  10. />
  11. <TextView
  12. android:layout_width="100dip"
  13. android:layout_height="wrap_content"
  14. android:layout_gravity="center"
  15. android:text="走马灯效果的演示"
  16. android:singleLine="true"
  17. android:ellipsize="marquee"
  18. android:clickable="true"
  19. android:focusable="true"
  20. android:focusableInTouchMode="true"
  21. ></TextView>
  22. </LinearLayout>

运行后会发现,应用开始以后跑马灯马上出现,鼠标点击TextView上方的位置也就是第二个LinearLayout的区域,跑马灯不停止,这说明:

android:clickable="true"不一定就能获得焦点,也就是一个空间能点击不一定就能获得焦点。

我们来看下一段代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. >
  7. <LinearLayout android:layout_width="fill_parent"
  8. android:layout_height="100dip"
  9. android:clickable="false"
  10. android:focusable="true"
  11. android:focusableInTouchMode="true"
  12. />
  13. <TextView
  14. android:layout_width="100dip"
  15. android:layout_height="wrap_content"
  16. android:layout_gravity="center"
  17. android:text="走马灯效果的演示"
  18. android:singleLine="true"
  19. android:ellipsize="marquee"
  20. android:clickable="true"
  21. android:focusable="true"
  22. android:focusableInTouchMode="true"
  23. ></TextView>
  24. </LinearLayout>

这段代码运行之后,首先代码中的第二个LinearLayout自动获得焦点,然后我们点击TextView。跑马灯出现,TextView获得焦点,然后我们点击TextView上方区域,

跑马灯不停止。这说明如果一个空间能获得触摸模式焦点但却不能点击,那么在触摸模式下无论怎么触摸也还是不能获得焦点的。

好的我们来看最后一段代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. >
  7. <LinearLayout android:layout_width="fill_parent"
  8. android:layout_height="100dip"
  9. android:clickable="true"
  10. android:focusable="true"
  11. android:focusableInTouchMode="true"
  12. />
  13. <TextView
  14. android:layout_width="100dip"
  15. android:layout_height="wrap_content"
  16. android:layout_gravity="center"
  17. android:text="走马灯效果的演示"
  18. android:singleLine="true"
  19. android:ellipsize="marquee"
  20. android:clickable="true"
  21. android:focusable="true"
  22. android:focusableInTouchMode="true"
  23. ></TextView>
  24. </LinearLayout>

这段代码运行之后,首先走马灯不出现,代码中的第二个LinearLayout获得焦点,然后我们点击第二个TextView,走马灯出现,然后我们点击TextView上方的区域,

走马灯效果消失,说明焦点转移到代码中的第二个LinearLayout。

好的,总结一下也就是说,在触摸模式下android:clickable="true"是(android:focusable="true",android:focusableInTouchMode="true")能获得焦点的必要条件,

就是说一个控件想要在触摸模式下获得焦点就一定要可点击,上面三个属性都要有。

转自:http://www.cnblogs.com/Gaojiecai/archive/2013/06/18/3142783.html

android:ellipsize实现跑马灯效果总结(转)的更多相关文章

  1. android:ellipsize实现跑马灯效果总结

    最近无意间看到了涉及到跑马灯效果的代码,于是在网上查阅了很多资料,在这里对自己看的一些文章进行一下总结,顺便加上自己的一些体会. 让我们一步步逐渐向下. 首先我们要实现走马灯这样一个效果,通常来说都是 ...

  2. TextView: android:ellipsize="marquee" 跑马灯效果无效的问题

    今天练习的时候想实现一个文字的跑马灯效果,本来想自己手动实现的,不过突然想起来android里的TextView属性似乎自带了这个效果,叫: android:ellipsize ,平时都是把它的属性值 ...

  3. android中实现跑马灯效果以及AutoCompleteTestView与MultiAutoCompleteTextView的学习

    跑马灯效果 1.用过属性的方式实现跑马灯效果 属性:                  android:singleLine="true" 这个属性是设置TextView文本中文字 ...

  4. 【Android】TextView跑马灯效果

    老规矩,先上图看效果. 说明 TextView的跑马灯效果也就是指当你只想让TextView单行显示,可是文本内容却又超过一行时,自动从左往右慢慢滑动显示的效果就叫跑马灯效果. 其实,TextView ...

  5. android 怎么实现跑马灯效果

    自定义控件 FocusedTextView, 使android系统误以为它拥有焦点 public class FocusedTextView extends TextView { public Foc ...

  6. Android 自定义View跑马灯效果(一)

    今天通过书籍重新复习了一遍自定义VIew,为了加强自己的学习,我把它写在博客里面,有兴趣的可以看一下,相互学习共同进步: 通过自定义一个跑马灯效果,来诠释一下简单的效果: 一.创建一个类继承View, ...

  7. android 设置textview跑马灯效果

    head_tv1.setEllipsize(TextUtils.TruncateAt.MARQUEE);head_tv1.setSingleLine(true);head_tv1.setSelecte ...

  8. android ellipsize的使用及实现跑马灯效果总结

    参考资料: http://blog.csdn.net/huiwolf2008/article/details/7901084 http://www.cnblogs.com/Gaojiecai/arch ...

  9. Android学习总结——TextView跑马灯效果

    Android系统中TextView实现跑马灯效果,必须具备以下几个条件: 1.android:ellipsize="marquee" 2.TextView必须单行显示,即内容必须 ...

随机推荐

  1. 所有博客已经迁移到个人空间 blog.scjia.cc

    所有博客已经迁移到个人空间 blog.scjia.cc

  2. 在多线程环境中使用CoreData

    在多线程环境中使用CoreData BY 子非鱼 · 2014 年 10 月 13 日   上回书说道,其实CoreData学起来也没有很复杂,我们其实增删改查都和别的ORM大同小异.但是世界总是很复 ...

  3. 十八、【开源】EnterpriseFrameWork框架核心类库之Winform控制器

    回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U EFW框架中的WinContro ...

  4. VPN有什么用?(转载)

    VPN有什么用?转载自:http://www.chinaz.com/web/2012/0320/240819.shtml 当你非常非常想访问一个国外的网站,而这个网站被防火墙屏蔽的时候,你应该怎么做呢 ...

  5. 【Java设计模式】单例模式

    ### 1. 概述> 单例模式是确保某一个类中有且只有一个实例. ----------### 2. 饿汉式单例``` javapublic class SingletonInstance { p ...

  6. `cocos2dx 非完整` UI解析模块

    昨天在cocos2dx的一个群里,遇到一位匿名为x的朋友询问的问题,是关于ui的.他使用c++写了不少的ui封装节点,用来实现游戏中的各种不同效果.然后现在想改用lua,于是尝试使用最小代价去复用自己 ...

  7. ruby -- 基础学习(九)filename去除扩展名

         Rails -- filename去除扩展名 简单例子:params[:upload]['preview'].original_filename 的值为templateOne.html.er ...

  8. ServiceStack.Redis 中关系操作的局限与bug

    redis是文档型的,nosql中难处理的是关系. 比如人可以发博客,博客可以有分类.按照传统sql中,用户表和分类表都是主表,博客表是从表,有用户的外键和分类的外键 如果使用文档型的思考方式. 为用 ...

  9. 直接拿来用!最火的Android开源项目

    GitHub在中国的火爆程度无需多言,越来越多的开源项目迁移到GitHub平台上.更何况,基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要.利用这些项目,有时能够让你 ...

  10. 利用 ELK系统分析Nginx日志并对数据进行可视化展示

    一.写在前面 结合之前写的一篇文章:Centos7 之安装Logstash ELK stack 日志管理系统,上篇文章主要讲了监控软件的作用以及部署方法.而这篇文章介绍的是单独监控nginx 日志分析 ...