Android进阶——ViewPager详解之初识ViewPager(一)
2016-08-04 22:43
579 查看
一、ViewPager
1、概述
ViewPager继承自ViewGroup,是左右两个屏幕平滑地切换的一个容器,容器里呈现的视图由对应的Adapter决定,和其他标准的AdapterView类似。简而言之就是我们通过Adapter把View放到ViewPager里,动动手指我们就可以实现左右滑动互相切换View了。另外ViewPager的更新不是直接由ViewPager本身去完成的,而是通过观察者去调用PagerAdapter的notifyDataSetChanged等相关方法去完成界面更新工作。
2、重要的成员
成员 | 说明 |
---|---|
public ViewPager (Context context) | |
public ViewPager (Context context, AttributeSet attrs) | |
interface ViewPager.OnPageChangeListener | 内部接口当切换不同Page时触发对应回调方法 |
void addView(View child, int index, ViewGroup.LayoutParams params) | 添加View到ViewPager里 |
boolean dispatchKeyEvent(KeyEvent event) | 派发键盘事件到下一个视图 |
ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) | |
PagerAdapter getAdapter() | 获取对应的适配器 |
int getCurrentItem() | 返回当前page的index |
int getOffscreenPageLimit() | Returns the number of pages that will be retained to either side of the current page in the view hierarchy in an idle state. |
int getPageMargin() | 返回Page之间的外间距 |
boolean onTouchEvent(MotionEvent ev) | 重写这个方法可以处理Touch事件 |
void removeView(View view) | 注意不能在 draw(android.graphics.Canvas), onDraw(android.graphics.Canvas), dispatchDraw(android.graphics.Canvas)或其他相关方法调用 |
void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) | 当the scroll position改变时触发,可以用于设置自定义的动画效果,即只要实现PageTransformer接口和其唯一的方法transformPage(View view, float position) |
voidsetOnPageChangeListener(ViewPager.OnPageChangeListener listener) | 设置Page切换事件监听 |
void setPageMarginDrawable(int resId) | |
void setAdapter(PagerAdapter adapter) | 设置Adapter |
二、重要的PagerAdapter
PagerAdapter其实是一个抽象类封装了一些接口、回调和功能方法,在实际开发过程中我们往往是使用它及其子类——FragmentPagerAdapter和FragmentStatePagerAdapter的子类来填充到ViewPager中,通俗点来说,ViewPager只是个空皮囊,只有填充了PagerAdapter才能发挥其作用,正所谓巧妇也难为无米之炊,PagerAdapter就是这里的米,有了米才能各显神通做出各种各样的饭。
1、实现PagerAdapter时必须要重写的四个成员方法
ViewPager不是直接与View关联的,而是通过一个key对象,通过这个key对象我们可以追踪并且唯一识别指定的page在PagerAdapter的位置。Object instantiateItem(ViewGroup Container, int position)——实例化item,PagerAdapter将选择将这个对象填充到在当前ViewPager里。
void destroyItem(ViewGroup container, int position, Object object)——将item从指定的位置移出容器
int getCount()——获取item的总数,一般都是获取集合的size
isViewFromObject(View,Object)——判断容器里的View是否与一个key值相关联,比如说例如Fragment+ViewPager的处理,每个页面都由它是对应的Fragment来呈现,但ViewPager并不是直接与View关联,而是关联一个key。我们实现这个方法也很简单谷歌推荐我们只需一句——return view == object;。
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ViewPagerAdapter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">PagerAdapter</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> List<View> mList; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ViewPagerAdapter</span>(List<View> list) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mList = list; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getCount</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mList != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && mList.size() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> mList.size(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isViewFromObject</span>(View view, Object object) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> view == object; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">destroyItem</span>(ViewGroup container, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position, Object object) { container.removeView((View) object); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="box-sizing: border-box;">instantiateItem</span>(ViewGroup container, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) { container.addView(mList.get(position)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> mList.get(position); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getItemPosition</span>(Object object) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> POSITION_NONE; } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li></ul>
2、PagerAdapter重要的成员方法
PagerAdapter的工作过程其实很简单,当ViewPager里的内容要改变的时候,就调用startUpdate方法来完成,随即也会多次调用instantiateItem或者destroyItem方法,finishUpdate最后被调用来完成更新工作。finishUpdate最终会返回需要添加到容器里的View和对应的 key对象(通过instantiateItem完成);而一些传递到destroyItem的则被移除。成员方法 | 说明 |
---|---|
void finishUpdate(ViewGroup container) | 当完成page的更新工作时被调用 |
int getItemPosition(Object object) | 但需要确定item位置是否改变时被调用,默认实现永远返回-1 |
void notifyDataSetChanged() | 但需要去更新的时候我们可以去调用这个方法完成 |
void registerDataSetObserver(DataSetObserver observer) | 注册观察者 |
void unregisterDataSetObserver(DataSetObserver observer) | 取消注册 |
void restoreState(Parcelable state, ClassLoader loader) | |
Parcelable saveState() |
3、FragmentPagerAdapter
FragmentPagerAdapter继承自PagerAdapter,主要的成员方法功能都是大同小异的,这个适配器主要就是用于快速实现Fragment在ViewPager里面进行滑动切换的,所以,如果我们想实现Fragment的左右滑动,优先选择ViewPager+FragmentPagerAdapter模式,因为FragmentPagerAdapter拥有自己的缓存策略,当配合ViewPager配合使用时,会缓存当前Fragment以及左边一个、右边一个(一共三个Fragment对象)假设有三个Fragment,那么在ViewPager初始化之后,3个fragment都会加载完成,中间的Fragment在整个生命周期里面只会加载一次,当最左边的Fragment处于显示状态,最右边的Fragment由于超出缓存范围,会被销毁,当再次滑到中间的Fragment的时候,最右边的Fragment会被再次初始化。所以比较适合用户制作较少页面切换的tab界面(最多3个),FragmentPagerAdapter会对我们浏览过Fragment进行缓存,保存这些界面的临时状态,这样当我们左右滑动的时候,界面切换更加的流畅。但是,这样也会增加程序占用的内存。那么3个以上的话,谷歌推荐移步到FragmentStatePagerAdapter。
3.1、当我们使用FragmentPagerAdapter的时候,它的宿主ViewPager**必须设置对应的id,同时必须实现两个方法和构造方法**。
getCount()——返回的是ViewPager页面的数量,即Fragement的数量。getItem(int position)——返回的是要显示的fragment对象。
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//实现一个FragmentPagerAdapter最少只需要实现getCount和getItem方法即可</span> FragmentPagerAdapter fragmentadapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> FragmentPagerAdapter( getSupportFragmentManager()) { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getCount</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> fragments.size(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//getCount()返回的是ViewPager页面的数量,多少个Fragement对应多少个页面</span> } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Fragment <span class="hljs-title" style="box-sizing: border-box;">getItem</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> fragments.get(position);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回的是要显示的fragment对象。</span> } } }; </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
4、FragmentStatePagerAdapter
当然除了FragmentPagerAdapter之外,还有一个类也是专门用于快速实现多个(3个以上)Fragment在ViewPager里面进行适配并滑动切换的,即FragmentStatePagerAdapter。FragmentStatePagerAdapter也直接继承自PagerAdapter的,其工作方式和ListView十分相似的。当Fragment对用户不可见的时候,整个Fragment会被销毁并且保存Fragment的保存状态。基于这样的特性,FragmentStatePagerAdapter比FragmentPagerAdapter更适合用于很多界面之间的转换,而且消耗更少的内存资源。
3.1、当我们使用FragmentStatePagerAdapter的时候,它的宿主ViewPager必须设置对应的id,同时必须实现两个方法。
getCount()——返回的是ViewPager页面的数量,即Fragement的数量。getItem(int position)——返回的是要显示的fragment对象。
5、关于使用中发现,在删除或者修改数据的时候,PagerAdapter无法像BaseAdapter那样仅通过notifyDataSetChanged方法通知刷新View。
通常情况下调用notifyDataSetChanged方法会让ViewPager通过Adapter的getItemPosition方法查询一遍所有child view,如果所有child view位置均为POSITION_NONE,表示所有的child view都不存在,ViewPager会调用destroyItem方法销毁,并且重新生成,从而加大系统开销,并在一些复杂情况下导致逻辑问题。特别是对于只是希望更新child view内容的时候,但造成了完全不必要的开销,列表内容如果是针对于child view比较简单的情况(例如仅有TextView、ImageView等,没有ListView等展示数据的情况),可以重写PagerAdapter的方法getItemPosition
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">@Override <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getItemPosition</span>(Object <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> POSITION_NONE; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
但复杂的情况则需要根据自己的需求来实现notifyDataSetChanged的功能,比如,在仅需要对某个View内容进行更新时,在instantiateItem()时,用View.setTag方法加入标志,在需要更新信息时,通过findViewWithTag的方法找到对应的View进行局部更新。
6、FragmentPagerAdapter和FragmentStatePagerAdapter
FragmentPagerAdapter适合在较少Fragment滑动切换的界面使用的,划过的fragment会保存在内存中,尽管已经划过。而FragmentStatePagerAdapter和ListView有点类似,只会保存当前界面,以及下一个界面和上一个界面(如果有),最多保存3个,其他会被销毁掉。最后要注意的是FragmentStatePagerAdapter可能不经意间会造成内存未正常回收,严重导致内存溢出,比如图片资源没有释放,资源引用问题。(之前在网上看到过EditText由于保存焦点导致Fragment未被释放而导致OOM,设置edtText.saveEanble(false)就可以解决此问题)。最后PagerAdapter都只是数据集,数据集的改变只能发生在主线程里并且以必须调用notifyDataSetChanged()来通知完成更新。
小结
这篇主要是简单描述了下ViewPager的主要功能以及PagerAdapter的角色和一些简略的原理,由于篇幅问题,下一篇再结合实例来总结下。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories