Android ImageCropper 矩形 圆形 裁剪框

支持圆形裁剪框,裁剪后生成圆形图案。 代码基于开源项目修改,github上项目链接:https://github.com/shengge/android-crop 还是贴下效果图: 说一下圆形裁剪实现部分: 1.UI方面,自定义CircleHighlightView继承至HighlightView(原有的矩形裁剪框实现),直接看draw方法实现 **[java]** [view plain](http://blog.csdn.net/jiantao_yang/article/details/43635581#) [copy](http://blog.csdn.net/jiantao_yang/article/details/43635581#) <div> <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1"> </embed> </div> <span class="tracking-ad" data-mod="popu_167">[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/600342)</span><span class="tracking-ad" data-mod="popu_170">[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/600342/fork)</span></div> </div> - <span class="annotation">@Override</span> - <span class="keyword">protected</span> <span class="keyword">void</span> draw(Canvas canvas) { - canvas.save(); - Path path = <span class="keyword">new</span> Path(); - outlinePaint.setStrokeWidth( outlineWidth); - <span class="keyword">if</span>(!hasFocus()) {<span class="comment">//没焦点是,直接画一个黑色的矩形框</span> - outlinePaint.setColor( Color.BLACK); - canvas.drawRect( drawRect, outlinePaint); - } - <span class="keyword">else</span> { - Rect viewDrawingRect = <span class="keyword">new</span> Rect(); - viewContext.getDrawingRect( viewDrawingRect); - - <span class="comment">//已裁剪框drawRect,算出圆的半径</span> - <span class="comment">//添加一个圆形</span> - path.addCircle( drawRect.left + radius, drawRect.top + radius, radius, Direction.CW); - outlinePaint.setColor( highlightColor); - - <span class="comment">//裁剪画布,path之外的区域,以outsidePaint填充</span> - canvas.clipPath( path, Region.Op.DIFFERENCE); - canvas.drawRect( viewDrawingRect, outsidePaint); - - canvas.restore(); - <span class="comment">//绘制圆上高亮线,这里outlinePaint定义的Paint.Style.STROKE:表示只绘制几何图形的轮廓。</span> - canvas.drawPath( path, outlinePaint); - - <span class="comment">//当modifyMode为grow时,绘制handles,也就是那四个小圆</span> - <span class="keyword">if</span>(handleMode == HandleMode.Always || (handleMode == HandleMode.Changing && modifyMode == ModifyMode.Grow)) { - drawHandles( canvas); - } - } - } </div> 这里就实现了画圆形裁剪框的操作。 ### <a name="t1"></a>2. 响应和处理用户触摸事件 #### <a name="t2"></a>1). 判断触摸点坐标与圆的位置 <div> </div> <div> <div class="dp-highlighter bg_java"> <div class="bar"> <div class="tools"> **[java]** [view plain](http://blog.csdn.net/jiantao_yang/article/details/43635581#)<span class="tracking-ad" data-mod="popu_168"><span class="tracking-ad" data-mod="popu_168"> [copy](http://blog.csdn.net/jiantao_yang/article/details/43635581#)</span></span> <div> <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2"> </embed> </div> <span class="tracking-ad" data-mod="popu_167">[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/600342)</span><span class="tracking-ad" data-mod="popu_170">[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/600342/fork)</span></div> </div> - <span class="comment">/**</span> - <span class="comment"> * 根据x,y坐标,计算其与圆的关系(圆上、圆内、圆外)</span> - <span class="comment"> * @param x</span> - <span class="comment"> * @param y</span> - <span class="comment"> * @return</span> - <span class="comment"> */</span> - <span class="keyword">private</span> <span class="keyword">int</span> getHitOnCircle(<span class="keyword">float</span> x, <span class="keyword">float</span> y) { - Rect r = computeLayout(); - <span class="keyword">int</span> retval = GROW_NONE; - <span class="keyword">final</span> <span class="keyword">float</span> hysteresis = 20F; - - <span class="keyword">int</span> centerX = r.left + radius; - <span class="keyword">int</span> centerY = r.top + radius; - - <span class="comment">//判断触摸位置是否在圆上</span> - <span class="keyword">double</span> rRadius = Math.sqrt( ret); - - <span class="keyword">if</span>(gap <= hysteresis) {<span class="comment">// 圆上。这里由于是继承至HighlightView(绘制矩形框的)来处理,所以模拟返回了左右上下,而非纯圆上,亲测可用。你也可以自定义。</span> - <span class="keyword">if</span>(x < centerX) {<span class="comment">// left</span> - retval |= GROW_LEFT_EDGE; - } - <span class="keyword">else</span> { - retval |= GROW_RIGHT_EDGE; - } - - <span class="keyword">if</span>(y < centerY) {<span class="comment">// up</span> - retval |= GROW_TOP_EDGE; - } - <span class="keyword">else</span> { - retval |= GROW_BOTTOM_EDGE; - } - } - <span class="keyword">else</span> <span class="keyword">if</span>(rRadius > radius) {<span class="comment">// outside</span> - retval = GROW_NONE; - } - <span class="keyword">else</span> <span class="keyword">if</span>(rRadius < radius) {<span class="comment">// inside,圆内就执行move</span> - retval = MOVE; - } - - <span class="keyword">return</span> retval; - } </div> 由于是继承至HighLightView(矩形框)来实现的,如果点(x,y)位置圆上,还需判断其它那个象限,对应矩形的上下左右位置。 <div> </div> #### <a name="t3"></a>2). 移动裁剪框 <div> 若上一步判断,触摸点在圆内,就会返回MOVE,并处理移动过程。 </div> <div> </div> <div> <div class="dp-highlighter bg_java"> <div class="bar"> <div class="tools"> **[java]** [view plain](http://blog.csdn.net/jiantao_yang/article/details/43635581#)<span class="tracking-ad" data-mod="popu_168"><span class="tracking-ad" data-mod="popu_168"> [copy](http://blog.csdn.net/jiantao_yang/article/details/43635581#)</span></span> <div> <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_3"> </embed> </div> <span class="tracking-ad" data-mod="popu_167">[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/600342)</span><span class="tracking-ad" data-mod="popu_170">[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/600342/fork)</span></div> </div> - <span class="comment">// Grows the cropping rectangle by (dx, dy) in image space</span> - <span class="keyword">void</span> moveBy(<span class="keyword">float</span> dx, <span class="keyword">float</span> dy) { - Rect invalRect = <span class="keyword">new</span> Rect(drawRect); - <span class="comment">//移动</span> - cropRect.offset(dx, dy); - - <span class="comment">// Put the cropping rectangle inside image rectangle</span> - cropRect.offset( - - cropRect.offset( - - drawRect = computeLayout(); - invalRect.union(drawRect); - invalRect.inset(-(<span class="keyword">int</span>) handleRadius, -(<span class="keyword">int</span>) handleRadius); - viewContext.invalidate(invalRect); - } </div> 移动裁剪框并保证其它image图片显示范围内。 <div> </div> #### <a name="t4"></a>3). 缩放裁剪框 <div> 此过程和上一步类似,将cropRect矩阵进行等比缩放即可,这里就细说了,详见代码:HighLightView.growBy(float dx, float dy) </div> <div> </div> ### <a name="t5"></a>3.将裁剪图片保存为圆形 <div> <div class="dp-highlighter bg_java"> <div class="bar"> <div class="tools"> **[java]** [view plain](http://blog.csdn.net/jiantao_yang/article/details/43635581#)<span class="tracking-ad" data-mod="popu_168"><span class="tracking-ad" data-mod="popu_168"> [copy](http://blog.csdn.net/jiantao_yang/article/details/43635581#)</span></span> <div> <embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_4"> </embed> </div> <span class="tracking-ad" data-mod="popu_167">[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/600342)</span><span class="tracking-ad" data-mod="popu_170">[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/600342/fork)</span></div> </div> - <span class="comment">/**</span> - <span class="comment"> * @param bitmap src图片</span> - <span class="comment"> * @return</span> - <span class="comment"> */</span> - <span class="keyword">public</span> <span class="keyword">static</span> Bitmap getCircleBitmap(Bitmap bitmap) { - Bitmap output = Bitmap.createBitmap( bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); - Canvas canvas = <span class="keyword">new</span> Canvas( output); - - <span class="keyword">final</span> <span class="keyword">int</span> color = <span class="number">0xff424242</span>; - <span class="keyword">final</span> Paint paint = <span class="keyword">new</span> Paint(); - <span class="keyword">final</span> Rect rect = <span class="keyword">new</span> Rect( <span class="number"></span>, <span class="number"></span>, bitmap.getWidth(), bitmap.getHeight()); - - paint.setAntiAlias( <span class="keyword">true</span>); - paint.setFilterBitmap( <span class="keyword">true</span>); - paint.setDither( <span class="keyword">true</span>); - canvas.drawARGB( <span class="number"></span>, <span class="number"></span>, <span class="number"></span>, <span class="number"></span>); - paint.setColor( color); - <span class="comment">//在画布上绘制一个圆</span> - canvas.drawCircle( bitmap.getWidth() / <span class="number">2</span>, bitmap.getHeight() / <span class="number">2</span>, bitmap.getWidth() / <span class="number">2</span>, paint); - paint.setXfermode( <span class="keyword">new</span> PorterDuffXfermode( Mode.SRC_IN)); - canvas.drawBitmap( bitmap, rect, rect, paint); - <span class="keyword">return</span> output; - } </div> 注意:将bitmap保存为file时,格式请选择png,不然会出现黑色背景。 <div> </div> <div> 鉴于水平有限,从小语文就没学好,描述比较凌乱,需要深入理解的请阅读[源代码](http://download.csdn.net/detail/jiantao_yang/8433015)。 </div> <div> </div> <div> 附:另外一个很好开源项目 https://github.com/edmodo/cropper </div>

2016年2月19日 · 4 分钟 · 天边的星星

Android自定义相机拍照、图片裁剪的实现

最近项目里面又要加一个拍照搜题的功能,也就是用户对着不会做的题目拍一张照片,将照片的文字使用ocr识别出来,再调用题库搜索接口搜索出来展示给用户,类似于小猿搜题、学霸君等app。 其实Android提供Intent让我们打开系统的相机,但是系统相机跟自己app风格不搭,而且用起来体验不好。所以我使用了SDK提供的camera API自定义了一个相机,并且在相机界面上面添加了参考线,有助于用户将题目拍正,提高ocr的识别率。 1、绘制参考线的代码 ![复制代码](http://common.cnblogs.com/images/copycode.gif) 1 public class ReferenceLine extends View { 2 3 private Paint mLinePaint; 4 5 public ReferenceLine(Context context) { 6 super(context); 7 init(); 8 } 9 10 public ReferenceLine(Context context, AttributeSet attrs) { 11 super(context, attrs); 12 init(); 13 } 14 15 public ReferenceLine(Context context, AttributeSet attrs, int defStyleAttr) { 16 super(context, attrs, defStyleAttr); 17 init(); 18 } 19 20 private void init() { 21 mLinePaint = new Paint(); 22 mLinePaint.setAntiAlias(true); 23 mLinePaint.setColor(Color.parseColor("#45e0e0e0")); 24 mLinePaint.setStrokeWidth(1); 25 } 26 27 28 29 @Override 30 protected void onDraw(Canvas canvas) { 31 int screenWidth = Utils.getScreenWH(getContext()).widthPixels; 32 int screenHeight = Utils.getScreenWH(getContext()).heightPixels; 33 34 int width = screenWidth/3; 35 int height = screenHeight/3; 36 37 for (int i = width, j = 0;i &lt; screenWidth && j&lt;2;i += width, j++) { 38 canvas.drawLine(i, 0, i, screenHeight, mLinePaint); 39 } 40 for (int j = height,i = 0;j &lt; screenHeight && i &lt; 2;j += height,i++) { 41 canvas.drawLine(0, j, screenWidth, j, mLinePaint); 42 } 43 } 44 45 46 } ![复制代码](http://common.cnblogs.com/images/copycode.gif) ...

2016年2月19日 · 13 分钟 · 天边的星星

给 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 分钟 · 天边的星星

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 分钟 · 天边的星星