Android中ViewPager的使用---第一次进入软件时的引导页

现在大部分的软件在安装完之后,第一次打开都会出现引导页,这些引导页就是通过ViewPager来实现的,本篇内容就是关于ViewPager中引导页的实现过程

首先我们要在主布局中添加一个用于承载ViewPager的控件以及导航点控件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

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

    <!-- 这是导航点控件的布局 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="10dp"
        android:gravity="center">

        <ImageView
            android:id="@+id/dot1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="@drawable/dot_selected"/>

        <ImageView
            android:id="@+id/dot2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="@drawable/dot_normal"/>

        <ImageView
            android:id="@+id/dot3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="@drawable/dot_normal"/>

        <ImageView
            android:id="@+id/dot4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="@drawable/dot_normal"/>
    </LinearLayout>
</RelativeLayout>

然后我们在WelcomeActivity中添加引导页

//实现OnPageChangeListener,用于监听图片的滑动,然后改变导航点的状态
public class WelcomeActivity extends Activity implements ViewPager.OnPageChangeListener{   

    private ViewPager pager;
    private List<View> views;  //存放引导页View的集合
    private ImageView[] dots;
    private int[] ids = new int[]{ R.id.dot1,R.id.dot2,R.id.dot3,R.id.dot4};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        pager = (ViewPager) findViewById(R.id.viewpager);  //获取ViewPager控件

        initViews();  //初始化各个引导页
        initDots();  //初始化导航点

        //ViewPager需要使用适配器,将views通过适配器添加到布局中
        ViewPagerAdapter adapter = new ViewPagerAdapter(views);   //自定义的适配器
        pager.setAdapter(adapter);   
        pager.setOnPageChangeListener(this);  //添加回调接口,用于监听引导页滑动,从而改变导航点
}

    //初始化引导页
    private void initViews() {
        views = new ArrayList<>();  //List是一个接口,不能实例化,需要实例化一个ArrayList或者LinkedList
        LayoutInflater inflater = LayoutInflater.from(this);
        views.add(inflater.inflate(R.layout.one, null));  //给views添加引导页,使用的是布局one.xml
        views.add(inflater.inflate(R.layout.two, null));
        views.add(inflater.inflate(R.layout.three, null));
        views.add(inflater.inflate(R.layout.four, null));
    }

    //初始化导航点
    private void initDots() {
        dots = new ImageView[ids.length];
        for (int i=0;i<ids.length;i++){
            dots[i] = (ImageView) findViewById(ids[i]);
        }
    }


    //实现OnPageChangeListener接口需要重写此方法,作用:页面被滑动的时候调用
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {   
    }

    //实现OnPageChangeListener接口需要重写此方法,作用:新的页面被选中的时候调用
    @Override
    public void onPageSelected(int position) {
        for (int i = 0; i<dots.length;i++){
            if (i == position){  //设置当前被选中的引导页对应的导航点为dot_selected.png
                dots[i].setImageResource(R.drawable.dot_selected);
            }else {  //设置当前被选中的引导页对应的导航点为dot_normal.png
                dots[i].setImageResource(R.drawable.dot_normal);
            }
        }
    }

    //实现OnPageChangeListener接口需要重写此方法,作用:滑动状态改变的时候被调用
    @Override
    public void onPageScrollStateChanged(int state) {
    }
 }

适配器ViewPagerAdapter

public class ViewPagerAdapter extends PagerAdapter {  //继承PagerAdapter
    private List<View> views;

    public ViewPagerAdapter(List<View> views){
        this.views = views;
    }

    @Override
    public int getCount() {   //获取引导页数量,这里我们返回集合views的大小
        return views.size();
    }

/** 
*PagerAdapter最多只能缓存三张要显示的图片,如果滑动的图片超出了缓存的范围,就会调用这个方法,将图片
*销毁,(( 如果引导页有三张及以上,此方法必须重写!!否则程序会崩溃,所以建议无论引导页数量多少,都重写此
*方法,避免日后增加引导页引发错误))
*/
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(views.get(position));
        System.out.println("引导页"+position+"被销毁");
    }

/**
*当要显示的图片可以进行缓存的时候,会调用这个方法进行显示图片的缓存初始化,我们将要显示的ImageView
*加入到ViewGroup中,然后作为返回值返回即可
*/
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(views.get(position));
        System.out.println("引导页"+position+"被缓存");
        return views.get(position);
    }

/**
*判断instantiateItem(ViewGroup, int)函数所返回来的View与一个页面视图View是否是代表的同一个视图
*(即它俩是否表示同一个View)
*/
    @Override
    public boolean isViewFromObject(View view, Object object) {  
        return (view == object);
    }
}

注:如果引导页只有两张或一张,在定义适配器的时候,可以不用重写destroyItem方法,但是三张以上时必须重写destroyItem方法,所以为了避免日后增加引导页出错,建议一定要重写此方法。

关于缓存的顺序问题:
假如现在有A、B、C、D四张图片,程序运行后首先会缓存A和B,ViewPagerAdapter中只缓存了两张图片,当我们从A滑动到B的时候,C便会在此时进行缓存处理,ViewPagerAdapter中则缓存了三张图片。当我们从B滑动到C的时候,此时ViewPagerAdapter已经缓存三张图片,无法再缓存D,所以此时就会先调用destroyItem将A销毁掉,然后再缓存D进来。我将这个缓存制作成了Gif图:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AidenWU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值