如何优雅的为你的app添加启动引导页

简介

我们首次下载一个APP的时候,一般都会有一个可以滑动的引导页面用于介绍该APP的一些基本信息,通常我们都会用ViewPager来实现,本篇文章就对引导页面做了一个简单的封装,以便于开发中的复用。(效果图就不放了,大家应该都知道。。。)

使用
 ViewPager viewPager;
    ViewGroup viewGroup;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //构造方法传入ViewPager  ViewGroup  Intent
        AppStartUtils appStartUtils = new AppStartUtils(this,viewPager,viewGroup,new Intent(this,MainActivity.class));
        //设置指示器的图标(0 为选中 1 为为选中)
        appStartUtils.setIconResources(new int[]{R.mipmap.ic_launcher,R.mipmap.ic_launcher_round});
        //设置引导页图片(可以本地也可以传url)
        appStartUtils.setImageResources(new int[]{R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher_round});
//        appStartUtils.setImageResources(new String[]{"url","url","url"});
        appStartUtils.start();

    }

这里是基本的使用方法,你也可以继续封装源码这里:
点我下载

实现

想要实现此功能,一般情况下分三步:

1、创建一个ViewPager
2、创建对应的PagerAdapter
3、创建指示器ViewGroup

接下来我们依次实现上述步骤:

先上xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.project.lx.mystartapp.MainActivity">

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

    <LinearLayout
        android:id="@+id/view_appstart_indicator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="40dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal"/>

    <!-- 根据需求选择点击跳转还是滑动跳转可以不加按钮 -->
    <Button
        android:id="@+id/btn_appstart_skip"
        android:layout_width="wrap_content"
        android:text="点我跳转"
        android:textSize="36sp"
        android:layout_centerInParent="true"
        android:layout_height="wrap_content" />

</RelativeLayout>

这里很简单,就是放了一个ViewPager一个LinearLayout还有一个可以省略的Button
ViewPager是用来显示我们的导航图片的,我们要在封装类中动态去添加View;
LinearLayout是指示器,显示我们一共多少页面以及当前页面所在位置;
Button是用于末页点击跳转的按钮,我这里封装了末页继续滑动跳转,所以这个按钮也可以根据你的具体需求选择添加。

下面我们开始着手写封装类:

//上下文对象
    private Context context;
    //导航动画ViewPager(通过构造方法传过来)
    private ViewPager viewPager;
    //页面指示器
    private ViewGroup viewGroup;
    //ViewPager的视图数组
    private List<View> list;
    //每页展示的ImageView
    private ImageView imageView;
    //用于存放导航时的图片
    private ImageView[] imageViews;
    //计算当前页码
    private int currentPage;
    //图片资源路径
    private int[] imageResources;
    //网络图片资源url
    private String[] imageUrls;
    //指示器资源路径
    private int[] iconResources;
    //手势操作封装类
    private GestureDetector gestureDetector;
    //传入意图
    private Intent intent;
    //跳转按钮
    private Button button;
    //引导页页数
    private int len;
    //设置指示器大小(默认为60)
    private int iconPx = 60;
    //设置左右间距(默认为80)
    private int padding = 80;

    /**
     * 设置指示器大小
     *
     * @param iconPx
     */
    public void setIconPx(int iconPx) {
        this.iconPx = iconPx;
    }

    /**
     * 设置指示器间距
     *
     * @param padding
     */
    public void setPadding(int padding) {
        this.padding = padding;
    }

    /**
     * 设置跳转按钮
     *
     * @param button
     */
    public void setButton(Button button) {
        this.button = button;
    }

    /**
     * 设置指示器图标资源
     *
     * @param iconResources
     */
    public void setIconResources(int[] iconResources) {
        this.iconResources = iconResources;
    }

    /**
     * 设置导航页面图片资源
     *
     * @param imageResources
     */
    public void setImageResources(int[] imageResources) {
        this.imageResources = imageResources;
    }

    /**
     * 设置导航页面图片资源
     *
     * @param imageUrls
     */
    public void setImageResources(String[] imageUrls) {
        this.imageUrls = imageUrls;
    }

    /**
     * @param context
     * @param viewPager
     * @param indicator 指示器容器
     */
    public AppStartUtils(Context context, ViewPager viewPager, ViewGroup indicator) {
        this.context = context;
        this.viewPager = viewPager;
        this.viewGroup = indicator;
    }

    /**
     * @param context
     * @param viewPager
     * @param indicator
     * @param intent
     */
    public AppStartUtils(Context context, ViewPager viewPager, ViewGroup indicator, Intent intent) {
        this.context = context;
        this.viewPager = viewPager;
        this.viewGroup = indicator;
        this.intent = intent;
    }

    /**
     * 开始
     */
    public void start() {
        initData();
        initListener();
        //这里存储程序状态是否为第一次启动
        //SharedPreferencesUtils.putBoolean(context, "isFirst", false);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        list = new ArrayList<>();

        len = imageResources == null ? imageUrls == null ? 0 : imageUrls.length : imageResources.length;

        for (int i = 0; i < len; i++) {
            imageView = new ImageView(context);
            imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            if (imageResources != null){
                imageView.setImageResource(imageResources[i]);
            }
            if (imageUrls != null){
                //这里我用了Glide加载图片,当然用什么都可以的
                //Glide.with(context).load(imageUrls[i]).into(imageView);
            }
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            list.add(imageView);
        }

        imageViews = new ImageView[list.size()];
        for (int i = 0; i < imageViews.length; i++) {
            imageView = new ImageView(context);
            imageView.setLayoutParams(new ViewGroup.LayoutParams(iconPx, iconPx));
            imageView.setPadding(padding, 0, padding, 0);
            imageViews[i] = imageView;
            if (i == 0) {
                imageViews[i].setBackgroundResource(iconResources[0]);
            } else {
                imageViews[i].setBackgroundResource(iconResources[1]);
            }
            viewGroup.addView(imageViews[i]);
        }

        GuidePageAdapter guidePageAdapter = new GuidePageAdapter();
        viewPager.setAdapter(guidePageAdapter);
    }

    /**
     * 初始化接口
     */
    public void initListener() {

        GuidPageChangeListener guidPageChangeListener = new GuidPageChangeListener();
        viewPager.addOnPageChangeListener(guidPageChangeListener);

        gestureDetector = new GestureDetector(context, new IGestureDetectorListener());
        viewPager.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
            }
        });

    }

这里我代码中的注释很详细,大家应该都能看懂,主要就是通过构造方法传入对应的ViewPager,ViewGroup和一个Intent用于跳转。
里面有设置图片资源、设置指示器图标资源、设置指示器图标大小,设置指示器间距等方法。

下面我们需要写一个对应的PagerAdapter

/**
     * PagerAdapter类
     */
    class GuidePageAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = list.get(position);
            container.addView(view);
            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(list.get(position));
        }
    }

这里没什么好说的,简单的PagerAdapter;

接下来是对ViewPager的页面改变进行监听,和对手势操作进行监听

/**
     * 对ViewPager的页面改变进行监听
     */
    class GuidPageChangeListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            currentPage = position;
            for (int i = 0; i < imageViews.length; i++) {
                imageViews[position].setBackgroundResource(iconResources[0]);
                if (position != i) {
                    imageViews[i].setBackgroundResource(iconResources[1]);
                }
            }

            if (button != null){
                //判断是否是最后一页,若是则显示按钮

                if (position == len - 1){
                    button.setVisibility(View.VISIBLE);
                }else {
                    button.setVisibility(View.GONE);
                }
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

    /**
     * 对手势操作监听
     */
    class IGestureDetectorListener implements GestureDetector.OnGestureListener {

        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {

        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (button != null){
                return false;
            }

            if (currentPage == list.size() - 1) {
                if ((e1.getX() - e2.getX()) > 0) {
                    if (intent != null) {
                        context.startActivity(intent);
                        ((Activity) context).finish();
                    }
                }
            }
            return false;
        }
    }

手势操作这里我进行了判断是否有按钮,有了点击按钮跳转,没有则滑动跳转。
自此封装已经完成,别的项目中只需要把此类拷贝过去,直接用就可以了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值