ViewPager 从入门到带你撸个启动页之Fragment+ViewPager

Fragment+ViewPager的基本用法

1.FragmentPagerAdapter与FragmentStatePagerAdapter

  当ViewPager与Fragment结合使用时,我们所需要使用的数据适配器就已不再是PagerAdapter而是官方另外提供的FragmentPagerAdapter与FragmentStatePagerAdapter数据适配器,下面我们先来聊聊这两个FragmentPagerAdapter与FragmentStatePagerAdapter的使用方法及其主要区别。

  • FragmentPagerAdapter

  FragmentPagerAdapter 继承自 PagerAdapter。相比通用的 PagerAdapter,该类更专注于每一页均为 Fragment 的情况。该类内的每一个生成的 Fragment 都将保存在内存之中,尽管不可见的视图有时会被销毁,但用户所有访问过的fragment都会被保存在内存中,因此fragment实例会保存大量的各种状态,这就造成了很大的内存开销。所以FragmentPagerAdapter比较适用于那些相对静态的页,数量也比较少的应用情景,如主流主界面;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。对应实现FragmentPagerAdapter ,我们只需重写getCount()与getItem()两个方法,因此相对于继承自 PagerAdapter,更方便一些。接下来我们来看看如何用代码实现FragmentPagerAdapter

 class MyFragmentAdapter extends FragmentPagerAdapter{

        List<Fragment> list;

        public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
}

代码相当简单,我们这里简单以下两个函数

  • getItem(int position)

    这个函数实际上是根据下标position需要展示的fragment界面,该方法是在PagerAdapter#instantiateItem()方法中被调用的,大家只要看一下FragmentPagerAdapter源码就清晰了。

  • getCount()
    这个函数就更简单了,返回需要展示的fragment的总个数。

到此我们就对FragmentPagerAdapter介绍完了,下面我们接着看看FragmentStatePagerAdapter类。

  • FragmentStatePagerAdapter

  FragmentStatePagerAdapter 和 FragmentPagerAdapter 一样,是继承子 PagerAdapter。但是它们的不同点在于其类名中的 ‘State’ 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,再生成新的页面。这样实现的最大好处在于当拥有大量的页面时,不必在内存中占用大量的内存。我们在实现FragmentStatePagerAdapter是也同样只需重写getCount()与getItem()两个方法,而且其方法含义跟FragmentPagerAdapter是一样的。下面我们来看看实现案例,其实就改了个继承类而已。

class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

        List<Fragment> list;

        public MyFragmentStateAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }

 从代码的角度来看就换了继承类,其他都没有变化。最后我们来实现一个简单例子;
我们先来编写需要的Fragment布局.fragment.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv"
        android:textSize="20dp"
        android:textColor="@color/white"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

FragmentView.java代码如下:

package com.zejian.activity;

package com.zejian.viewpager;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class FragmentView extends Fragment {

    private Bundle arg;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        arg=getArguments();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       View view= inflater.inflate(R.layout.fragment,null);
        TextView tv= (TextView) view.findViewById(R.id.tv);
        int page=arg.getInt("pager_num");

        if (page==1){
            view.setBackgroundResource(R.color.colorAccent);
        }else if(page==2){
            view.setBackgroundResource(R.color.greed);
        }else if(page==3){
            view.setBackgroundResource(R.color.red);
        }else if(page==4){
            view.setBackgroundResource(R.color.colorPrimary);
        }

        tv.setText(arg.getString("Title"));
        return view;
    }


   public static FragmentView newInstance(Bundle args) {
        FragmentView fragment = new FragmentView();
        fragment.setArguments(args);
        return fragment;
    }

}

Fragment的代码也很清新,我们通过传递过来的参数去判断每个fragment的背景颜色,并设置标题名称,最后返回我们需要展示的view。我们再来看看actvity的布局文件 activity_vp_fg.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>
</LinearLayout>

VP_FG_Activity.java

package com.zejian.viewpager;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class VP_FG_Activity extends FragmentActivity {

    private ViewPager viewPager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vp_fg);
        viewPager= (ViewPager) findViewById(R.id.vp);
        initData();
    }

    public void initData(){

        List<Fragment> list=new ArrayList<>();

        Bundle bundle1=new Bundle();
        bundle1.putString("Title","第一个Fragment");
        bundle1.putInt("pager_num",1);
        Fragment fg1=FragmentView.newInstance(bundle1);

        Bundle bundle2=new Bundle();
        bundle2.putString("Title","第二个Fragment");
        bundle2.putInt("pager_num",2);
        Fragment fg2=FragmentView.newInstance(bundle2);

        Bundle bundle3=new Bundle();
        bundle3.putString("Title","第三个Fragment");
        bundle3.putInt("pager_num",3);
        Fragment fg3=FragmentView.newInstance(bundle3);

        Bundle bundle4=new Bundle();
        bundle4.putString("Title","第四个Fragment");
        bundle4.putInt("pager_num",4);
        Fragment fg4=FragmentView.newInstance(bundle4);

        list.add(fg1);
        list.add(fg2);
        list.add(fg3);
        list.add(fg4);

        viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),list));

    }

    class MyFragmentAdapter extends FragmentPagerAdapter{

        List<Fragment> list;

        public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }
    class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

        List<Fragment> list;

        public MyFragmentStateAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }
}

在Activity我们通过以下代码去初始化ViewPager所需要的数据

List<Fragment> list=new ArrayList<>();

Bundle bundle1=new Bundle();
bundle1.putString("Title","第一个Fragment");
bundle1.putInt("pager_num",1);
Fragment fg1=FragmentView.newInstance(bundle1);

Bundle bundle2=new Bundle();
bundle2.putString("Title","第二个Fragment");
bundle2.putInt("pager_num",2);
Fragment fg2=FragmentView.newInstance(bundle2);

Bundle bundle3=new Bundle();
bundle3.putString("Title","第三个Fragment");
bundle3.putInt("pager_num",3);
Fragment fg3=FragmentView.newInstance(bundle3);

Bundle bundle4=new Bundle();
bundle4.putString("Title","第四个Fragment");
bundle4.putInt("pager_num",4);
Fragment fg4=FragmentView.newInstance(bundle4);

list.add(fg1);
list.add(fg2);
list.add(fg3);
list.add(fg4);

viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),list));
最后把数据时适配器MyFragmentAdapter设置给ViewPager,这样就完成数据的填充。这里有点要注意的是,Activity继承自FragmentActivity,只有FragmentActivity才能内嵌fragment页面,普通Activity是不行的。我们运行一下程序,效果如下:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值