给 Android 开发者的 RxJava 详解

前言 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 。而最近这几个月,我也发现国内越来越多的人开始提及 RxJava 。有人说『RxJava 真是太好用了』,有人说『RxJava 真是太难用了』,另外更多的人表示:我真的百度了也谷歌了,但我还是想问: RxJava 到底是什么? 鉴于 RxJava 目前这种既火爆又神秘的现状,而我又在一年的使用过程中对 RxJava 有了一些理解,我决定写下这篇文章来对 RxJava 做一个相对详细的、针对 Android 开发者的介绍。 这篇文章的目的有两个: 给对 RxJava 感兴趣的人一些入门的指引 给正在使用 RxJava 但仍然心存疑惑的人一些更深入的解析 - [RxJava 到底是什么](http://gank.io/post/560e15be2dca930e00da1083#toc_1) - [RxJava 好在哪](http://gank.io/post/560e15be2dca930e00da1083#toc_2) - [API 介绍和原理简析](http://gank.io/post/560e15be2dca930e00da1083#toc_3) - [1. 概念:扩展的观察者模式](http://gank.io/post/560e15be2dca930e00da1083#toc_4) - [观察者模式](http://gank.io/post/560e15be2dca930e00da1083#toc_5) - [RxJava 的观察者模式](http://gank.io/post/560e15be2dca930e00da1083#toc_6) - [2. 基本实现](http://gank.io/post/560e15be2dca930e00da1083#toc_7) - [1) 创建 Observer](http://gank.io/post/560e15be2dca930e00da1083#toc_8) - [2) 创建 Observable](http://gank.io/post/560e15be2dca930e00da1083#toc_9) - [3) Subscribe (订阅)](http://gank.io/post/560e15be2dca930e00da1083#toc_10) - [4) 场景示例](http://gank.io/post/560e15be2dca930e00da1083#toc_11) - [a. 打印字符串数组](http://gank.io/post/560e15be2dca930e00da1083#toc_12) - [b. 由 id 取得图片并显示](http://gank.io/post/560e15be2dca930e00da1083#toc_13) - [3. 线程控制 —— Scheduler (一)](http://gank.io/post/560e15be2dca930e00da1083#toc_14) - [1) Scheduler 的 API (一)](http://gank.io/post/560e15be2dca930e00da1083#toc_15) - [2) Scheduler 的原理 (一)](http://gank.io/post/560e15be2dca930e00da1083#toc_16) - [4. 变换](http://gank.io/post/560e15be2dca930e00da1083#toc_17) - [1) API](http://gank.io/post/560e15be2dca930e00da1083#toc_18) - [2) 变换的原理:lift()](http://gank.io/post/560e15be2dca930e00da1083#toc_19) - [3) compose: 对 Observable 整体的变换](http://gank.io/post/560e15be2dca930e00da1083#toc_20) - [5. 线程控制:Scheduler (二)](http://gank.io/post/560e15be2dca930e00da1083#toc_21) - [1) Scheduler 的 API (二)](http://gank.io/post/560e15be2dca930e00da1083#toc_22) - [2) Scheduler 的原理(二)](http://gank.io/post/560e15be2dca930e00da1083#toc_23) - [3) 延伸:doOnSubscribe()](http://gank.io/post/560e15be2dca930e00da1083#toc_24) - [RxJava 的适用场景和使用方式](http://gank.io/post/560e15be2dca930e00da1083#toc_25) - [1. 与 Retrofit 的结合](http://gank.io/post/560e15be2dca930e00da1083#toc_26) - [2. RxBinding](http://gank.io/post/560e15be2dca930e00da1083#toc_27) - [3. 各种异步操作](http://gank.io/post/560e15be2dca930e00da1083#toc_28) - [4. RxBus](http://gank.io/post/560e15be2dca930e00da1083#toc_29) - [最后](http://gank.io/post/560e15be2dca930e00da1083#toc_30) - [关于作者:](http://gank.io/post/560e15be2dca930e00da1083#toc_31) - [为什么写这个?](http://gank.io/post/560e15be2dca930e00da1083#toc_32) 在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github: https://github.com/ReactiveX/RxJava https://github.com/ReactiveX/RxAndroid 引入依赖: compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxandroid:1.0.1' (版本号是文章发布时的最新稳定版) ...

2016年1月20日 · 25 分钟 · 天边的星星

Android性能优化典范 – 第4季

Android性能优化典范第4季的课程学习笔记终于在2015年的最后一天完成了,文章共17个段落,包含的内容大致有:优化网络请求的行为,优化安装包的资源文件,优化数据传输的效率,性能优化的几大基础原理等等。因为学习认知水平有限,肯定存在不少理解偏差甚至错误的地方,请多多交流指正! 1)Cachematters for networking 想要使得Android系统上的网络访问操作更加的高效就必须做好网络数据的缓存。这是提高网络访问性能最基础的步骤之一。从手机的缓存中直接读取数据肯定比从网络上获取数据要更加的便捷高效,特别是对于那些会被频繁访问到的数据,需要把这些数据缓存到设备上,以便更加快速的进行访问。 Android系统上关于网络请求的Http Response Cache是默认关闭的,这样会导致每次即使请求的数据内容是一样的也会需要重复被调用执行,效率低下。我们可以通过下面的代码示例开启HttpResponseCache。 开启Http Response Cache之后,Http操作相关的返回数据就会缓存到文件系统上,不仅仅是主程序自己编写的网络请求相关的数据会被缓存,另外引入的library库中的网络相关的请求数据也会被缓存到这个Cache中。 网络请求的场景有可以是普通的http请求,也可以打开某个URL去获取数据,如下图所示: 我们有两种方式来清除HttpResponseCache的缓存数据:第一种方式是缓存溢出的时候删除最旧最老的文件,第二种方式是通过Http返回Header中的Cache-Control字段来进行控制的。如下图所示: 通常来说,HttpResponseCache会缓存所有的返回信息,包括实际的数据与Header的部分.一般情况下,这个Cache会自动根据协议返回Cache-Control的内容与当前缓存的数据量来决定哪些数据应该继续保留,哪些数据应该删除。但是在一些极端的情况下,例如服务器返回的数据没有设置Cache废弃的时间,或者是本地的Cache文件系统与返回的缓存数据有冲突,或者是某些特殊的网络环境导致HttpResponseCache工作异常,在这些情况下就需要我们自己来实现Http的缓存Cache。 实现自定义的http缓存,需要解决两个问题:第一个是实现一个DiskCacheManager,另外一个是制定Cache的缓存策略。关于DiskCacheManager,我们可以扩展Android系统提供的DiskLruCache来实现。而Cache的缓存策略,相对来说复杂一些,我们可能需要把部分JSON数据设计成不能缓存的,另外一些JSON数据设计成可以缓存几天的,把缩略图设计成缓存一两天的等等,为不同的数据类型根据他们的使用特点制定不同的缓存策略。 想要比较好的实现这两件事情,如果全部自己从头开始写会比较繁琐复杂,所幸的是,有不少著名的开源框架帮助我们快速的解决了那些问题。我们可以使用Volly,okHTTP,Picasso来实现网络缓存。 实现好网络缓存之后,我们可以使用Android Studio里面的Network Traffic Tools来查看网络数据的请求与返回情况,另外我们还可以使用AT&T ARO工具来抓取网络数据包进行分析查看。 2)Optimizing Network Request Frequencies 应用程序的一个基础功能是能够保持确保界面上呈现的信息是即时最新的,例如呈现最新的新闻,天气,信息流等等信息。但是,过于频繁的促使手机客户端应用去同步最新的服务器数据会对性能产生很大的负面影响,不仅仅使得CPU不停的在工作,内存,网络流量,电量等等都会持续的被消耗,所以在进行网络请求操作的时候一定要避免多度同步操作。 退到后台的应用为了能够在切换回前台的时候呈现最新的数据,会偷偷在后台不停的做同步的操作。这种行为会带来很严重的问题,首先因为网络请求的行为异常的耗电,其次不停的进行网络同步会耗费很多带宽流量。 为了能够尽量的减少不必要的同步操作,我们需要遵守下面的一些规则: 首先我们要对网络行为进行分类,区分需要立即更新数据的行为和其他可以进行延迟的更新行为,为不同的场景进行差异化处理。 其次要避免客户端对服务器的轮询操作,这样会浪费很多的电量与带宽流量。解决这个问题,我们可以使用Google Cloud Message来对更新的数据进行推送。 然后在某些必须做同步的场景下,需要避免使用固定的间隔频率来进行更新操作,我们应该在返回的数据无更新的时候,使用双倍的间隔时间来进行下一次同步。 最后更进一步,我们还可以通过判断当前设备的状态来决定同步的频率,例如判断设备处于休眠,运动等不同的状态设计各自不同时间间隔的同步频率。 另外,我们还可以通过判断设备是否连接上WiFi,是否正在充电来决定更新的频率。为了能够方便的实现这个功能,Android为我们提供了GCMNetworkManager来判断设备当下的状态,从而设计更加高效的网络同步操作,如下图所示: 3)Effective Prefetching 关于提升网络操作的性能,除了避免频繁的网络同步操作之外,还可以使用捆绑批量访问的方式来减少访问的频率,为了达到这个目的,我们就需要了解Prefetching。 举个例子,在某个场景下,一开始发出了网络请求得到了某张图片,隔了10s之后,发出第二次请求想要拿到另外一张图片,再隔了6s发出第三张图片的网络请求。这会导致设备的无线蜂窝一直处于高消耗的状态。Prefetching就是预先判定那些可能马上就会使用到的网络资源,捆绑一起集中进行网络请求。这样能够极大的减少电量的消耗,提升设备的续航时间。 使用Prefetching的难点在于如何判断事先获取的数据量到底是多少,如果预取的数据量偏少,那么就起不到什么效果,但是如果预取过多,又可能导致访问的时间过长。 那么问题来了,到底预取多少才比较合适呢?一个比较普适的规则是,在3G网络下可以预取1-5Mb的数据量,或者是按照提前预期后续1-2分钟的数据作为基线标准。在实际的操作当中,我们还需要考虑当前的网络速度来决定预取的数据量,例如在同样的时间下,4G网络可以获取到12张图片的数据,而2G网络则只能拿到3张图片的数据。所以,我们还需要把当前的网络环境情况添加到设计预取数据量的策略当中去。判断当前设备的状态与网络情况,可以使用前面提到过的GCMNetworkManager。 4)Adapting to Latency 网络延迟通常来说很容易被用户察觉到,严重的网络延迟会对用户体验造成很大的影响,用户很容易抱怨应用程序写的不好。 一个典型的网络操作行为,通常包含以下几个步骤:首先手机端发起网络请求,到达网络服务运营商的基站,再转移到服务提供者的服务器上,经过解码之后,接着访问本地的存储数据库,获取到数据之后,进行编码,最后按照原来传递的路径逐层返回。如下图所示: 在上面的网络请求链路当中的任何一个环节都有可能导致严重的延迟,成为性能瓶颈,但是这些环节可能出现的问题,客户端应用是无法进行调节控制的,应用能够做的就只是根据当前的网络环境选择当下最佳的策略来降低出现网络延迟的概率。主要的实施步骤有两步:第1步检测收集当前的网络环境信息,第2步根据当前收集到的信息进行网络请求行为的调整。 关于第1步检测当前的网络环境,我们可以使用系统提供的API来获取到相关的信息,如下图所示: 通过上面的示例,我们可以获取到移动网络的详细子类型,例如4G(LTE),3G等等,详细分类见下图,获取到详细的移动网络类型之后,我们可以根据当前网络的速率来调整网络请求的行为: 关于第2步根据收集到的信息进行策略的调整,通常来说,我们可以把网络请求延迟划分为三档:例如把网络延迟小于60ms的划分为GOOD,大于220ms的划分为BAD,介于两者之间的划分为OK(这里的60ms,220ms会需要根据不同的场景提前进行预算推测)。如果网络延迟属于GOOD的范畴,我们就可以做更多比较激进的预取数据的操作,如果网络延迟属于BAD的范畴,我们就应该考虑把当下的网络请求操作Hold住等待网络状况恢复到GOOD的状态再进行处理。 前面提到说60ms,220ms是需要提前自己预测的,可是预测的工作相当复杂。首先针对不同的机器与网络环境,网络延迟的三档阈值都不太一样,出现的概率也不尽相同,我们会需要针对这些不同的用户与设备选择不同的阈值进行差异化处理: Android官方为了帮助我们设计自己的网络请求策略,为我们提供了模拟器的网络流量控制功能来对实际环境进行模拟测量,或者还可以使用AT&T提供的AT&T Network Attenuator来帮助预估网络延迟。 5)Minimizing Asset Payload 为了能够减小网络传输的数据量,我们需要对传输的数据做压缩的处理,这样能够提高网络操作的性能。首先不同的网络环境,下载速度以及网络延迟是存在差异的,如下图所示: ...

2016年1月20日 · 1 分钟 · 天边的星星

在CentOS上安装Java环境:[1]使用yum安装java

现阶段做企业级项目开发一般都采用Java语言。开发的项目需要放在服务器上运行测试,若以CentOS系统为服务器系统,首先要解决就是CentOS系统上的Java环境搭建。 下面由小河给大家分享:如何使用yum方式在CentOS上安装Java环境,系统以CentOS6.4为例。 </div> </div> ## 工具/原料 - <div class="content-list-text"> Java JDK </div> - <div class="content-list-text"> yum库 </div> - <div class="content-list-text"> CentOS6.4 </div> ## 方法/步骤 - <div class="list-icon"> </div> <div class="content-list-text"> 查看CentOS自带JDK是否已安装。 ◆输入:yum list installed |grep java。 </div> <div class="content-list-media"> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://c.hiphotos.baidu.com/exp/w=500/sign=5b030433b01bb0518f24b328067bda77/a1ec08fa513d2697ab9a004c56fbb2fb4316d852.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=1) </div> </div> - <div class="list-icon"> </div> <div class="content-list-text"> 若有自带安装的JDK,如何卸载CentOS系统自带Java环境? ◆卸载JDK相关文件输入:yum -y remove java-1.7.0-openjdk*。 ◆卸载tzdata-java输入:yum -y remove tzdata-java.noarch。 当结果显示为Complete!即卸载完毕。 *注:“*”表示卸载掉java 1.7.0的所有openjdk相关文件。* </div> <div class="content-list-media"> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://d.hiphotos.baidu.com/exp/w=500/sign=047d15191c30e924cfa49c317c096e66/0df3d7ca7bcb0a46f16a83286863f6246b60af52.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=2) </div> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://g.hiphotos.baidu.com/exp/w=500/sign=5596d6e5b44543a9f51bfacc2e168a7b/7af40ad162d9f2d3b1a32cfeaaec8a136327cc75.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=3) </div> </div> - <div class="list-icon"> </div> <div class="content-list-text"> 检查CentOS系统网络连接是否正常。 ◆使用yum方式安装需要连接网络下载Java相应安装文件,故此需要使用ping命令测试网络;如:ping 百度URL即可。 </div> <div class="content-list-media"> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://f.hiphotos.baidu.com/exp/w=500/sign=e95f1515379b033b2c88fcda25cf3620/8c1001e93901213f857b46cd57e736d12f2e9552.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=4) </div> </div> - <div class="list-icon"> </div> <div class="content-list-text"> 查看yum库中的Java安装包。 ◆输入:yum -y list java* 。 </div> <div class="content-list-media"> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://e.hiphotos.baidu.com/exp/w=500/sign=1958e90b2b34349b74066e85f9eb1521/7dd98d1001e939011d4a852f78ec54e736d19652.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=5) </div> </div> - <div class="list-icon"> </div> <div class="content-list-text"> 使用yum安装Java环境。 ◆输入:yum -y install java-1.7.0-openjdk* ,以yum库中java-1.7.0为例。 当结果显示为Complete!即安装完毕。 *注:“*”表示将java-1.7.0的所有相关Java程序都安装上。* </div> <div class="content-list-media"> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://h.hiphotos.baidu.com/exp/w=500/sign=0bee3e1a58b5c9ea62f303e3e538b622/3801213fb80e7bec6b920bf02c2eb9389b506b52.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=6) </div> </div> - <div class="list-icon"> </div> <div class="content-list-text"> 查看刚安装的Java版本信息。 ◆输入:java -version 可查看Java版本; ◆输入:javac 可查看Java的编译器命令用法(可略)。 </div> <div class="content-list-media"> <div class="content-list-image clearfix"> [![在CentOS上安装Java环境:[1]使用yum安装java](http://h.hiphotos.baidu.com/exp/w=500/sign=fd64ae32b37eca80120539e7a1229712/a6efce1b9d16fdfae024ceffb78f8c5494ee7b52.jpg)](http://jingyan.baidu.com/album/4853e1e51d0c101909f72607.html?picindex=7) </div> </div> <div class="last-item"> <span class="last-item-end">END</span> </div> 转自:http://jingyan.baidu.com/article/4853e1e51d0c101909f72607.html

2016年1月18日 · 1 分钟 · 天边的星星

Android获取手机底部虚拟按键高度

获取手机底部虚拟键盘的高度 魅族手机底部SmartBar高度 import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.os.Build; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.view.ViewConfiguration; import android.view.WindowManager; import java.lang.reflect.Field; import java.lang.reflect.Method; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); Log.e(MainActivity.class.getName(), "hasNavBar1 = " + hasNavBar(MainActivity.this)); } }); Log.e(MainActivity.class.getName(),"ScreenHeight = "+getScreenHight()); Log.e(MainActivity.class.getName(),"SmartBarHeight = "+getSmartBarHeight(this)); Log.e(MainActivity.class.getName(),"hasNavBar = "+hasNavBar(this)); Log.e(MainActivity.class.getName(),"getNavigationBarHeight = "+getNavigationBarHeight(this)); } private int getScreenHight(){ // 获取屏幕高 Point point = new Point(); getWindowManager().getDefaultDisplay().getSize(point); int screenHeight = point.y + (isMeizu() ? 0 : getNavigationBarHeight(this)); return screenHeight; } /** * 获取虚拟按键栏高度 * @param context * @return */ public static int getNavigationBarHeight(Context context) { int result = 0; if (hasNavBar(context)){ Resources res = context.getResources(); int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android"); if (resourceId &gt; 0) { result = res.getDimensionPixelSize(resourceId); } } return result; } /** * 检查是否存在虚拟按键栏 * @param context * @return */ private static boolean hasNavBar(Context context) { Resources res = context.getResources(); int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android"); if (resourceId != 0) { boolean hasNav = res.getBoolean(resourceId); // check override flag String sNavBarOverride = getNavBarOverride(); if ("1".equals(sNavBarOverride)) { hasNav = false; } else if ("0".equals(sNavBarOverride)) { hasNav = true; } return hasNav; } else { // fallback return !ViewConfiguration.get(context).hasPermanentMenuKey(); } } /** * 判断虚拟按键栏是否重写 * @return */ private static String getNavBarOverride() { String sNavBarOverride = null; if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.KITKAT) { try { Class c = Class.forName("android.os.SystemProperties"); Method m = c.getDeclaredMethod("get", String.class); m.setAccessible(true); sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys"); } catch (Throwable e) { } } return sNavBarOverride; } /** * 判断是否meizu手机 * @return */ public static boolean isMeizu() { return Build.BRAND.equals("Meizu"); } /** * 获取魅族手机底部虚拟键盘高度 * @param context * @return */ public static int getSmartBarHeight(Context context) { try { Class c = Class.forName("com.android.internal.R$dimen"); Object obj = c.newInstance(); Field field = c.getField("mz_action_button_min_height"); int height = Integer.parseInt(field.get(obj).toString()); return context.getResources().getDimensionPixelSize(height); } catch (Exception e) { e.printStackTrace(); } return 0; } } import java.lang.reflect.Field; <td id="file-smartbarutils-java-LC4" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">java.lang.reflect.InvocationTargetException</span>; </td> <td id="file-smartbarutils-java-LC5" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">java.lang.reflect.Method</span>; </td> <td id="file-smartbarutils-java-LC6" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC7" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.app.ActionBar</span>; </td> <td id="file-smartbarutils-java-LC8" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.content.Context</span>; </td> <td id="file-smartbarutils-java-LC9" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.content.res.Configuration</span>; </td> <td id="file-smartbarutils-java-LC10" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.os.Build</span>; </td> <td id="file-smartbarutils-java-LC11" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.support.v4.app.FragmentActivity</span>; </td> <td id="file-smartbarutils-java-LC12" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.view.View</span>; </td> <td id="file-smartbarutils-java-LC13" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.view.Window</span>; </td> <td id="file-smartbarutils-java-LC14" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">import</span> <span class="pl-smi">android.view.WindowManager</span>; </td> <td id="file-smartbarutils-java-LC15" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC16" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">SmartBarUtils</span> { </td> <td id="file-smartbarutils-java-LC17" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC18" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">final</span> <span class="pl-k">int</span> <span class="pl-c1">SMART_BAR_HEIGH</span> <span class="pl-k">=</span> <span class="pl-c1">96</span>; </td> <td id="file-smartbarutils-java-LC19" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC20" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC21" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 调用 ActionBar.setTabsShowAtBottom(boolean) 方法。 如果</span> </td> <td id="file-smartbarutils-java-LC22" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * android:uiOptions=&#8221;splitActionBarWhenNarrow&#8221;,则可设置ActionBar Tabs显示在底栏。</span> </td> <td id="file-smartbarutils-java-LC23" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC24" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 示例: public class MyActivity extends Activity implements</span> </td> <td id="file-smartbarutils-java-LC25" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * ActionBar.TabListener { protected void onCreate(Bundle</span> </td> <td id="file-smartbarutils-java-LC26" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * savedInstanceState) { super.onCreate(savedInstanceState); &#8230;</span> </td> <td id="file-smartbarutils-java-LC27" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC28" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * final ActionBar bar = getActionBar();</span> </td> <td id="file-smartbarutils-java-LC29" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);</span> </td> <td id="file-smartbarutils-java-LC30" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * SmartBarUtils.setActionBarTabsShowAtBottom(bar, true);</span> </td> <td id="file-smartbarutils-java-LC31" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC32" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * bar.addTab(bar.newTab().setText(&quot;tab1&quot;).setTabListener(this));</span> </td> <td id="file-smartbarutils-java-LC33" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * &#8230; } }</span> </td> <td id="file-smartbarutils-java-LC34" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC35" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC36" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">setActionBarTabsShowAtBottom</span>(<span class="pl-smi">ActionBar</span> <span class="pl-v">actionbar</span>, </td> <td id="file-smartbarutils-java-LC37" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">boolean</span> <span class="pl-v">showAtBottom</span>) { </td> <td id="file-smartbarutils-java-LC38" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC39" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Method</span> method <span class="pl-k">=</span> <span class="pl-smi">Class</span><span class="pl-k">.</span>forName(<span class="pl-s"><span class="pl-pds">&#8220;</span>android.app.ActionBar<span class="pl-pds">&#8220;</span></span>)<span class="pl-k">.</span>getMethod( </td> <td id="file-smartbarutils-java-LC40" class="blob-code blob-code-inner js-file-line"> <span class="pl-s"><span class="pl-pds">&#8220;</span>setTabsShowAtBottom<span class="pl-pds">&#8220;</span></span>, <span class="pl-k">new</span> <span class="pl-smi">Class</span>[] { <span class="pl-k">boolean</span><span class="pl-k">.</span>class }); </td> <td id="file-smartbarutils-java-LC41" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC42" class="blob-code blob-code-inner js-file-line"> method<span class="pl-k">.</span>invoke(actionbar, showAtBottom); </td> <td id="file-smartbarutils-java-LC43" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalArgumentException</span> e) { </td> <td id="file-smartbarutils-java-LC44" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC45" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalAccessException</span> e) { </td> <td id="file-smartbarutils-java-LC46" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC47" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">InvocationTargetException</span> e) { </td> <td id="file-smartbarutils-java-LC48" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC49" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC50" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">SecurityException</span> e) { </td> <td id="file-smartbarutils-java-LC51" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC52" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">NoSuchMethodException</span> e) { </td> <td id="file-smartbarutils-java-LC53" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC54" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">ClassNotFoundException</span> e) { </td> <td id="file-smartbarutils-java-LC55" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC56" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC57" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC58" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC59" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC60" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 调用 ActionBar.setActionBarViewCollapsable(boolean) 方法。</span> </td> <td id="file-smartbarutils-java-LC61" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 设置ActionBar顶栏无显示内容时是否隐藏。</span> </td> <td id="file-smartbarutils-java-LC62" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC63" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 示例:</span> </td> <td id="file-smartbarutils-java-LC64" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC65" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * public class MyActivity extends Activity {</span> </td> <td id="file-smartbarutils-java-LC66" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC67" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * protected void onCreate(Bundle savedInstanceState) {</span> </td> <td id="file-smartbarutils-java-LC68" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * super.onCreate(savedInstanceState); &#8230;</span> </td> <td id="file-smartbarutils-java-LC69" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC70" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * final ActionBar bar = getActionBar();</span> </td> <td id="file-smartbarutils-java-LC71" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC72" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * // 调用setActionBarViewCollapsable,并设置ActionBar没有显示内容,则ActionBar顶栏不显示</span> </td> <td id="file-smartbarutils-java-LC73" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * SmartBarUtils.setActionBarViewCollapsable(bar, true);</span> </td> <td id="file-smartbarutils-java-LC74" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * bar.setDisplayOptions(0); } }</span> </td> <td id="file-smartbarutils-java-LC75" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC76" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">setActionBarViewCollapsable</span>(<span class="pl-smi">ActionBar</span> <span class="pl-v">actionbar</span>, </td> <td id="file-smartbarutils-java-LC77" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">boolean</span> <span class="pl-v">collapsable</span>) { </td> <td id="file-smartbarutils-java-LC78" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC79" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Method</span> method <span class="pl-k">=</span> <span class="pl-smi">Class</span><span class="pl-k">.</span>forName(<span class="pl-s"><span class="pl-pds">&#8220;</span>android.app.ActionBar<span class="pl-pds">&#8220;</span></span>)<span class="pl-k">.</span>getMethod( </td> <td id="file-smartbarutils-java-LC80" class="blob-code blob-code-inner js-file-line"> <span class="pl-s"><span class="pl-pds">&#8220;</span>setActionBarViewCollapsable<span class="pl-pds">&#8220;</span></span>, </td> <td id="file-smartbarutils-java-LC81" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">new</span> <span class="pl-smi">Class</span>[] { <span class="pl-k">boolean</span><span class="pl-k">.</span>class }); </td> <td id="file-smartbarutils-java-LC82" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC83" class="blob-code blob-code-inner js-file-line"> method<span class="pl-k">.</span>invoke(actionbar, collapsable); </td> <td id="file-smartbarutils-java-LC84" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalArgumentException</span> e) { </td> <td id="file-smartbarutils-java-LC85" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC86" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalAccessException</span> e) { </td> <td id="file-smartbarutils-java-LC87" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC88" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">InvocationTargetException</span> e) { </td> <td id="file-smartbarutils-java-LC89" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC90" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC91" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">SecurityException</span> e) { </td> <td id="file-smartbarutils-java-LC92" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC93" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">NoSuchMethodException</span> e) { </td> <td id="file-smartbarutils-java-LC94" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC95" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">ClassNotFoundException</span> e) { </td> <td id="file-smartbarutils-java-LC96" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC97" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC98" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC99" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC100" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC101" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 调用 ActionBar.setActionModeHeaderHidden(boolean) 方法。 设置ActionMode顶栏是否隐藏。</span> </td> <td id="file-smartbarutils-java-LC102" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC103" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * public class MyActivity extends Activity {</span> </td> <td id="file-smartbarutils-java-LC104" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC105" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * protected void onCreate(Bundle savedInstanceState) {</span> </td> <td id="file-smartbarutils-java-LC106" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * super.onCreate(savedInstanceState); &#8230;</span> </td> <td id="file-smartbarutils-java-LC107" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC108" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * final ActionBar bar = getActionBar();</span> </td> <td id="file-smartbarutils-java-LC109" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC110" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * // ActionBar转为ActionMode时,不显示ActionMode顶栏</span> </td> <td id="file-smartbarutils-java-LC111" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * SmartBarUtils.setActionModeHeaderHidden(bar, true); } }</span> </td> <td id="file-smartbarutils-java-LC112" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC113" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">setActionModeHeaderHidden</span>(<span class="pl-smi">ActionBar</span> <span class="pl-v">actionbar</span>, </td> <td id="file-smartbarutils-java-LC114" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">boolean</span> <span class="pl-v">hidden</span>) { </td> <td id="file-smartbarutils-java-LC115" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC116" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Method</span> method <span class="pl-k">=</span> <span class="pl-smi">Class</span><span class="pl-k">.</span>forName(<span class="pl-s"><span class="pl-pds">&#8220;</span>android.app.ActionBar<span class="pl-pds">&#8220;</span></span>)<span class="pl-k">.</span>getMethod( </td> <td id="file-smartbarutils-java-LC117" class="blob-code blob-code-inner js-file-line"> <span class="pl-s"><span class="pl-pds">&#8220;</span>setActionModeHeaderHidden<span class="pl-pds">&#8220;</span></span>, <span class="pl-k">new</span> <span class="pl-smi">Class</span>[] { <span class="pl-k">boolean</span><span class="pl-k">.</span>class }); </td> <td id="file-smartbarutils-java-LC118" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC119" class="blob-code blob-code-inner js-file-line"> method<span class="pl-k">.</span>invoke(actionbar, hidden); </td> <td id="file-smartbarutils-java-LC120" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalArgumentException</span> e) { </td> <td id="file-smartbarutils-java-LC121" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC122" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalAccessException</span> e) { </td> <td id="file-smartbarutils-java-LC123" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC124" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">InvocationTargetException</span> e) { </td> <td id="file-smartbarutils-java-LC125" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC126" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC127" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">SecurityException</span> e) { </td> <td id="file-smartbarutils-java-LC128" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC129" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">NoSuchMethodException</span> e) { </td> <td id="file-smartbarutils-java-LC130" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC131" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">ClassNotFoundException</span> e) { </td> <td id="file-smartbarutils-java-LC132" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC133" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC134" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC135" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC136" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC137" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 原隐藏SmartBar的方法</span> </td> <td id="file-smartbarutils-java-LC138" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 此方法已从Flyme2.4.1开始失效 示例:</span> </td> <td id="file-smartbarutils-java-LC139" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC140" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * final ActionBar actionBar = getActionBar(); SmartBarUtils.hide(this);</span> </td> <td id="file-smartbarutils-java-LC141" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC142" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC143" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">@Deprecated</span> </td> <td id="file-smartbarutils-java-LC144" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">final</span> <span class="pl-k">void</span> <span class="pl-en">hide</span>(<span class="pl-smi">FragmentActivity</span> <span class="pl-v">activity</span>) { </td> <td id="file-smartbarutils-java-LC145" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">ActionBar</span> actionBar <span class="pl-k">=</span> activity<span class="pl-k">.</span>getActionBar(); </td> <td id="file-smartbarutils-java-LC146" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> (actionBar <span class="pl-k">==</span> <span class="pl-c1">null</span>) { </td> <td id="file-smartbarutils-java-LC147" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span>; </td> <td id="file-smartbarutils-java-LC148" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC149" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">Class<? extends <span class="pl-smi">ActionBar</span>></span> <span class="pl-smi">ActionBarClass</span> <span class="pl-k">=</span> actionBar<span class="pl-k">.</span>getClass(); </td> <td id="file-smartbarutils-java-LC150" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Method</span> setTabsShowAtBottom; </td> <td id="file-smartbarutils-java-LC151" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC152" class="blob-code blob-code-inner js-file-line"> setTabsShowAtBottom <span class="pl-k">=</span> <span class="pl-smi">ActionBarClass</span><span class="pl-k">.</span>getMethod( </td> <td id="file-smartbarutils-java-LC153" class="blob-code blob-code-inner js-file-line"> <span class="pl-s"><span class="pl-pds">&#8220;</span>setTabsShowAtBottom<span class="pl-pds">&#8220;</span></span>, <span class="pl-smi">Boolean</span><span class="pl-c1"><span class="pl-k">.</span>TYPE</span>); </td> <td id="file-smartbarutils-java-LC154" class="blob-code blob-code-inner js-file-line"> setTabsShowAtBottom<span class="pl-k">.</span>invoke(activity<span class="pl-k">.</span>getActionBar(), <span class="pl-c1">true</span>); </td> <td id="file-smartbarutils-java-LC155" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">NoSuchMethodException</span> e) { </td> <td id="file-smartbarutils-java-LC156" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC157" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalArgumentException</span> e) { </td> <td id="file-smartbarutils-java-LC158" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC159" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">IllegalAccessException</span> e) { </td> <td id="file-smartbarutils-java-LC160" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC161" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">InvocationTargetException</span> e) { </td> <td id="file-smartbarutils-java-LC162" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC163" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC164" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC165" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC166" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC167" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 以下三个方法原作者为c跳跳(http://weibo.com/u/1698085875),</span> </td> <td id="file-smartbarutils-java-LC168" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 由Shawn(http://weibo.com/linshen2011)在其基础上改进了一种判断SmartBar是否存在的方法,</span> </td> <td id="file-smartbarutils-java-LC169" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 注意该方法反射的接口只存在于2013年6月之后魅族的flyme固件中</span> </td> <td id="file-smartbarutils-java-LC170" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC171" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC172" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC173" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 方法一:uc等在使用的方法(新旧版flyme均有效),</span> </td> <td id="file-smartbarutils-java-LC174" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 此方法需要配合requestWindowFeature(Window.FEATURE_NO_TITLE</span> </td> <td id="file-smartbarutils-java-LC175" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * )使用,缺点是程序无法使用系统actionbar</span> </td> <td id="file-smartbarutils-java-LC176" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC177" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @param decorView</span> </td> <td id="file-smartbarutils-java-LC178" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * window.getDecorView</span> </td> <td id="file-smartbarutils-java-LC179" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC180" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">hide</span>(<span class="pl-smi">View</span> <span class="pl-v">decorView</span>) { </td> <td id="file-smartbarutils-java-LC181" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> (<span class="pl-k">!</span>hasSmartBar()) </td> <td id="file-smartbarutils-java-LC182" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span>; </td> <td id="file-smartbarutils-java-LC183" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC184" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC185" class="blob-code blob-code-inner js-file-line"> @SuppressWarnings(<span class="pl-s"><span class="pl-pds">&#8220;</span>rawtypes<span class="pl-pds">&#8220;</span></span>) </td> <td id="file-smartbarutils-java-LC186" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">Class</span>[] arrayOfClass <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Class</span>[<span class="pl-c1">1</span>]; </td> <td id="file-smartbarutils-java-LC187" class="blob-code blob-code-inner js-file-line"> arrayOfClass[<span class="pl-c1"></span>] <span class="pl-k">=</span> <span class="pl-smi">Integer</span><span class="pl-c1"><span class="pl-k">.</span>TYPE</span>; </td> <td id="file-smartbarutils-java-LC188" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Method</span> localMethod <span class="pl-k">=</span> <span class="pl-smi">View</span><span class="pl-k">.</span>class<span class="pl-k">.</span>getMethod(<span class="pl-s"><span class="pl-pds">&#8220;</span>setSystemUiVisibility<span class="pl-pds">&#8220;</span></span>, </td> <td id="file-smartbarutils-java-LC189" class="blob-code blob-code-inner js-file-line"> arrayOfClass); </td> <td id="file-smartbarutils-java-LC190" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Field</span> localField <span class="pl-k">=</span> <span class="pl-smi">View</span><span class="pl-k">.</span>class </td> <td id="file-smartbarutils-java-LC191" class="blob-code blob-code-inner js-file-line"> .getField(<span class="pl-s"><span class="pl-pds">&#8220;</span>SYSTEM_UI_FLAG_HIDE_NAVIGATION<span class="pl-pds">&#8220;</span></span>); </td> <td id="file-smartbarutils-java-LC192" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">Object</span>[] arrayOfObject <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Object</span>[<span class="pl-c1">1</span>]; </td> <td id="file-smartbarutils-java-LC193" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC194" class="blob-code blob-code-inner js-file-line"> arrayOfObject[<span class="pl-c1"></span>] <span class="pl-k">=</span> localField<span class="pl-k">.</span>get(<span class="pl-c1">null</span>); </td> <td id="file-smartbarutils-java-LC195" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">Exception</span> e) { </td> <td id="file-smartbarutils-java-LC196" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC197" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC198" class="blob-code blob-code-inner js-file-line"> localMethod<span class="pl-k">.</span>invoke(decorView, arrayOfObject); </td> <td id="file-smartbarutils-java-LC199" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span>; </td> <td id="file-smartbarutils-java-LC200" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">Exception</span> e) { </td> <td id="file-smartbarutils-java-LC201" class="blob-code blob-code-inner js-file-line"> e<span class="pl-k">.</span>printStackTrace(); </td> <td id="file-smartbarutils-java-LC202" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC203" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC204" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC205" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC206" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 方法二:此方法需要配合requestWindowFeature(Window.FEATURE_NO_TITLE)使用</span> </td> <td id="file-smartbarutils-java-LC207" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * ,缺点是程序无法使用系统actionbar</span> </td> <td id="file-smartbarutils-java-LC208" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC209" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @param context</span> </td> <td id="file-smartbarutils-java-LC210" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @param window</span> </td> <td id="file-smartbarutils-java-LC211" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC212" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">hide</span>(<span class="pl-smi">Context</span> <span class="pl-v">context</span>, <span class="pl-smi">Window</span> <span class="pl-v">window</span>) { </td> <td id="file-smartbarutils-java-LC213" class="blob-code blob-code-inner js-file-line"> hide(context, window, <span class="pl-c1"></span>); </td> <td id="file-smartbarutils-java-LC214" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC215" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC216" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">private</span> <span class="pl-k">static</span> <span class="pl-k">int</span> <span class="pl-en">getStatusBarHeight</span>(<span class="pl-smi">Context</span> <span class="pl-v">context</span>) { </td> <td id="file-smartbarutils-java-LC217" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">int</span> result <span class="pl-k">=</span> <span class="pl-c1"></span>; </td> <td id="file-smartbarutils-java-LC218" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">int</span> resourceId <span class="pl-k">=</span> context<span class="pl-k">.</span>getResources()<span class="pl-k">.</span>getIdentifier( </td> <td id="file-smartbarutils-java-LC219" class="blob-code blob-code-inner js-file-line"> <span class="pl-s"><span class="pl-pds">&#8220;</span>status_bar_height<span class="pl-pds">&#8220;</span></span>, <span class="pl-s"><span class="pl-pds">&#8220;</span>dimen<span class="pl-pds">&#8220;</span></span>, <span class="pl-s"><span class="pl-pds">&#8220;</span>android<span class="pl-pds">&#8220;</span></span>); </td> <td id="file-smartbarutils-java-LC220" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> (resourceId <span class="pl-k">></span> <span class="pl-c1"></span>) { </td> <td id="file-smartbarutils-java-LC221" class="blob-code blob-code-inner js-file-line"> result <span class="pl-k">=</span> context<span class="pl-k">.</span>getResources()<span class="pl-k">.</span>getDimensionPixelSize(resourceId); </td> <td id="file-smartbarutils-java-LC222" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC223" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span> result; </td> <td id="file-smartbarutils-java-LC224" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC225" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC226" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC227" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 方法三:需要使用顶部actionbar的应用请使用此方法</span> </td> <td id="file-smartbarutils-java-LC228" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * </span> </td> <td id="file-smartbarutils-java-LC229" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @param context</span> </td> <td id="file-smartbarutils-java-LC230" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @param window</span> </td> <td id="file-smartbarutils-java-LC231" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @param smartBarHeight</span> </td> <td id="file-smartbarutils-java-LC232" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * set SmartBarUtils.SMART_BAR_HEIGHT_PIXEL</span> </td> <td id="file-smartbarutils-java-LC233" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC234" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">hide</span>(<span class="pl-smi">Context</span> <span class="pl-v">context</span>, <span class="pl-smi">Window</span> <span class="pl-v">window</span>, <span class="pl-k">int</span> <span class="pl-v">smartBarHeight</span>) { </td> <td id="file-smartbarutils-java-LC235" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> (<span class="pl-k">!</span>hasSmartBar()) { </td> <td id="file-smartbarutils-java-LC236" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span>; </td> <td id="file-smartbarutils-java-LC237" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC238" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> (context<span class="pl-k">.</span>getResources()<span class="pl-k">.</span>getConfiguration()<span class="pl-k">.</span>orientation <span class="pl-k">==</span> <span class="pl-smi">Configuration</span><span class="pl-c1"><span class="pl-k">.</span>ORIENTATION_LANDSCAPE</span>) { </td> <td id="file-smartbarutils-java-LC239" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span>; </td> <td id="file-smartbarutils-java-LC240" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC241" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC242" class="blob-code blob-code-inner js-file-line"> window<span class="pl-k">.</span>setFlags(<span class="pl-smi">WindowManager</span><span class="pl-k">.</span><span class="pl-smi">LayoutParams</span><span class="pl-c1"><span class="pl-k">.</span>FLAG_FULLSCREEN</span>, </td> <td id="file-smartbarutils-java-LC243" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">WindowManager</span><span class="pl-k">.</span><span class="pl-smi">LayoutParams</span><span class="pl-c1"><span class="pl-k">.</span>FLAG_FULLSCREEN</span>); </td> <td id="file-smartbarutils-java-LC244" class="blob-code blob-code-inner js-file-line"> window<span class="pl-k">.</span>addFlags(<span class="pl-smi">WindowManager</span><span class="pl-k">.</span><span class="pl-smi">LayoutParams</span><span class="pl-c1"><span class="pl-k">.</span>FLAG_FORCE_NOT_FULLSCREEN</span>); </td> <td id="file-smartbarutils-java-LC245" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">int</span> statusBarHeight <span class="pl-k">=</span> getStatusBarHeight(context); </td> <td id="file-smartbarutils-java-LC246" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC247" class="blob-code blob-code-inner js-file-line"> window<span class="pl-k">.</span>getDecorView() </td> <td id="file-smartbarutils-java-LC248" class="blob-code blob-code-inner js-file-line"> .setPadding(<span class="pl-c1"></span>, statusBarHeight, <span class="pl-c1"></span>, <span class="pl-k">&#8211;</span>smartBarHeight); </td> <td id="file-smartbarutils-java-LC249" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC250" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC251" class="blob-code blob-code-inner js-file-line"> <span class="pl-c">/**</span> </td> <td id="file-smartbarutils-java-LC252" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * 新型号可用反射调用Build.hasSmartBar()来判断有无SmartBar</span> </td> <td id="file-smartbarutils-java-LC253" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> * @return</span> </td> <td id="file-smartbarutils-java-LC254" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"> */</span> </td> <td id="file-smartbarutils-java-LC255" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">boolean</span> <span class="pl-en">hasSmartBar</span>() { </td> <td id="file-smartbarutils-java-LC256" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span> { </td> <td id="file-smartbarutils-java-LC257" class="blob-code blob-code-inner js-file-line"> <span class="pl-smi">Method</span> method <span class="pl-k">=</span> <span class="pl-smi">Class</span><span class="pl-k">.</span>forName(<span class="pl-s"><span class="pl-pds">&#8220;</span>android.os.Build<span class="pl-pds">&#8220;</span></span>)<span class="pl-k">.</span>getMethod( </td> <td id="file-smartbarutils-java-LC258" class="blob-code blob-code-inner js-file-line"> <span class="pl-s"><span class="pl-pds">&#8220;</span>hasSmartBar<span class="pl-pds">&#8220;</span></span>); </td> <td id="file-smartbarutils-java-LC259" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span> ((<span class="pl-smi">Boolean</span>) method<span class="pl-k">.</span>invoke(<span class="pl-c1">null</span>))<span class="pl-k">.</span>booleanValue(); </td> <td id="file-smartbarutils-java-LC260" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">catch</span> (<span class="pl-smi">Exception</span> e) { </td> <td id="file-smartbarutils-java-LC261" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC262" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC263" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> (<span class="pl-smi">Build</span><span class="pl-c1"><span class="pl-k">.</span>DEVICE</span><span class="pl-k">.</span>equals(<span class="pl-s"><span class="pl-pds">&#8220;</span>mx2<span class="pl-pds">&#8220;</span></span>)) { </td> <td id="file-smartbarutils-java-LC264" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span> <span class="pl-c1">true</span>; </td> <td id="file-smartbarutils-java-LC265" class="blob-code blob-code-inner js-file-line"> } <span class="pl-k">else</span> <span class="pl-k">if</span> (<span class="pl-smi">Build</span><span class="pl-c1"><span class="pl-k">.</span>DEVICE</span><span class="pl-k">.</span>equals(<span class="pl-s"><span class="pl-pds">&#8220;</span>mx<span class="pl-pds">&#8220;</span></span>) <span class="pl-k">||</span> <span class="pl-smi">Build</span><span class="pl-c1"><span class="pl-k">.</span>DEVICE</span><span class="pl-k">.</span>equals(<span class="pl-s"><span class="pl-pds">&#8220;</span>m9<span class="pl-pds">&#8220;</span></span>)) { </td> <td id="file-smartbarutils-java-LC266" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span> <span class="pl-c1">false</span>; </td> <td id="file-smartbarutils-java-LC267" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC268" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span> <span class="pl-c1">false</span>; </td> <td id="file-smartbarutils-java-LC269" class="blob-code blob-code-inner js-file-line"> } </td> <td id="file-smartbarutils-java-LC270" class="blob-code blob-code-inner js-file-line"> </td> <td id="file-smartbarutils-java-LC271" class="blob-code blob-code-inner js-file-line"> } </td>

2016年1月15日 · 16 分钟 · 天边的星星

在低版本android系统上实现Material design应用

Material Design真的很好看,动画效果真的很实用。前面也写了一些文章介绍如何编写Material风格的程序,但是很多都是一些新的api,低版本上面没有这些api,我们没办法使用。但是不用气馁,google官方,以及一些大牛,给我们提供了一些程序,让我们在低版本上面可以实现Material风格的程序,这里就给大家介绍一下。 妹子图截屏 使用support library 使用support library最新的版本,appcomt21,可以在较低版本上面实现部分风格,在之前的文章我已经说过了,这里在系统的说一下。 应用主题 这部分的话之前的文章说过,链接在这里: http://blog.isming.me/2014/10/18/creating-android-app-with-material-design-one-theme/ 使用gralde进行构建的话,在依赖中添加v7包: [?](http://www.open-open.com/lib/view/open1416277425289.html#) <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="gutter"> <div class="line number1 index0 alt2"> 1 </div> <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> <div class="line number4 index3 alt1"> 4 </div> <div class="line number5 index4 alt2"> 5 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `dependencies {` </div> <div class="line number2 index1 alt1"> `compile ``'com.android.support:appcompat-v7:21.0.+'` </div> <div class="line number3 index2 alt2"> `compile ``'com.android.support:cardview-v7:21.0.+'` </div> <div class="line number4 index3 alt1"> `compile ``'com.android.support:recyclerview-v7:21.0.+'` </div> <div class="line number5 index4 alt2"> `}` </div> </div> </td> </tr> </table> 使用eclipse构建的话,加入最新的appcompat包即可。 ...

2016年1月5日 · 5 分钟 · 天边的星星

Material Designer的低版本兼容实现——View & Animation

Material Designer 宗旨:让不同大小不同用途的设备上拥有同一种设计风格 1.纸张 这种设计模式大量参考了纸墨的模式,将空间变得像纸张一样,而用户的手指就是毛笔。用户按到控件上就会产生墨晕效果。这样的好处是明确的告诉用户是否点击了控件,而且还能让用户一下子明白控件的布局思路。毕竟一张一张的纸叠加起来的控件是很容易让人接受的。这里还有一个词“引喻”,虽然控件像纸张,但是它具有变大变小,改变颜色等能力,所以完全可以不用拘泥于现实纸张。 2.深度 新的设计中希望所有的控件都是现实世界中的隐喻,比如你按下按钮,按钮就应该有被按下的状态,这里就要用到了涟漪(Ripple)效果了。其实涟漪效果是来表示你手指按上去后墨晕扩散的效果的,下面的图能很明白的说明这点。 3.动画 动画贯穿于Material Designer之中,官方文档中用了很大的篇幅来讲解动画效果,希望让设计的动画效果很美观。但我个人认为为了动画而动画是完全不可取的,比如下面的例子 这里的动画看起来十分自然和美观,但是在实际中用户切换activity是很常见的,如果经常出现这个动画用户会觉得“很腻”,十分不友好。动画其实是一个画龙点睛的东西,万不可变为画蛇添足。那么,上图的这个动画应该在什么时候使用呢?用在第一次用户进入一个新的界面的时候,我们为了凸显这个界面的某种特定功能,就可以让这个功能的图标动起来,表现出一个点我试试的效果。 4.排版 新的设计里面很在意排版,里面列出了很多详细的数据来支持我们的设计。对于留白也有了详细的说明。优秀的排班会让你的应用看起来干净,优雅,这点十分重要。在之后的文章中我也会多少说到这方面的知识。 设计文档(不用FQ) http://design.1sters.com/ http://www.ui.cn/Material/ 目录 Material Designer的低版本兼容实现(二)—— Theme{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(三)——Color{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(四)—— ToolBar{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(五)—— ActivityOptionsCompat{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(六)—— Ripple Layout{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(七)—— Rectange Button{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(八)—— Flat Button{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(九)—— Float Button & Small Float Button{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(十)—— CheckBox & RadioButton{#cb_post_title_url.postTitle2} Material Designer的低版本兼容实现(十一)—— Switch{#cb_post_title_url.postTitle2} ...

2016年1月5日 · 1 分钟 · 天边的星星

Android 增强版百分比布局库 为了适配而扩展

一 概述 上周一我们发布了[Android 百分比布局库(percent-support-lib) 解析与扩展][1]中对percent-support这个库进行了解析和添加了PercentLinearLayout的支持。 那么为什么本篇博客的存在的意义是什么呢? 首先我们回顾下百分比布局库的用法,提供了PercentRelativeLayout、PercentFrameLayout供大家在编写的时候,对于以下属性: layout_widthPercent、layout_heightPercent、 layout_marginPercent、layout_marginLeftPercent、 layout_marginTopPercent、layout_marginRightPercent、 layout_marginBottomPercent、layout_marginStartPercent、layout_marginEndPercent。 可以使用百分比进行设置宽、高、边距,的确给我们在适配上提供了极大的便利,但是在使用过程中,觉得存在一些场景无法得到满足。什么场景呢?下面我举几个例子。 当使用图片时,无法设置宽高的比例 比如我们的图片宽高是200*100的,我们在使用过程中我们设置宽高为20%、10%,这样会造成图片的比例失调。为什么呢?因为20%参考的是屏幕的宽度,而10%参考的是屏幕的高度。 很难使用百分比定义一个正方形的控件 比如,我现在界面的右下角有一个FloatingActionButton,我希望其宽度和高度都为屏幕宽度的10%,很难做到。 一个控件的margin四个方向值一致 有些时候,我设置margin,我希望四边的边距一致的,但是如果目前设置5%,会造成,上下为高度的5%,左右边距为宽度的5%。 综合上述这些问题,可以发现目前的percent-support-lib并不能完全满足我们的需求,所以我们考虑对其进行扩展。说白了,我们就希望在布局的时候可以自己设定参考看度还是高度,比如上述2,我们对于宽高可以写成10%w,10%w。也就是在不改变原库的用法的前提下,添加一些额外的支持。 二 扩展的功能 目前我初步对该库进行了改写,github地址:[android-percent-support-extend][2],对于官方库,做了如下的改变: 不改变原有库的用法 添加了PercentLinearLayout 支持百分比指定特定的参考值,比如宽度或者高度。 例如:app:layout_heightPercent="50%w", app:layout_marginPercent="15%w", app:layout_marginBottomPercent="20%h". 支持通过app:layout_textSizePercent设置textView的textSize 对于外层套ScrollView的问题,目前可以在PercentLinearLayout的外层使用ScrollView,不过对于宽度的百分比参考的就是android.R.id.content的高度(因为,无法参考父控件的高度,父控件的高度理论上依赖于子View高度,且模式为UNSPECIFIED)。 对于如何导入,也是相当的简单,android studio的用户,直接: ``` dependencies { //... compile 'com.zhy:percent-support-extends:1.0.1' } - 1 - 2 - 3 - 4 - 5 不需要导入官方的percent-support-lib了。 对于的三个类分别为: ``` `com.zhy.android.percent.support.PercentLinearLayout com.zhy.android.percent.support.PercentRelativeLayout com.zhy.android.percent.support.PercentFrameLayout` - 1 - 2 - 3 对于eclipse的用户:github上自行下载源码,就几个类和一个attrs.xml,也可以在[bintray.com/percent-support-extends][3] 下载相关文件。 下面看几个具体的示例。 * * * ### <a name="t2"></a>三 具体的示例 {#三-具体的示例} #### <a name="t3"></a>Demo 1 {#demo-1} ...

2015年12月26日 · 9 分钟 · 天边的星星

StrictMode 详解

StrictMode类是Android 2.3 (API 9)引入的一个工具类,可以用来帮助开发者发现代码中的一些不规范的问题。比如,如果你在UI线程中进行了网络或者磁盘操作,StrictMode就会通过Log(logcat )或者对话框的方式把信息提示给你,因为让你的UI线程处理这里操作会被认为是不规范的做法,可能会让你的应用变得比较卡顿。 官网文档:http://developer.android.com/reference/android/os/StrictMode.html 如何启用 StrictMode 我们通常在 Activity 或者自定义的Application类中启动 StrictMode,代码如下: ``` ` <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">()</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">DEVELOPER_MODE</span><span class="o">)</span> <span class="o">{</span> <span class="n">StrictMode</span><span class="o">.</span><span class="na">setThreadPolicy</span><span class="o">(</span><span class="k">new</span> <span class="n">StrictMode</span><span class="o">.</span><span class="na">ThreadPolicy</span><span class="o">.</span><span class="na">Builder</span><span class="o">()</span> <span class="o">.</span><span class="na">detectDiskReads</span><span class="o">()</span> <span class="o">.</span><span class="na">detectDiskWrites</span><span class="o">()</span> <span class="o">.</span><span class="na">detectNetwork</span><span class="o">()</span> <span class="c1">// or .detectAll() for all detectable problems</span> <span class="o">.</span><span class="na">penaltyLog</span><span class="o">()</span> <span class="o">.</span><span class="na">build</span><span class="o">());</span> <span class="n">StrictMode</span><span class="o">.</span><span class="na">setVmPolicy</span><span class="o">(</span><span class="k">new</span> <span class="n">StrictMode</span><span class="o">.</span><span class="na">VmPolicy</span><span class="o">.</span><span class="na">Builder</span><span class="o">()</span> <span class="o">.</span><span class="na">detectLeakedSqlLiteObjects</span><span class="o">()</span> <span class="o">.</span><span class="na">detectLeakedClosableObjects</span><span class="o">()</span> <span class="o">.</span><span class="na">penaltyLog</span><span class="o">()</span> <span class="o">.</span><span class="na">penaltyDeath</span><span class="o">()</span> <span class="o">.</span><span class="na">build</span><span class="o">());</span> <span class="o">}</span> <span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">();</span> <span class="o">}</span> ` ``` **注意:**我们只需要在app的开发版本下使用 StrictMode,线上版本避免使用 StrictMode,随意需要通过 诸如 DEVELOPER_MODE 这样的配置变量来进行控制。 下面我们举几个例子来说明 StrictMode 是如何发挥作用的。 代码1: ``` `<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ActivitySimple</span> <span class="kd">extends</span> <span class="n">Activity</span> <span class="o">{</span> &lt;span class="nd">@Override&lt;/span> &lt;span class="kd">protected&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">onCreate&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="n">Bundle&lt;/span> &lt;span class="n">savedInstanceState&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">{&lt;/span> &lt;span class="kd">super&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">onCreate&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="n">savedInstanceState&lt;/span>&lt;span class="o">);&lt;/span> &lt;span class="n">setContentView&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">layout&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">activity_main&lt;/span>&lt;span class="o">);&lt;/span> &lt;span class="n">StrictMode&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">setThreadPolicy&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="k">new&lt;/span> &lt;span class="n">ThreadPolicy&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">Builder&lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="o">.&lt;/span>&lt;span class="na">detectAll&lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="o">.&lt;/span>&lt;span class="na">penaltyDialog&lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="c1">//弹出违规提示对话框&lt;/span> &lt;span class="o">.&lt;/span>&lt;span class="na">penaltyLog&lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="c1">//在Logcat 中打印违规异常信息&lt;/span> &lt;span class="o">.&lt;/span>&lt;span class="na">build&lt;/span>&lt;span class="o">());&lt;/span> &lt;span class="k">this&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">testNetwork&lt;/span>&lt;span class="o">();&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="kd">private&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">testNetwork&lt;/span>&lt;span class="o">()&lt;/span> &lt;span class="o">{&lt;/span> &lt;span class="k">try&lt;/span> &lt;span class="o">{&lt;/span> &lt;span class="n">URL&lt;/span> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">URL&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="s">"http://www.baidu.com"&lt;/span>&lt;span class="o">);&lt;/span> &lt;span class="n">HttpURLConnection&lt;/span> &lt;span class="n">conn&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="n">HttpURLConnection&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="n">url&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">openConnection&lt;/span>&lt;span class="o">();&lt;/span> &lt;span class="n">conn&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">connect&lt;/span>&lt;span class="o">();&lt;/span> &lt;span class="n">BufferedReader&lt;/span> &lt;span class="n">reader&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">BufferedReader&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="k">new&lt;/span> &lt;span class="n">InputStreamReader&lt;/span>&lt;span class="o">(&lt;/span> &lt;span class="n">conn&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">getInputStream&lt;/span>&lt;span class="o">()));&lt;/span> &lt;span class="n">String&lt;/span> &lt;span class="n">lines&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="o">;&lt;/span> &lt;span class="n">StringBuffer&lt;/span> &lt;span class="n">sb&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">StringBuffer&lt;/span>&lt;span class="o">();&lt;/span> &lt;span class="k">while&lt;/span> &lt;span class="o">((&lt;/span>&lt;span class="n">lines&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">reader&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">readLine&lt;/span>&lt;span class="o">())&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">{&lt;/span> &lt;span class="n">sb&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">append&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="n">lines&lt;/span>&lt;span class="o">);&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="n">Exception&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="o">{&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="na">printStackTrace&lt;/span>&lt;span class="o">();&lt;/span> &lt;span class="o">}&lt;/span> &lt;span class="o">}&lt;/span> <span class=“o”>}</span> ` ...

2015年12月16日 · 10 分钟 · 天边的星星

EventBus源码研读

摘要 转载:http://kymjs.com/code/2015/12/12/01 本文总共分三部分,从源码角度分析了 EventBus 库。以及介绍了其内部实现注册、发送、响应、取消注册的原理。 EventBus 是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent, Handler, BroadCast 在 Fragment,Activity,Service,线程之间传递消息.优点是开销小,使用方便,可以很大程度上降低它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。 类似的库还有 Otto ,今天就带大家一起研读 EventBus 的源码. 在写这篇文章之前,我已经将本文相关的中文注释代码上传到了GitHub:https://github.com/kymjs/EventBus 基础用法 在读代码之前,首先你得了解它的基本用法.如果你已经能够很熟练的使用EventBus等事件总线库了,那么你可以跳过本节. 首先引入依赖包,查看GitHub主页的说明: https://github.com/greenrobot/EventBus 在Gradle文件加入 compile 'de.greenrobot:eventbus:2.4.0' 用法与广播相同,且比广播更简单: 注册订阅者 首先你需要注册一个事件订阅者,为了方便理解你可以把他当成广播的广播接收者 你可以在任何一个类中使用如下代码注册以及解除注册 ``` `<span class="c1"><span class="hljs-comment">//把当前类注册为订阅者(接收者)</span></span> <span class="n">EventBus</span><span class="o">.</span><span class="na">getDefault</span><span class="o">().</span><span class="na">register</span><span class="o">(</span><span class="k"><span class="hljs-keyword">this</span></span><span class="o">);</span> <span class=“c1”><span class=“hljs-comment”>//解除注册当前类(同广播一样,一定要调用,否则会内存泄露)</span></span> <span class=“n”>EventBus</span><span class=“o”>.</span><span class=“na”>getDefault</span><span class=“o”>().</span><span class=“na”>unregister</span><span class=“o”>(</span><span class=“k”><span class=“hljs-keyword”>this</span></span><span class=“o”>);</span>` </div> 注册了订阅者以后,我们需要创建一个回调方法`onEvent`,当我们订阅的事件发送的时候就会回调它 <div class="highlight"> &lt;span class="c1">&lt;span class="hljs-comment">//其实命名不一定必须是onEvent(),但那属于高级用法了,这里我们只说最简单的&lt;/span>&lt;/span> &lt;span class="kd">&lt;span class="hljs-function">&lt;span class="hljs-keyword">public&lt;/span>&lt;/span>&lt;/span> &lt;span class="kt">&lt;span class="hljs-function">&lt;span class="hljs-keyword">void&lt;/span>&lt;/span>&lt;/span> &lt;span class="nf">&lt;span class="hljs-function">&lt;span class="hljs-title">onEvent&lt;/span>&lt;/span>&lt;/span>&lt;span class="o">&lt;span class="hljs-function">&lt;span class="hljs-params">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="n">&lt;span class="hljs-function">&lt;span class="hljs-params">Object&lt;/span>&lt;/span>&lt;/span> &lt;span class="n">&lt;span class="hljs-function">&lt;span class="hljs-params">event&lt;/span>&lt;/span>&lt;/span>&lt;span class="o">&lt;span class="hljs-function">&lt;span class="hljs-params">)&lt;/span>&lt;/span>&lt;/span> &lt;span class="o">{}&lt;/span> ...

2015年12月16日 · 15 分钟 · 天边的星星

android 源码角度全方位理解filter 及简单使用

写一个listview容易,写一个adapter容易,自己new一个线程过滤数据也容易,但是如何将过滤的效率发挥到最大化,不得不提一下android自带的filter类。 有同学肯定要问,过滤数据自己写一个完全没问题,为什么要用android自带的filter类?我原来也是自己写线程过滤,然而最近项目中遇到一个低配机,双核0.8GCPU,过滤效果实在是卡顿厉害,优化起见,使用了android内部filter试一下效果,结果真是比自己写的好用,于是认真学习了下源码,从头至尾备忘如下: ![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif) ![复制代码](http://common.cnblogs.com/images/copycode.gif) ``` private static final String LOG_TAG = “Filter”; private static final String THREAD_NAME = "Filter"; private static final int FILTER_TOKEN = 0xD0D0F00D; private static final int FINISH_TOKEN = 0xDEADBEEF; private Handler mThreadHandler; private Handler mResultHandler; private Delayer mDelayer; private final Object mLock = new Object(); <div class="cnblogs_code_toolbar"> <span class="cnblogs_code_copy"><a title="复制代码">![复制代码](http://common.cnblogs.com/images/copycode.gif)</a></span> </div> </div> </div> 其实用到的全局变量只有8个,并且有一半是常量:两个handler,一个delayer,一个对象锁。google开发大牛用这几个变量加上为数不多的几个局部变量就做出来了一个拓展性极佳的过滤器,不得不让人钦佩。 首先看构造方法: <div class="cnblogs_code"> ![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif) <div id="cnblogs_code_open_c440c2da-b7c0-476f-bacb-a745b6a72f88" class="cnblogs_code_hide"> ``` public Filter() { mResultHandler = new ResultsHandler(); } 构造方法中二小强之一——ResultsHandler已经被创建了,顾名思义处理过滤操作结果。我们看看这个类的定义: ...

2015年12月4日 · 5 分钟 · 天边的星星