Adapter的getViewTypeCount和getItemViewType 使用

通过本篇文章,让你掌握新的技巧,请不用只看看一点,希望能够看完,让你很快明白不同的使用场景 ListView 和 Adapter 的基础 工作原理: ListView 针对List中每个item,要求 adapter “给我一个视图” (getView)。 一个新的视图被返回并显示 如果我们有上亿个项目要显示怎么办?为每个项目创建一个新视图?NO!这不可能! 实际上Android为你缓存了视图。 Android中有个叫做Recycler的构件,下图是他的工作原理: 如果你有10亿个项目(item),其中只有可见的项目存在内存中,其他的在Recycler中。 ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的。 当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图。 请看下面的示例代码,这里在getView中使用了System.out进行输出 [?](http://www.aitinan.com/3885.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> <div class="line number6 index5 alt1"> 6 </div> <div class="line number7 index6 alt2"> 7 </div> <div class="line number8 index7 alt1"> 8 </div> <div class="line number9 index8 alt2"> 9 </div> <div class="line number10 index9 alt1"> 10 </div> <div class="line number11 index10 alt2"> 11 </div> <div class="line number12 index11 alt1"> 12 </div> <div class="line number13 index12 alt2"> 13 </div> <div class="line number14 index13 alt1"> 14 </div> <div class="line number15 index14 alt2"> 15 </div> <div class="line number16 index15 alt1"> 16 </div> <div class="line number17 index16 alt2"> 17 </div> <div class="line number18 index17 alt1"> 18 </div> <div class="line number19 index18 alt2"> 19 </div> <div class="line number20 index19 alt1"> 20 </div> <div class="line number21 index20 alt2"> 21 </div> <div class="line number22 index21 alt1"> 22 </div> <div class="line number23 index22 alt2"> 23 </div> <div class="line number24 index23 alt1"> 24 </div> <div class="line number25 index24 alt2"> 25 </div> <div class="line number26 index25 alt1"> 26 </div> <div class="line number27 index26 alt2"> 27 </div> <div class="line number28 index27 alt1"> 28 </div> <div class="line number29 index28 alt2"> 29 </div> <div class="line number30 index29 alt1"> 30 </div> <div class="line number31 index30 alt2"> 31 </div> <div class="line number32 index31 alt1"> 32 </div> <div class="line number33 index32 alt2"> 33 </div> <div class="line number34 index33 alt1"> 34 </div> <div class="line number35 index34 alt2"> 35 </div> <div class="line number36 index35 alt1"> 36 </div> <div class="line number37 index36 alt2"> 37 </div> <div class="line number38 index37 alt1"> 38 </div> <div class="line number39 index38 alt2"> 39 </div> <div class="line number40 index39 alt1"> 40 </div> <div class="line number41 index40 alt2"> 41 </div> <div class="line number42 index41 alt1"> 42 </div> <div class="line number43 index42 alt2"> 43 </div> <div class="line number44 index43 alt1"> 44 </div> <div class="line number45 index44 alt2"> 45 </div> <div class="line number46 index45 alt1"> 46 </div> <div class="line number47 index46 alt2"> 47 </div> <div class="line number48 index47 alt1"> 48 </div> <div class="line number49 index48 alt2"> 49 </div> <div class="line number50 index49 alt1"> 50 </div> <div class="line number51 index50 alt2"> 51 </div> <div class="line number52 index51 alt1"> 52 </div> <div class="line number53 index52 alt2"> 53 </div> <div class="line number54 index53 alt1"> 54 </div> <div class="line number55 index54 alt2"> 55 </div> <div class="line number56 index55 alt1"> 56 </div> <div class="line number57 index56 alt2"> 57 </div> <div class="line number58 index57 alt1"> 58 </div> <div class="line number59 index58 alt2"> 59 </div> <div class="line number60 index59 alt1"> 60 </div> <div class="line number61 index60 alt2"> 61 </div> <div class="line number62 index61 alt1"> 62 </div> <div class="line number63 index62 alt2"> 63 </div> <div class="line number64 index63 alt1"> 64 </div> <div class="line number65 index64 alt2"> 65 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `public` `class` `MultipleItemsListextends ListActivity {` </div> <div class="line number2 index1 alt1"> ` ` </div> <div class="line number3 index2 alt2"> ` ``private` `MyCustomAdapter mAdapter;` </div> <div class="line number4 index3 alt1"> ` ` </div> <div class="line number5 index4 alt2"> ` ``@Override` </div> <div class="line number6 index5 alt1"> ` ``public` `void` `onCreate(Bundle savedInstanceState) {` </div> <div class="line number7 index6 alt2"> ` ``super``.onCreate(savedInstanceState);` </div> <div class="line number8 index7 alt1"> ` ``mAdapter = ``new` `MyCustomAdapter();` </div> <div class="line number9 index8 alt2"> ` ``for` `(``int` `i = ````; i &lt; ``50``; i++) {` </div> <div class="line number10 index9 alt1"> ` ``mAdapter.addItem(``"item "` `+ i);` </div> <div class="line number11 index10 alt2"> ` ``}` </div> <div class="line number12 index11 alt1"> ` ``setListAdapter(mAdapter);` </div> <div class="line number13 index12 alt2"> ` ``}` </div> <div class="line number14 index13 alt1"> ` ` </div> <div class="line number15 index14 alt2"> ` ``private` `class` `MyCustomAdapterextends BaseAdapter {` </div> <div class="line number16 index15 alt1"> ` ` </div> <div class="line number17 index16 alt2"> ` ``private` `ArrayList mData = ``new` `ArrayList();` </div> <div class="line number18 index17 alt1"> ` ``private` `LayoutInflater mInflater;` </div> <div class="line number19 index18 alt2"> ` ` </div> <div class="line number20 index19 alt1"> ` ``public` `MyCustomAdapter() {` </div> <div class="line number21 index20 alt2"> ` ``mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);` </div> <div class="line number22 index21 alt1"> ` ``}` </div> <div class="line number23 index22 alt2"> ` ` </div> <div class="line number24 index23 alt1"> ` ``public` `void` `addItem(``final` `String item) {` </div> <div class="line number25 index24 alt2"> ` ``mData.add(item);` </div> <div class="line number26 index25 alt1"> ` ``notifyDataSetChanged();` </div> <div class="line number27 index26 alt2"> ` ``}` </div> <div class="line number28 index27 alt1"> ` ` </div> <div class="line number29 index28 alt2"> ` ``@Override` </div> <div class="line number30 index29 alt1"> ` ``public` `int` `getCount() {` </div> <div class="line number31 index30 alt2"> ` ``return` `mData.size();` </div> <div class="line number32 index31 alt1"> ` ``}` </div> <div class="line number33 index32 alt2"> ` ` </div> <div class="line number34 index33 alt1"> ` ``@Override` </div> <div class="line number35 index34 alt2"> ` ``public` `String getItem(``int` `position) {` </div> <div class="line number36 index35 alt1"> ` ``return` `mData.get(position);` </div> <div class="line number37 index36 alt2"> ` ``}` </div> <div class="line number38 index37 alt1"> ` ` </div> <div class="line number39 index38 alt2"> ` ``@Override` </div> <div class="line number40 index39 alt1"> ` ``public` `long` `getItemId(``int` `position) {` </div> <div class="line number41 index40 alt2"> ` ``return` `position;` </div> <div class="line number42 index41 alt1"> ` ``}` </div> <div class="line number43 index42 alt2"> ` ` </div> <div class="line number44 index43 alt1"> ` ``@Override` </div> <div class="line number45 index44 alt2"> ` ``public` `View getView(``int` `position, View convertView, ViewGroup parent) {` </div> <div class="line number46 index45 alt1"> ` ``System.out.println(``"getView "` `+ position + ``" "` `+ convertView);` </div> <div class="line number47 index46 alt2"> ` ``ViewHolder holder = ``null``;` </div> <div class="line number48 index47 alt1"> ` ``if` `(convertView == ``null``) {` </div> <div class="line number49 index48 alt2"> ` ``convertView = mInflater.inflate(R.layout.item1, ``null``);` </div> <div class="line number50 index49 alt1"> ` ``holder = ``new` `ViewHolder();` </div> <div class="line number51 index50 alt2"> ` ``holder.textView = (TextView)convertView.findViewById(R.id.text);` </div> <div class="line number52 index51 alt1"> ` ``convertView.setTag(holder);` </div> <div class="line number53 index52 alt2"> ` ``}``else` `{` </div> <div class="line number54 index53 alt1"> ` ``holder = (ViewHolder)convertView.getTag();` </div> <div class="line number55 index54 alt2"> ` ``}` </div> <div class="line number56 index55 alt1"> ` ``holder.textView.setText(mData.get(position));` </div> <div class="line number57 index56 alt2"> ` ``return` `convertView;` </div> <div class="line number58 index57 alt1"> ` ``}` </div> <div class="line number59 index58 alt2"> ` ` </div> <div class="line number60 index59 alt1"> ` ``}` </div> <div class="line number61 index60 alt2"> ` ` </div> <div class="line number62 index61 alt1"> ` ``public` `static` `class` `ViewHolder {` </div> <div class="line number63 index62 alt2"> ` ``public` `TextView textView;` </div> <div class="line number64 index63 alt1"> ` ``}` </div> <div class="line number65 index64 alt2"> `}` </div> </div> </td> </tr> </table> </div> </div> </div> 执行程序,然后在Logcat中查看日志 ...

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

android TypedValue.applyDimension()的作用

android TypedValue.applyDimension()的作用 这个方法是转变为标准尺寸的一个函数,例如 int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, context.getResources().getDisplayMetrics()); 这里COMPLEX_UNIT_SP是单位,20是数值,也就是20sp。 int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics()); 这里COMPLEX_UNIT_DIP是单位,20是数值,也就是20dp。

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

高仿微信对话列表滑动删除效果

转载:http://blog.csdn.net/singwhatiwanna/article/details/17515543 前言 用过微信的都知道,微信对话列表滑动删除效果是很不错的,这个效果我们也可以有。思路其实很简单,弄个ListView,然后里面的每个item做成一个可以滑动的自定义控件即可。由于ListView是上下滑动而item是左右滑动,因此会有滑动冲突,也许你需要了解下android中点击事件的派发流程,请参考Android源码分析-点击事件派发机制。我的解决思路是这样的:重写ListView的onInterceptTouchEvent方法,在move的时候做判断,如果是左右滑动就返回false,否则返回true;重写SlideView(即自定义item控件)的onTouchEvent方法来处理滑动。整个思路没有问题,滑动冲突也解决了,可是ListView无法得到焦点了,也就是ListView无法处理点击事件了。让我们回想下问题出在哪里:我的理解是这样的,上述处理滑动本身没有问题,但是有一个副作用,就是会让外层View失去焦点且无法处理点击事件。常见的滑动冲突场景,比如launcher内部嵌入ListView却是没有问题的,因为这个时候launcher不需要获得焦点,需要获得焦点的是内部的ListView。因此,上述处理方式对于外部需要获得焦点的情况(比如外部是ListView)就不太适合了。于是我就和ttdevs探讨,发现他采用了另外一种思路,我从来没有想过还可以这样玩。下面介绍他的思路。 新的思路 不考虑那么复杂,不采用主流玩法,所有的事件均由外层的ListView做拦截,同时把事件传递给SlideView做滑动,这种实现的确可以达到效果,而且代码很简单,根本不需要处理什么复杂的滑动冲突。 效果 下面分别为微信和高仿效果 代码分析 先看SlideView是如何实现的 看layout xml: **[html]** [view plain](http://blog.csdn.net/singwhatiwanna/article/details/17515543#)[copy](http://blog.csdn.net/singwhatiwanna/article/details/17515543#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/125514)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/125514/fork) - <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">merge</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:layout_width</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> <span class="tag">></span> - - <span class="tag"><</span><span class="tag-name">LinearLayout</span> - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/view_content&#8221;</span> - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> - <span class="attribute">android:orientation</span>=<span class="attribute-value">&#8220;horizontal&#8221;</span> <span class="tag">></span> - <span class="tag"></</span><span class="tag-name">LinearLayout</span><span class="tag">></span> - - <span class="tag"><</span><span class="tag-name">RelativeLayout</span> - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/holder&#8221;</span> - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;120dp&#8221;</span> - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> - <span class="attribute">android:clickable</span>=<span class="attribute-value">&#8220;true&#8221;</span> - <span class="attribute">android:background</span>=<span class="attribute-value">&#8220;@drawable/holder_bg&#8221;</span><span class="tag">></span> - - <span class="tag"><</span><span class="tag-name">TextView</span> - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/delete&#8221;</span> - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span> - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span> - <span class="attribute">android:drawableLeft</span>=<span class="attribute-value">&#8220;@drawable/del_icon_normal&#8221;</span> - <span class="attribute">android:layout_centerInParent</span>=<span class="attribute-value">&#8220;true&#8221;</span> - <span class="attribute">android:gravity</span>=<span class="attribute-value">&#8220;center&#8221;</span> - <span class="attribute">android:textColor</span>=<span class="attribute-value">&#8220;@color/floralwhite&#8221;</span> - <span class="attribute">android:text</span>=<span class="attribute-value">&#8220;删除&#8221;</span> <span class="tag">/></span> - <span class="tag"></</span><span class="tag-name">RelativeLayout</span><span class="tag">></span> - - <span class="tag"></</span><span class="tag-name">merge</span><span class="tag">></span> 上述xml文件中,所有的view都会被放在view_content中,而holder是放置诸如删除按钮之类的东西,我们的SlideView会加载这个布局。 ...

2015年4月22日 · 8 分钟 · 天边的星星

android仿通讯录

friend.xml **[java]** [view plain](http://blog.csdn.net/csh159/article/details/8955029#)[copy](http://blog.csdn.net/csh159/article/details/8955029#)[print](http://blog.csdn.net/csh159/article/details/8955029#)[?](http://blog.csdn.net/csh159/article/details/8955029#) <div> <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="29" height="15" align="middle" name="ZeroClipboardMovie_1"> </embed> </div> </div> - <?xml version=<span class="string">&#8220;1.0&#8221;</span> encoding=<span class="string">&#8220;utf-8&#8221;</span>?> - <LinearLayout xmlns:android=<span class="string">&#8220;http://schemas.android.com/apk/res/android&#8221;</span> - android:layout_width=<span class="string">&#8220;match_parent&#8221;</span> - android:layout_height=<span class="string">&#8220;match_parent&#8221;</span> - android:orientation=<span class="string">&#8220;vertical&#8221;</span> > - <RelativeLayout - android:layout_width=<span class="string">&#8220;fill_parent&#8221;</span> - android:layout_height=<span class="string">&#8220;fill_parent&#8221;</span> - android:orientation=<span class="string">&#8220;vertical&#8221;</span> > - - <ListView - android:id=<span class="string">&#8220;@+id/list_view&#8221;</span> - android:layout_width=<span class="string">&#8220;fill_parent&#8221;</span> - android:layout_height=<span class="string">&#8220;wrap_content&#8221;</span> - android:scrollbars=<span class="string">&#8220;none&#8221;</span> > - </ListView> - - <com.example.menu.MyLetterListView - android:id=<span class="string">&#8220;@+id/my_list_view&#8221;</span> - android:layout_width=<span class="string">&#8220;30dip&#8221;</span> - android:layout_height=<span class="string">&#8220;fill_parent&#8221;</span> - android:layout_alignParentRight=<span class="string">&#8220;true&#8221;</span> - /> - </RelativeLayout> - - </LinearLayout> friend_header.xml ...

2015年4月14日 · 13 分钟 · 天边的星星

Android Lock Pattern 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 介绍 1.1 关于 Android 的图案密码解锁,通过手势连接 3 * 3 的点矩阵绘制图案表示解锁密码。基于 Android Source Code。 1.2 特点 支持: Android 1.6+ (API 4+)。 无特殊依赖。 支持手机与平板的布局。 Stealth mode (invisible pattern)。 包含 5 种主题: Dark/Light Light with dark action bar (API 14+) Dark/Light dialogs 有验证码模式。 1.3 使用 1.3.1 Manifest 配置 <activity android:name="com.haibison.android.lockpattern.LockPatternActivity" android:theme="@style/Alp.42447968.Theme.Dark" /> 1.3.2 创建图形锁模式 private static final int REQ_CREATE_PATTERN = 1; Intent intent = new Intent(LockPatternActivity.ACTION_CREATE_PATTERN, null, your-context, LockPatternActivity.class); startActivityForResult(intent, REQ_CREATE_PATTERN); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQ_CREATE_PATTERN: { if (resultCode == RESULT_OK) { char[] pattern = data.getCharArrayExtra( LockPatternActivity.EXTRA_PATTERN); ... } break; } } } 1.3.3 验证图形锁 private static final int REQ_ENTER_PATTERN = 2; char[] savedPattern = ... Intent intent = new Intent(LockPatternActivity.ACTION_COMPARE_PATTERN, null, your-context, LockPatternActivity.class); intent.putExtra(LockPatternActivity.EXTRA_PATTERN, savedPattern); startActivityForResult(intent, REQ_ENTER_PATTERN); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQ_ENTER_PATTERN: { switch (resultCode) { case RESULT_OK: // The user passed break; case RESULT_CANCELED: // The user cancelled the task break; case LockPatternActivity.RESULT_FAILED: // The user failed to enter the pattern break; case LockPatternActivity.RESULT_FORGOT_PATTERN: // The user forgot the pattern and invoked your recovery Activity. break; } int retryCount = data.getIntExtra( LockPatternActivity.EXTRA_RETRY_COUNT, 0); break; } } } 2. 总体设计 本项目较为简单,总体设计略过,具体实现请参考下面的分析。 ...

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

Dagger 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 1.1 Dagger Dagger 是一款 Java 平台的依赖注入库,关于依赖注入,详细见 依赖注入简介。 Java 的依赖注入库中,最有名的应该属 Google 的 Guice,Spring 也很有名,不过是专注于 J2EE 开发。Guice 的功能非常强大,但它是通过在运行时读取注解来实现依赖注入的,依赖的生成和注入需要依靠 Java 的反射机制,这对于对性能非常敏感的 Android 来说是一个硬伤。基于此,Dagger 应运而生。 Dagger 同样使用注解来实现依赖注入,但它利用 APT(Annotation Process Tool) 在编译时生成辅助类,这些类继承特定父类或实现特定接口,程序在运行时 Dagger 加载这些辅助类,调用相应接口完成依赖生成和注入。Dagger 对于程序的性能影响非常小,因此更加适用于 Android 应用的开发。 1.2 依赖注入相关概念 **依赖(Dependency):**如果在 Class A 中,有个属性是 Class B 的实例,则称 Class B 是 Class A 的依赖,本文中我们将 Class A 称为宿主(Host),并且全文用 Host 表示;Class B 称为依赖(Dependency),并且全文用 Dependency 表示。一个 Host 可能是另外一个类的 Dependency。 **宿主(Host):**如果 Class B 是 Class A 的 Dependency,则称 Class A 是 Class B 的宿主(Host)。 ...

2015年4月8日 · 10 分钟 · 天边的星星

HoloGraphLibrary 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 HoloGraphLibrary 是一个可用于绘制图表的项目,支持绘制线状图、柱状图、饼状图。 优点:图形设计友好,使用方便。 2. 总体设计 本项目较为简单,总体设计请参考4.1类关系图。 3. 流程图 本项目的每个控件的流程较为类似,可以抽象成一个流程图来理解。 4. 详细设计 4.1 类关系图 其中LineGraph、BarGraph、PieGraph分别对应线状图、柱状图、饼状图控件。 其他除 View 以外的类都表示封装的数据。 4.2 核心类功能介绍 4.2.1 柱状图: Bar.java:用于表现一个柱体,构成柱状图的基本元素。封装了颜色,名字,BarStackSegment(下文将会涉及)数组等属性。若需要对Bar的每一个片段进行控制,改变BarStackSegment数组属性即可。 BarStackSegment.java:一般来说,一个柱体用于展示一个类型的数据,而BarStackSegment是作为柱体的扩展部分,用在同一个柱体上不同区间展示不同数据。 BarGraph.java:继承View类,表示柱状图控件,通过数据绘制负责柱状图。 (1). onDraw 流程图 (2). onDraw 源码分析 a. 绘制的样式定义(柱体颜色、宽度大小等属性) `public void onDraw(Canvas ca) { ... // 柱体的样式定义 float maxValue = 0; float padding = 7; int selectPadding = 4; float bottomPadding = 40; // 定义绘制柱体的区间 float usableHeight; if (showBarText) { this.p.setTextSize(40); this.p.getTextBounds(unit, 0, 1, r3); usableHeight = getHeight() - bottomPadding - Math.abs(r3.top - r3.bottom) - 26; } else { usableHeight = getHeight() - bottomPadding; } ... // 绘制柱体 int count = 0; for (Bar p : points) { // 绘制每个柱体里的自定义区间 if(p.getStackedBar()){ ... }else { // 若没有自定义区间,则正常绘制 ... } } ... } ` b. 绘制计算过程(详细看源码) 1)绘制 X 轴 2)确定柱体的数量 3)计算柱体所需的宽度 4)如果使用动画,柱体最大值(影响绘画的高度)使用动态计算的最大值 5)计算 X 轴上标签的字体的大小(不考虑动画状态,否则会导致字体抖动) 6)设置柱体边界 7)绘制柱体 8)创建选择区域 9)绘制标签 10)绘制柱体顶部的文字 11)限制总体宽度,防止弹出 12)若有使用后,设置监听,对进行动画更新 ...

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

PhotoView 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 特性(Features): 支持Pinch手势自由缩放。 支持双击放大/还原。 支持平滑滚动。 在滑动父控件下能够运行良好。(例如:ViewPager) 支持基于Matrix变化(放大/缩小/移动)的事件监听。 优势: PhotoView是ImageView的子类,自然的支持所有ImageView的源生行为。 任意项目可以非常方便的从ImageView升级到PhotoView,不用做任何额外的修改。 可以非常方便的与ImageLoader/Picasso之类的异步网络图片读取库集成使用。 事件分发做了很好的处理,可以方便的与ViewPager等同样支持滑动手势的控件集成。 2. 总体设计 PhotoView这个库实际上比较简单,关键点其实就是Touch事件处理和Matrix图形变换的应用. 2.1 TouchEvent及手势事件处理 对TouchEvent分发流程不了解的建议先阅读 Android Touch事件传递机制 本库中对Touch事件的处理流程请参考第三部分的流程图,会有一个比较直观的认识。 2.2 Matrix 由于Matrix是Android系统源生API,很多开发者对此都比较熟悉,为了不影响阅读效果,故不在此详细叙述,如果对其不是很了解,可以查看本文档末尾的Matrix补充说明 3. 流程图 Touch及手势事件判定及传递流程: 如图,从架构上看,干净利落的将事件层层分离,交由不同的Detector处理,最后再将处理结果回调给PhtotViewAttacher中的Matrix去实现图形变换效果。 4. 详细设计 4.1 核心类功能介绍 Core核心类 4.1.1 PhotoView PhotoView 类负责暴露所有供外部调用的API,其本身直接继承自ImageView,同时实现了IPhotoView接口. IPhotoView接口提供了缩放相关的设置属性 和操控matrix变化的回调接口. 主要方法说明: public PhotoView(Context context) public PhotoView(Context context, AttributeSet attr) public PhotoView(Context context, AttributeSet attr, int defStyle) 构造函数,完全与ImageView相同,你可以将PhotoView直接当做ImageView使用,完全兼容. public void setPhotoViewRotation(float rotationDegree) 用于设置图片旋转角度. 注意: 例如使用Android相机拍摄的相片,会根据拍摄时手机方向的不同,在EXIF中存储不同的旋转角度信息,显示时往往需要查询EXIF信息并将照片旋转至正确的方向. 通常我们处理这种问题有两种方案: 通过Bitmap.createBitmap方式重建出正确方向的图片,再加载到ImageView中显示。(不建议使用,因为会占用双倍的内存,Bitmap的回收不是立即生效的。) 在ImageView中使用自定义Matrix将图片旋转到正确的方向。 由于PhotoView中对图片的 缩放 操作依赖对Matrix的操作,自定义Matrix会干扰 PhotoView 的缩放行为,所以PhotoView并不支持ScaleType.Matrix. 可参见PhotoViewAttacher源码: ...

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

xUtils 源码解析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 xUtils一个Android公共库框架,主要包括四个部分:View,Db, Http, Bitmap 四个模块。 View模块主要的功能是通过注解绑定UI,资源,事件。 Db模块是一个数据库orm框架, 简单的语句就能进行数据的操作。 Http模块主要访问网络,支持同步,异步方式的请求,支持文件的下载。 Bitmap模块是加载图片以及图片的处理, 支持加载本地,网络图片。而且支持图片的内存和本地缓存。 2. 详细设计 2.1 View模块 2.1.1 总体设计 流程和关系较少, 请看下面的详细分析 2.1.2 流程图 2.1.3 核心类功能介绍 请先了解注解 ,动态代理 可以帮助到您, 如果已经了解请忽略。 注解和反射知识是这个模块的主要内容 1.ViewUtils.java View和各种事件的注入以及资源的注入。 (1)主要函数 ` private static void injectObject(Object handler, ViewFinder finder) ` 第一个参数Object handler代表的是需要注入的对象, 第二个参数是需要注入View(这个View就是handler的成员变量)所在的View或者Activity的包装对象。 该方法完成了View和各种事件的注入以及资源的注入。主要的原理就是通过反射和注解。 完成Activity的setContentView。 完成View的注入。 完成资源的注入。 完成各种事件的注入。 2.ViewFinder.java (1)主要函数 ` public View findViewById(int id, int pid) public View findViewById(int id) ` 如果存在父View, 优先从父View寻找,否则从当前的View或者Activity中寻找。 3.ResLoader.java ` public static Object loadRes(ResType type, Context context, int id) ` 获取资源文件值。支持多种资源的获取。 ...

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

Android Universal Image Loader 源码分析

内容来自:https://github.com/android-cn/android-open-project-analysis 1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的、可高度定制的图片缓存,本文简称为UIL。 简单的说 UIL 就做了一件事——获取图片并显示在相应的控件上。 1.2 基本使用 1.2.1 初始化 添加完依赖后在Application或Activity中初始化ImageLoader,如下: `public class YourApplication extends Application { @Override public void onCreate() { super.onCreate(); ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this) // 添加你的配置需求 .build(); ImageLoader.getInstance().init(configuration); } } ` 其中 configuration 表示ImageLoader的配置信息,可包括图片最大尺寸、线程池、缓存、下载器、解码器等等。 1.2.2 Manifest 配置 `&lt;manifest&gt; &lt;uses-permission android:name="android.permission.INTERNET" /&gt; &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&gt; &lt;application android:name=".YourApplication" …… &gt; …… &lt;/application&gt; &lt;/manifest&gt; ` 添加网络权限。如果允许磁盘缓存,需要添加写外设的权限。 ...

2015年4月8日 · 10 分钟 · 天边的星星