Android — RecyclerView

“A flexible view for providing a limited window into a large data set.” 可以说是ListView的升级版,ListVie中我们需要自己写ViewHolder,当然你也可以不写,是在RecylerView中,是要让写的哟~RecyclerView适用于无法在一个屏幕范围内展现格式一样的数据时,需要用多行或多列来展示。例如展示联系人,图片,视频等。用户需要滑动屏幕来查看数据,这时RecyclerView的特性就有用武之地了。比如,当用户滑动使当前一个可视的Item滑出屏幕,这个Item的视图将会被回收并在一个新Item进入可视范围后重新被使用。可回收利用View是个很实用的功能,它不仅可以减少CPU不断inflate View的开销,而且可以节省缓存View的内存开销。 RecylerView还有一大特色,就是动画! RecyclerView不再负责显示工作 和ListView不一样的是,RecyclerView不再负责Item的摆放等显示方面的功能。所有和布局、绘制等方面的工作都其拆分成不同的类进行管理。所以开发者可以自定义各种各样满足定制需求的的功能类。 RecyclerView.Adapter <td valign="top" width="454"> 托管数据集合,为每个Item创建视图 </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.ViewHolder </td> <td valign="top" width="454"> 承载Item视图的子视图 </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.LayoutManager </td> <td valign="top" width="454"> 负责Item视图的布局 </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.ItemDecoration </td> <td valign="top" width="454"> 为每个Item视图添加子视图,在Demo中被用来绘制Divider </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.ItemAnimator </td> <td valign="top" width="454"> 负责添加、删除数据时的动画效果 </td> </tr> ViewHolder 关于ViewHolder,Google早就推荐开发者使用,但也只是建议。但是现在,RecyclerView.Adapter最终要求开发者必须使用ViewHolder。 ...

2015年5月8日 · 3 分钟 · 天边的星星

【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法…

[http://blog.csdn.net/shulianghan/article/details/41520569](http://blog.csdn.net/shulianghan/article/details/41520569?utm_source=tuicool) **博客地址 **: [http://blog.csdn.net/shulianghan/article/details/41520569](http://blog.csdn.net/shulianghan/article/details/41520569) 代码下载 : &#8212; **GitHub **: [https://github.com/han1202012/WheelViewDemo.git](https://github.com/han1202012/WheelViewDemo.git) &#8212; **CSDN **: [http://download.csdn.net/detail/han1202012/8208997](http://download.csdn.net/detail/han1202012/8208997) ; #### 博客总结 : 博文内容 : 本文完整地分析了 WheelView 所有的源码, 包括其 适配器类型 , 两种回调接口 ( 选中条目改变回调 , 和 开始结束滚动回调 ), 以及详细的分析了 WheelView 主题源码, 其中 组件宽高测量 , 手势监听器添加 , 以及 精准的绘图方法 是主要目的, 花了将近1周时间, 感觉很值, 在这里分享给大家; 自定义组件宽高获取策略 : MeasureSpec 最大模式 取 默认值 和 给定值中较小的那个 , 未定义模式取默认值 , 精准模式取 给定值 ; 自定义组件维护各种回调监听器策略 : 维护集合, 将监听器置于集合中, 回调接口时遍历集合元素, 回调每个元素的接口方法; 自定义组件手势监听器添加方法 : 创建手势监听器, 将手势监听器传入手势探测器, 在 onTouchEvent() 方法中回调手势监听器的 onTouchEvent()方法; ## 一. WheelView 简介 ## 1. WheelView 效果 在 Android 中实现类似与 IOS 的 WheelView 控件 : 如图 ![](http://img2.tuicool.com/bMfU7b.png) ## 2. WheelView 使用流程 ### (1) 基本流程简介 a. 创建 WheelView 组件 : 使用 构造方法 或者 从布局文件获取 WheelView 组件; b. 设置显示条目数 : 调用 WheelView 组件对象的 setVisibleItems 方法 设置; c. 设置是否循环 : 设置 WheelView 是否循环, 调用 setCyclic() 方法设置; d. 设置适配器 : 调用 WheelView 组件的 setAdapter() 方法设置; e. 设置条目改变监听器 : 调用 WheelView 组件对象的 addChangingListener() 方法设置; f. 设置滚动监听器 : 调用 WheelView 组件对象的 addScrollingListener() 方法设置; ### (2) 代码实例 a. 创建 WheelView 对象 : ``` //创建 WheelView 组件 final WheelView wheelLeft = new WheelView(context); ...

2015年5月7日 · 47 分钟 · 天边的星星

Android设置虚线、圆角、渐变

有图又真相,先上图再说。 点击效果: 设置虚线: **[html]** [view plain](http://blog.csdn.net/lan410812571/article/details/9946991#)[copy](http://blog.csdn.net/lan410812571/article/details/9946991#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/83373)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/83373/fork) <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> </div> - <span class="tag"><?</span><span class="tag-name">xml</span> <span class="attribute">version</span>=<span class="attribute-value">&#8220;1.0&#8221;</span> <span class="attribute">encoding</span>=<span class="attribute-value">&#8220;utf-8&#8221;</span><span class="tag">?></span> - <span class="tag"><</span><span class="tag-name">shape</span> <span class="attribute">xmlns:android</span>=<span class="attribute-value">&#8220;http://schemas.android.com/apk/res/android&#8221;</span> - <span class="attribute">android:shape</span>=<span class="attribute-value">&#8220;line&#8221;</span> <span class="tag">></span> - <span class="tag"><</span><span class="tag-name">stroke</span> - <span class="attribute">android:dashGap</span>=<span class="attribute-value">&#8220;3dp&#8221;</span> - <span class="attribute">android:dashWidth</span>=<span class="attribute-value">&#8220;6dp&#8221;</span> - <span class="attribute">android:width</span>=<span class="attribute-value">&#8220;1dp&#8221;</span> - <span class="attribute">android:color</span>=<span class="attribute-value">&#8220;#63a219&#8221;</span> <span class="tag">/></span> - <span class="tag"><</span><span class="tag-name">size</span> <span class="attribute">android:height</span>=<span class="attribute-value">&#8220;1dp&#8221;</span> <span class="tag">/></span> - <span class="tag"></</span><span class="tag-name">shape</span><span class="tag">></span> 其中,破折线的宽度为dashWith,破折线之间的空隙的宽度为dashGap,当dashGap=0dp时,为实线 ...

2015年5月2日 · 3 分钟 · 天边的星星

Android Studio 修改module名

Android Studio 新建工程自动生成的 module 名为 app,尝试用 refactor->rename 进行改变,发现会报错:failed to complete gradle execution already disposed:Module:app,百度居然又没有答案,google一下就有了,三个步骤: 1.refactor -> rename,先按常规修改这个; 2.修改 settings.gradle 中的模块名; 3.打开文件夹,修改文件夹名。 以上就完成了模块名的修改,最后不要忘了gradle同步一下

2015年4月29日 · 1 分钟 · 天边的星星

使用Android Studio阅读整个Android源码

之前一直在windows下用source insight阅读android源码,效果非常好。 后来远程异地服务器,网络限制,一直用ssh + vim,现在主要还是以这种方式。 最近发现一个不错的东西(早就有了),在android源码中有这么一个目录development/tools/idegen。 顾名思义,是生成ide的project文件,主要是生成intellij的project文件,当然也可用于android studio。 使用之后,发现效果超棒,所以这里专门撰文推荐。 1、效果图 2、编译idegen模块 源码要编过,不然idegen没法生成。 提示: 1 <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"> `// 找不到idegen,需要全局编译一下` </div> <div class="line number2 index1 alt1"> `/*` </div> <div class="line number3 index2 alt2"> `ubuntu:~/Data/cyanogenmod$ . development/tools/idegen/idegen.sh` </div> <div class="line number4 index3 alt1"> `Couldn't find idegen.jar. Please run make first.` </div> <div class="line number5 index4 alt2"> `*/` </div> </div> </td> </tr> </table> </div> 但是我相信很多看源码的人是不需要编译的,所以只要我上传一个idegen.jar: http://jayfeng-files.stor.sinaapp.com/idegen.jar 把这个文件copy到out/host/linux-x86/framework/目录下: ...

2015年4月29日 · 2 分钟 · 天边的星星

android staticlayout使用讲解

使用Canvas的drawText绘制文本是不会自动换行的,即使一个很长很长的字符串,drawText也只显示一行,超出部分被隐藏在屏幕之外。可以逐个计算每个字符的宽度,通过一定的算法将字符串分割成多个部分,然后分别调用drawText一部分一部分的显示, 但是这种显示效率会很低。 StaticLayout是android中处理文字换行的一个工具类,StaticLayout已经实现了文本绘制换行处理,下面是如何使用StaticLayout的例子: package com.example.amdroidstaticlayoutdemo; import android.support.v4.app.Fragment; import android.text.Layout.Alignment; import android.text.StaticLayout; import android.text.TextPaint; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.os.Bundle; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.os.Build; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } public class MyView extends View { Paint mPaint; //画笔,包含了画几何图形、文本等的样式和颜色信息 public MyView(Context context) { super(context); } ...

2015年4月29日 · 2 分钟 · 天边的星星

android之interpolator的用法详解

android:interpolator Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。 android中的文档内容如下: ![](http://img.blog.csdn.net/20131117161350500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFzb24wNTM5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速 AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速 AnticipateInterpolator 开始的时候向后然后向前甩 AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值 BounceInterpolator 动画结束的时候弹起 CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线 DecelerateInterpolator 在动画开始的地方快然后慢 LinearInterpolator 以常量速率改变 OvershootInterpolator 向前甩一定值后再回到原来位置 如果android定义的interpolators不符合你的效果也可以自定义interpolators &nbsp; Android中的Interpolator nterpolator用于动画中的时间插值,其作用就是把0到1的浮点值变化映射到另一个浮点值变化。 本文列出Android API提供的Interpolator的若干种实现,列出源码,并且用一个程序绘制出其数学曲线。(项目链接附在文后)。 AccelerateDecelerateInterpolator ![复制代码](http://common.cnblogs.com/images/copycode.gif) ``` /** An interpolator where the rate of change starts and ends slowly but accelerates through the middle. */ public class AccelerateDecelerateInterpolator implements Interpolator { public AccelerateDecelerateInterpolator() { } @SuppressWarnings({"UnusedDeclaration"}) public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) { } public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } } ...

2015年4月28日 · 7 分钟 · 天边的星星

用户手势检测-GestureDetector使用详解

一、概述 当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等。 一般情况下,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势)。 Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势,主要是通过他的onTouchEvent(event)方法完成了不同手势的识别。虽然他能识别手势,但是不同的手势要怎么处理,应该是提供给程序员实现的。 GestureDetector这个类对外提供了两个接口和一个外部类 接口:OnGestureListener,OnDoubleTapListener 内部类:SimpleOnGestureListener 这个外部类,其实是两个接口中所有函数的集成,它包含了这两个接口里所有必须要实现的函数而且都已经重写,但所有方法体都是空的;不同点在于:该类是static class,程序员可以在外部继承这个类,重写里面的手势处理方法。 下面我们先看OnGestureListener接口; 二、GestureDetector.OnGestureListener—接口 1、基本讲解 如果我们写一个类并implements OnGestureListener,会提示有几个必须重写的函数,加上之后是这个样子的: **[java]** [view plain](http://blog.csdn.net/harvic880925/article/details/39520901#)[copy](http://blog.csdn.net/harvic880925/article/details/39520901#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/475851)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/475851/fork) <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> </div> - <span class="keyword">private</span> <span class="keyword">class</span> gesturelistener <span class="keyword">implements</span> GestureDetector.OnGestureListener{ - - <span class="keyword">public</span> <span class="keyword">boolean</span> onDown(MotionEvent e) { - <span class="comment">// TODO Auto-generated method stub</span> - <span class="keyword">return</span> <span class="keyword">false</span>; - } - - <span class="keyword">public</span> <span class="keyword">void</span> onShowPress(MotionEvent e) { - <span class="comment">// TODO Auto-generated method stub</span> - - } - - <span class="keyword">public</span> <span class="keyword">boolean</span> onSingleTapUp(MotionEvent e) { - <span class="comment">// TODO Auto-generated method stub</span> - <span class="keyword">return</span> <span class="keyword">false</span>; - } - - <span class="keyword">public</span> <span class="keyword">boolean</span> onScroll(MotionEvent e1, MotionEvent e2, - <span class="keyword">float</span> distanceX, <span class="keyword">float</span> distanceY) { - <span class="comment">// TODO Auto-generated method stub</span> - <span class="keyword">return</span> <span class="keyword">false</span>; - } - - <span class="keyword">public</span> <span class="keyword">void</span> onLongPress(MotionEvent e) { - <span class="comment">// TODO Auto-generated method stub</span> - - } - - <span class="keyword">public</span> <span class="keyword">boolean</span> onFling(MotionEvent e1, MotionEvent e2, <span class="keyword">float</span> velocityX, - <span class="keyword">float</span> velocityY) { - <span class="comment">// TODO Auto-generated method stub</span> - <span class="keyword">return</span> <span class="keyword">false</span>; - } - - } 可见,这里总共重写了六个函数,这些函数都在什么情况下才会触发呢,下面讲一下: ...

2015年4月28日 · 11 分钟 · 天边的星星

Android Scroller简单用法

Android里Scroller类是为了实现View平滑滚动的一个Helper类。通常在自定义的View时使用,在View中定义一个私有成员mScroller = new Scroller(context)。设置mScroller滚动的位置时,并不会导致View的滚动,通常是用mScroller记录/计算View滚动的位置,再重写View的computeScroll(),完成实际的滚动。 相关API介绍如下 Java代码 <embed src="http://ipjmc.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" type="application/x-shockwave-flash" width="14" height="15"> </embed> <a title="收藏这段代码">![收藏代码](http://ipjmc.iteye.com/images/icon_star.png)</a> </div> - mScroller.getCurrX() <span class="comment">//获取mScroller当前水平滚动的位置</span> - mScroller.getCurrY() <span class="comment">//获取mScroller当前竖直滚动的位置</span> - mScroller.getFinalX() <span class="comment">//获取mScroller最终停止的水平位置</span> - mScroller.getFinalY() <span class="comment">//获取mScroller最终停止的竖直位置</span> - mScroller.setFinalX(<span class="keyword">int</span> newX) <span class="comment">//设置mScroller最终停留的水平位置,没有动画效果,直接跳到目标位置</span> - mScroller.setFinalY(<span class="keyword">int</span> newY) <span class="comment">//设置mScroller最终停留的竖直位置,没有动画效果,直接跳到目标位置</span> - - <span class="comment">//滚动,startX, startY为开始滚动的位置,dx,dy为滚动的偏移量, duration为完成滚动的时间</span> - mScroller.startScroll(<span class="keyword">int</span> startX, <span class="keyword">int</span> startY, <span class="keyword">int</span> dx, <span class="keyword">int</span> dy) <span class="comment">//使用默认完成时间250ms</span> - mScroller.startScroll(<span class="keyword">int</span> startX, <span class="keyword">int</span> startY, <span class="keyword">int</span> dx, <span class="keyword">int</span> dy, <span class="keyword">int</span> duration) - - mScroller.computeScrollOffset() <span class="comment">//返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。这是一个很重要的方法,通常放在View.computeScroll()中,用来判断是否滚动是否结束。</span> 举例说明,自定义一个CustomView,使用Scroller实现滚动: ...

2015年4月28日 · 6 分钟 · 天边的星星

Android 4.4从图库选择图片,获取图片路径并裁剪

 最近在做一个从图库选择图片或拍照,然后裁剪的功能.本来是没问题的,一直在用 **[java]** [view plain](http://blog.csdn.net/tempersitu/article/details/20557383#)[copy](http://blog.csdn.net/tempersitu/article/details/20557383#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/219069)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/219069/fork) - Intent intent=<span class="keyword">new</span> Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 的方式来做,是调用系统图库来做,但是发现如果有图片是同步到google相册的话,图库里面能看到一个auto backup的目录,点进去选图片的话是无法获取到图片的路径的.因为那些图片根本就不存在于手机上.然后看到无论是百度贴吧,Instagram,或者还有些会选取图片做修改的app,都是用一个很漂亮的图片选择器(4.4以上,4.3的还是用系统旧的图库). 而这个图片选择器可以屏蔽掉那个auto backup的目录.所以就开始打算用这个图片选择器来选图片了. 这个方法就是 **[java]** [view plain](http://blog.csdn.net/tempersitu/article/details/20557383#)[copy](http://blog.csdn.net/tempersitu/article/details/20557383#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/219069)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/219069/fork) - Intent intent=<span class="keyword">new</span> Intent(Intent.ACTION_GET_CONTENT);<span class="comment">//ACTION_OPEN_DOCUMENT</span> - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType(<span class="string">&#8220;image/jpeg&#8221;</span>); - <span class="keyword">if</span>(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){ - startActivityForResult(intent, SELECT_PIC_KITKAT); - }<span class="keyword">else</span>{ - startActivityForResult(intent, SELECT_PIC); - } 为什么要分开不同版本呢?其实在4.3或以下可以直接用ACTION_GET_CONTENT的,在4.4或以上,官方建议用ACTION_OPEN_DOCUMENT,但其实都不算太大区别,区别是他们返回的Uri,那个才叫大区别.这就是困扰了我一整天的问题所在了. 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT的方法,返回的uri跟4.3是完全不一样的,4.3返回的是带文件路径的,而4.4返回的却是content://com.android.providers.media.documents/document/image:3951这样的,没有路径,只有图片编号的uri.这就导致接下来无法根据图片路径来裁剪的步骤了. 还好找了很多方法,包括加权限啊什么的,中间还试过用一些方法,自己的app没崩溃,倒是让系统图库崩溃了,引发了java.lang.SecurityException. **[java]** [view plain](http://blog.csdn.net/tempersitu/article/details/20557383#)[copy](http://blog.csdn.net/tempersitu/article/details/20557383#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/219069)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/219069/fork) - Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{437b5d88 <span class="number">9494</span>:com.google.android.gallery3d/u0a20} (pid=<span class="number">9494</span>, uid=<span class="number">10020</span>) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS 看来4.4的系统还是有些bug.重点来了,4.4得到的uri,需要以下方法来获取文件的路径 ...

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