ViewPager 的用法详解
来源:互联网 发布:淘宝图片推荐几款相机 编辑:程序博客网 时间:2024/05/17 01:05
现在很多浏览类型app都是viewpager + fragment + 自定义tab的组合,比如网易新闻,优酷等。
使用这种组合的好处: 可以在一个Activity中处理多个页面,方便用户操作,视图结构清晰。
一、 viewpager 对应的几个adapter
PagerAdapter: 一般适配器,图片,view,Fragment都行。
FragmentPagerAdapter: 为PageAdapter子类,适用于数量较少的Fragment为页面。特点,每一个生成的Fragment都将保存到内存中,当不可见时,销毁Fragment的view,调用onDestroyView; 用户体验好FragmentStatePagerAdapter: 为PageAdapter子类,适用于处理很多页,数据动态性较大,占用内存较多的Fragment为页面。 特点,当不可见时,整个Fragment都会销毁,调用onDestroy 和 onDestroyView; 数据需重新加载
一般PageAdapter中4个方法:
1. public int getCount(): 返回当前有效视图的个数。
2. public boolean isViewFromObject(View view, Object object): 该函数用来判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View)
3. public Object instantiateItem(ViewGroup container, int position): 这个函数的实现的功能是创建指定位置的页面视图。返回值:返回一个代表新增视图页面的Object(Key),这里没必要非要返回视图本身,也可以这个页面的其它容器。
4. public void destroyItem(ViewGroup container, int position, Object object): 该方法实现的功能是移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。
5. public CharSequence getPageTitle(int position): 使用系统PagerTabStrip PagerTitleStrip 返回的tab字符串
二、ViewPager 滑动页面的监听,一般可用于对自定义tab进行动画处理
//viewPager.setOnPageChangeListener(myOnPageChangeListener); 被弃用。 下面区别是将listener放入集合中 viewPager.addOnPageChangeListener(myOnPageChangeListener); private MyOnPageChangeListener myOnPageChangeListener = new MyOnPageChangeListener(); public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener { @Override //滑动的过程调用 位置 当前页面屏幕的百分比 当前页面偏移的像素位置 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { Log.d("stormxz", "onPageScrolled 111"); } @Override //当前页面的位置 public void onPageSelected(int position) { Log.d("stormxz", "onPageScrolled 222"); } @Override //状态 1开始 2正在滑动 0结束 public void onPageScrollStateChanged(int state) { Log.d("stormxz", "onPageScrollStateChanged 333"); } }
一般用来对自定义tabbar 进行位置,动画设置
三、3种adapter使用Fragment + viewPager
1. PagerAdapter
package com.example.stormxz.viewpagerdemo;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v4.view.PagerAdapter;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;/** * Created by stormxz on 2017/9/6. */public class MyViewPagerAdapter extends PagerAdapter { private ArrayList<Fragment> fragments = new ArrayList<Fragment>(); private ArrayList<String> titles = new ArrayList<String>(); private FragmentManager fragmentManager = null; public MyViewPagerAdapter(ArrayList<Fragment> viewArrayList, ArrayList<String> titlesList, FragmentManager fragmentManager) { this.fragments = viewArrayList; this.titles = titlesList; this.fragmentManager = fragmentManager; } @Override public int getCount() { //返回fragment 的个数 return fragments.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; //判读当前View是否一致 } @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment = fragments.get(position); if (fragment != null) { if (!fragment.isAdded()){ //判读当前fragment是否已经提交 ,如果没有,则创建事务,进行提交 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(fragment, fragment.getClass().getSimpleName()); fragmentTransaction.commitAllowingStateLoss(); /** * 在用FragmentTransaction.commit()方法提交FragmentTransaction对象后 会在进程的主线程中,用异步的方式来执行。 * 如果想要立即执行这个等待中的操作,就要调用这个方法(只能在主线程中调用)。 要注意的是,所有的回调和相关的行为都会在这个调用中被执行完成,因此要仔细确认这个方法的调用位置。 */ fragmentManager.executePendingTransactions(); } if (fragment.getView() != null) { container.addView(fragment.getView()); } } return fragment.getView(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(fragments.get(position).getView()); //removeView } @Override public CharSequence getPageTitle(int position) { return titles.get(position); //返回tab 文字信息 }}
MainActivity.java 传递FragmentManager tabname Fragment集合
myViewPagerAdapter = new MyViewPagerAdapter(fragments, titles, getSupportFragmentManager()); viewPager.setAdapter(myViewPagerAdapter);
一般不建议使用PagerAdapter. 建议使用其子类FragmentPagerAdapter 以及 FragmentStatePagerAdapter
2. FragmentPagerAdapter 与 FragmentStatePagerAdapter
只需要重新2个方法即可package com.example.stormxz.viewpagerdemo;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.app.FragmentStatePagerAdapter;import java.util.ArrayList;/** * Created by stormxz on 2017/9/11. */public class MyFragmentAdapter extends FragmentPagerAdapter { private ArrayList<Fragment> fragments = new ArrayList<Fragment>(); public MyFragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments) { super(fm); this.fragments = fragments; } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); }}
myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(), fragments); viewPager.setAdapter(myFragmentAdapter);
源码中已经实现
事务提交
判断fragment是否是当前的,是则设置为用户可见
1. 使用,将其作为子类View 放入ViewPager中@Override public Object instantiateItem(ViewGroup container, int position) { // If we already have this item instantiated, there is nothing // to do. This can happen when we are restoring the entire pager // from its saved state, where the fragment manager has already // taken care of restoring the fragments we previously had instantiated. if (mFragments.size() > position) { Fragment f = mFragments.get(position); if (f != null) { return f; } } if (mCurTransaction == null) { //获得事务 mCurTransaction = mFragmentManager.beginTransaction(); } Fragment fragment = getItem(position); if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment); if (mSavedState.size() > position) { Fragment.SavedState fss = mSavedState.get(position); if (fss != null) { fragment.setInitialSavedState(fss); } } while (mFragments.size() <= position) { mFragments.add(null); } fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); //设置为不可见 mFragments.set(position, fragment); mCurTransaction.add(container.getId(), fragment); //添加Fragment return fragment; }
事务提交
@Override public void finishUpdate(ViewGroup container) { if (mCurTransaction != null) { mCurTransaction.commitNowAllowingStateLoss(); mCurTransaction = null; } }
判断fragment是否是当前的,是则设置为用户可见
@Override public void setPrimaryItem(ViewGroup container, int position, Object object) { Fragment fragment = (Fragment)object; if (fragment != mCurrentPrimaryItem) { if (mCurrentPrimaryItem != null) { mCurrentPrimaryItem.setMenuVisibility(false); mCurrentPrimaryItem.setUserVisibleHint(false); } if (fragment != null) { fragment.setMenuVisibility(true); fragment.setUserVisibleHint(true); } mCurrentPrimaryItem = fragment; } }
四、 系统PagerTabStrip PagerTitleStrip
<android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="368dp" android:layout_height="495dp" tools:layout_editor_absoluteY="8dp" tools:layout_editor_absoluteX="8dp"> <android.support.v4.view.PagerTabStrip android:id="@+id/pager_tab_strip" android:layout_width="wrap_content" android:layout_height="wrap_content"> </android.support.v4.view.PagerTabStrip><!-- <android.support.v4.view.PagerTitleStrip android:id="@+id/pager_title_strip" android:layout_width="wrap_content" android:layout_height="wrap_content"> </android.support.v4.view.PagerTitleStrip>--> </android.support.v4.view.ViewPager>
2. 在Adapter中传入tabname集合,并在不同位置进行提取
@Override public CharSequence getPageTitle(int position) { return titles.get(position); }
相同点:
(1)作为ViewPager内部控件进行使用,只需要重写adapter中的getPageTitle(return position的字符串)
(2) android:layout_gravity 属性设置为TOP或BOTTOM来将它显示在ViewPager的顶部或底部。
不同点: PagerTabStrip 支持点击tab进行跳转页面,有下划线; PagerTitleStrip 则无
主流app 不会用
阅读全文
0 0
- ViewPager 的用法详解
- viewpager的用法总结
- ViewPager的用法
- ViewPager的用法
- ViewPager的用法
- ViewPager的基本用法
- ViewPager的用法(1)
- ViewPager的用法
- Viewpager的用法
- ViewPager的用法
- ViewPager的简单用法
- viewpager的基本用法
- viewpager的基本用法
- ViewPager的PageTransformer用法
- 真正的ViewPager详解
- ViewPager的使用详解
- Android启动界面之ViewPager用法详解
- ViewPager的用法(一)
- (lintcode)第29题交叉字符串
- JVM垃圾回收策略和垃圾收集器
- Mac下卸载Nginx服务器
- 伪类和伪元素的区别(结论)
- 最大递增序列之和
- ViewPager 的用法详解
- css选择器
- matter.js学习笔记(六)--Composites.softBody()制造布料或球网
- js获取方法的返回值
- Failed to resolve: com.android.support:appcompat-v7:26.0.0
- python中的数组类型及特点
- C++学习
- 初入spring,理解aop和ioc思想
- TCP三次握手四次挥手详解