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

原创粉丝点击