优雅的让Fragment整合到ViewPager中

一、概要

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
其他出处均为转载,原创作品,欢迎读者批评指正。

猜你喜欢

转载自blog.csdn.net/shaoduo/article/details/75193852
今日推荐