优雅的让Fragment整合到ViewPager中
来源:互联网 发布:html商城模板源码 编辑:程序博客网 时间:2024/06/11 06:00
一、概要
1.Fragment
相信大家对Fragment不陌生,使用Fragment,一方面Fragment依赖于Activity,需要再Activity 中安放一个Fragment的位置,另一方面,需要管理打点好Fragment的生命周期。Activity中有个FragmentManager,通过FragmentManager其内部维护fragment队列,以及fragment事务的回退栈。
2.ViewPager
ViewPager 的使用需要用到ViewPager以及它的适配器。
1.ViewPager的简介和作用
ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view
1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类。
2)ViewPager类需要一个PagerAdapter适配器类给它提供数据。
3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。
2.ViewPager的适配器
简介中提到了PagerAdapter,和ListView等控件使用一样,需要ViewPager设置PagerAdapter来完成页面和数据的绑定,这个PagerAdapter是一个基类适配器,我们经常用它来实现app引导图,它的子类有FragmentPagerAdapter和FragmentStatePagerAdapter,这两个子类适配器用于和Fragment一起使用,在安卓应用中它们就像listview一样出现的频繁。
二、效果
app的主体样式分很多种, 比如说QQ是侧滑菜单+碎片,微信是可以滑动的碎片形式等等,接下来,我们就用 Fragment+ViewPager 来做一下微信的效果。
三、加工和制造
我们知道图片中的每个tab对应的页面分别是一个fragment, 这些 fragment都在一个ViewPager 中,并且这个ViewPager 在一个 Activity中显示。所以我们需要创建几个Fragment 和一个Activity。使用ViewPager的适配器将 Fragment 联系起来并放到Activity中显示。姑且可以这么理解。
加工材料: 一个tab布局,几张Fragment及对应xml布局文件 , 一个Activity和布局文件,一个ViewPager的适配类。
1.打造底部选项卡Tab.xml
使用了一个简单的线性布局。
<?xml version="1.0" encoding="utf-8"?><LinearLayout android:layout_width="match_parent" android:layout_height="60dp" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" > <LinearLayout android:id="@+id/tab_lin_one" android:layout_width="10dp" android:layout_weight="1" android:orientation="vertical" android:gravity="center" android:layout_height="match_parent"> <ImageView android:id="@+id/tab_img_one" android:layout_width="40dp" android:layout_height="40dp" android:src="@mipmap/tab_img_pro" /> <TextView android:id="@+id/tab_text_one" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tab_one"/> </LinearLayout> <LinearLayout android:id="@+id/tab_lin_two" android:layout_width="10dp" android:layout_weight="1" android:orientation="vertical" android:gravity="center" android:layout_height="match_parent"> <ImageView android:id="@+id/tab_img_two" android:layout_width="40dp" android:layout_height="40dp" android:src="@mipmap/tab_img_team" /> <TextView android:id="@+id/tab_text_two" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tab_two"/> </LinearLayout> <LinearLayout android:id="@+id/tab_lin_three" android:layout_width="10dp" android:layout_weight="1" android:orientation="vertical" android:gravity="center" android:layout_height="match_parent"> <ImageView android:id="@+id/tab_img_three" android:layout_width="40dp" android:layout_height="40dp" android:src="@mipmap/tab_img_pers" /> <TextView android:id="@+id/tab_text_three" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tab_three"/> </LinearLayout></LinearLayout>
2.创建几张Fragment及对应xml布局文件
每个Fragment就是了Fragment类的 java类。
ProjectFragment . java
public class ProjectFragment extends Fragment{ LayoutInflater inflater ; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.fragment_project,container,false) ; setHasOptionsMenu(true); return view ; } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); }}
PersFragment . java
public class PersFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_pers,container,false) ; return view ; }}
TeamFragment . java
public class TeamFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_team,container,false) ; return view ; }}
对应的布局我就贴一个,其他两个套路一样。
project_layout.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#d799e8"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="项目" android:layout_gravity="center" /></LinearLayout>
3.创建所需要的ViewPager适配器FragmentPagerAdapter
FragmentPagerAdapter试将Fragments 数据绑定到ViewPager上。它的使用有点类似ListView的适配器。
代码:
/** * Created by shaoduo on 2017-07-14. */public class MainPagerAdapter extends FragmentPagerAdapter { List<Fragment> fragments ; public MainPagerAdapter(FragmentManager fm) { super(fm); } public MainPagerAdapter(FragmentManager fm, List<Fragment> fragments) { this(fm) ; this.fragments = fragments ; } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); }}
也可以用:
简化了的适配器QuickFragmentPageAdapter
你也可以使用简化了的适配器,使用泛型,不仅仅适应Fragment的集合,其他类型的数据集合都可以是适配到ViewPager当中。这样你就不会因为适配数据集合不一样而写N个Pager的适配器类了,是不是很屌,快来看看这个牛逼哄哄的泛型。
public class QuickFragmentPageAdapter<T extends Fragment> extends FragmentPagerAdapter { private List<T> mList; private String[] mStrings; /** * @param fm * @param list * @param titles PageTitles */ public QuickFragmentPageAdapter(FragmentManager fm, List<T> list, String[] titles) { super(fm); mList = list; mStrings = titles; } @Override public Fragment getItem(int position) { return mList.get(position); } @Override public int getCount() { return mList.size(); } @Override public CharSequence getPageTitle(int position) { return mStrings == null ? super.getPageTitle(position) : mStrings[position]; }}
4.创建Activity以及其xml文件
负责呈现ViewPager和组织显示Tab选项卡的Activity,其XML布局文件应该包含两部分,——ViewPager 和 Tab
所以activity_mainiter.xml文件应该这样写:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/mainer_pager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"> </android.support.v4.view.ViewPager> <include layout="@layout/tab" /></LinearLayout>
可以看到,tab.xml 使用 include标签导入到 我们的主Activity 当中的。
接着就是我们的主角:MainInterFaceActivity.java
它继承了FragmentActivity 实现了View.OnClickListener接口和,ViewPager.OnPageChangeListener 接口。OnClickListener接口是实现 选项卡点击事件,OnPageChangeListener 接口是为了监听我们的ViewPager滑动情况,其中有三个必须需要实现的方法onPageScrollStateChanged,onPageSelected,onPageScrolled。这里我们只重写onPageScrollStateChanged方法 ,其中的一个滑动停止时候的状态 CROLL_STATE_IDLE状态,
//监听当停止滑动时候,处于哪一页,并设置相应的颜色
if(ViewPager.SCROLL_STATE_IDLE==state)
{
int position = viewPager.getCurrentItem() ;
setTab(position);
}
我们只需要让他滑动完成后,让我们的tab 的图片和文字 变颜色即可。如果你想在滑动中实现一些效果,可以考虑其他的两种状态。
,唯一稍微麻烦一点的也就是当你滑动完成后,更换tab的图拍呢和文字颜色, 和你点击选项卡更换它的颜色。所以你从点击的角度出发, 我点击到哪个选项卡,获取到这个卡的位置,去设置相应卡的图片和文字颜色。你从滑动角度出发,当你滑动完成后,你获取viewPager.的当前的页面的索引然后再去设置相应选项卡的图片和文字颜色。
MainInterFaceActivity .java
代码如下:
public class MainInterFaceActivity extends FragmentActivity implements View.OnClickListener ,ViewPager.OnPageChangeListener{ //声明包括图片和文本的线性布局,后边用到了线性布局设置点击事件 private LinearLayout mLinerOne; private LinearLayout mLinerTwo; private LinearLayout mLinerThree; //声明 Tab图片 private ImageView mImgOne; private ImageView mImgTwo; private ImageView mImgThree; //声明 Fragment private Fragment tab_one =null ; private Fragment tab_two = null; private Fragment tab_three = null ; // 声明Tab文本 private TextView mTextOne ; private TextView mTextTwo ; private TextView mTextThree ; //声明ViewPager 和适配器 private ViewPager viewPager; private MainPagerAdapter pagerAdapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mainiter); initView(); initEvent(); initPager(); } private void initEvent() { mLinerOne.setOnClickListener(this); mLinerTwo .setOnClickListener(this); mLinerThree .setOnClickListener(this); viewPager.setOnPageChangeListener(this); } private void initView() { //初始化线性布局 mLinerOne = (LinearLayout) findViewById(R.id.tab_lin_one); mLinerTwo = (LinearLayout) findViewById(R.id.tab_lin_two); mLinerThree = (LinearLayout) findViewById(R.id.tab_lin_three); //初始化图片 mImgOne = findViewById(R.id.tab_img_one); mImgTwo = findViewById(R.id.tab_img_two); mImgThree = findViewById(R.id.tab_img_three); //初始化文字 mTextOne = findViewById(R.id.tab_text_one) ; mTextTwo = findViewById(R.id.tab_text_two) ; mTextThree = findViewById(R.id.tab_text_three) ; //初始化菜单栏 // Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); // setActionBar(toolbar); //初始化ViewPager viewPager = findViewById(R.id.mainer_pager); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.tab_lin_one: viewPager.setCurrentItem(0); setTab(0); break; case R.id.tab_lin_two: viewPager.setCurrentItem(1); setTab(1); break; case R.id.tab_lin_three: viewPager.setCurrentItem(2); setTab(2); break; } } public void initPager(){ viewPager.setCurrentItem(0);//设置第一页默认页 FragmentManager fm = getSupportFragmentManager() ; List<Fragment> fragmentList = new ArrayList<Fragment>() ; if(tab_one==null) { tab_one = new ProjectFragment() ; } if(tab_two == null ) { tab_two = new TeamFragment() ; } if(tab_three ==null) { tab_three = new PersFragment() ; } fragmentList.add(tab_one) ; fragmentList.add(tab_two) ; fragmentList.add(tab_three) ; pagerAdapter = new MainPagerAdapter(fm,fragmentList) ;//将数据构造到Adapger中 viewPager.setAdapter(pagerAdapter); //设置适配器 } //照片资源重置 public void resetTab() { //将图片和文字恢复原始色 mImgOne.setImageResource(R.mipmap.tab_img_pro); mImgTwo.setImageResource(R.mipmap.tab_img_team); mImgThree.setImageResource(R.mipmap.tab_img_pers); mTextOne.setTextColor(getResources().getColor(R.color.color_tab_nomal)); mTextTwo.setTextColor(getResources().getColor(R.color.color_tab_nomal)); mTextThree.setTextColor(getResources().getColor(R.color.color_tab_nomal)); } //根据点击到哪个页面来设置图片和文字颜色 public void setTab(int index) { resetTab(); switch (index) { case 0 : mImgOne.setImageResource(R.mipmap.tab_img_pro_focus); mTextOne.setTextColor(getResources().getColor(R.color.color_tab_focus)); break ; case 1 : mImgTwo.setImageResource(R.mipmap.tab_img_team_focus); mTextTwo.setTextColor(getResources().getColor(R.color.color_tab_focus));break ; case 2 : mImgThree.setImageResource(R.mipmap.tab_img_pers_focus); mTextThree.setTextColor(getResources().getColor(R.color.color_tab_focus)); break ; default: resetTab(); break ; } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { //监听当停止滑动时候,处于哪一页,并设置相应的颜色 if(ViewPager.SCROLL_STATE_IDLE==state) { int position = viewPager.getCurrentItem() ; setTab(position); } } //初始化菜单 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); return true ; }}
好了,搞定了这个Activity就大功造成,赶紧跑一下看看效果吧。
最后的最后附上源代码:
https://github.com/shaoduo123/Fragment-ViewPager-ToolBar-Demo
版权声明
author :shaoduo
原文来自:http://blog.csdn.net/shaoduo/article/details/75193852
其他出处均为转载,原创作品,欢迎读者批评指正。
- 优雅的让Fragment整合到ViewPager中
- TabLayout让Fragment在ViewPager中的滑动切换更优雅
- 优雅的让Fragment监听返回键
- 优雅的让Fragment监听返回键
- viewpager fragment中fragment的状态保存
- viewpager 中fragment 的生命周期
- ViewPager中Fragment的生命周期
- 关于viewpager+fragment中嵌套viewpager+fragment的问题处理:
- Android让Fragment加载到Activity中
- Android让Fragment加载到Activity中
- Android让Fragment加载到Activity中
- ViewPager +Fragment 中Fragment被预加载问题(ViewPager中Fragment的生命周期管理)
- 自定义Android FragmentPagerAdapter中相关Fragment加载到ViewPager的一点说明
- viewpager中fragment的生命周期管理
- Android中ViewPager+Fragment的基本使用
- Android中Fragment+ViewPager的配合使用
- viewpager中fragment的生命周期管理
- Android中ViewPager+Fragment的基本使用
- Android给图片添加认证水印
- final关键字 多态 抽象 作业
- java总结2
- SVN使用教程
- UOJ #82 [UR #7] 水题生成器
- 优雅的让Fragment整合到ViewPager中
- uva509 RAID
- hdu 1728 逃离迷宫
- hdu 5823(状压DP)
- 音乐播放器
- python中文字符截取乱码
- Android Git 笔记
- Android实现可左右滑动的选择控件
- java导出jar包以及jar内程序读取jar包外配置文件