简介
我们首次下载一个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;
}
}
手势操作这里我进行了判断是否有按钮,有了点击按钮跳转,没有则滑动跳转。
自此封装已经完成,别的项目中只需要把此类拷贝过去,直接用就可以了。