相信大家对Fragment不陌生,使用Fragment,一方面Fragment依赖于Activity,需要再Activity 中安放一个Fragment的位置,另一方面,需要管理打点好Fragment的生命周期。Activity中有个FragmentManager,通过FragmentManager其内部维护fragment队列,以及fragment事务的回退栈。
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的适配类。
使用了一个简单的线性布局。
<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>
每个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
<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>
FragmentPagerAdapter试将Fragments 数据绑定到ViewPager上。它的使用有点类似ListView的适配器。
代码:
/**
* Created by shaoduo on 2017-07-14.
*/
public class MainPagerAdapter extends FragmentPagerAdapter {
List fragments ;
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
public MainPagerAdapter(FragmentManager fm, List 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 mList;
private String[] mStrings;
/**
* @param fm
* @param list
* @param titles PageTitles
*/
public QuickFragmentPageAdapter(FragmentManager fm, List 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];
}
}
负责呈现ViewPager和组织显示Tab选项卡的Activity,其XML布局文件应该包含两部分,——ViewPager 和 Tab
所以activity_mainiter.xml文件应该这样写:
<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 fragmentList = new ArrayList() ;
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
其他出处均为转载,原创作品,欢迎读者批评指正。