先看一下引导页的效果图
具体步骤
1.先从一个主页进入,判断是不是第一次进入,如果是第一次就跳转到引导页不是就跳转到登录页(BaseActivity为个人项目的其他页面所用,一般继承默认的Activity就行)
package com.fb.hckjfb.activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import com.fb.hckjfb.R;
/**
* 主程序入口,也就是主页
*/
public class SplashActivity extends BaseActivity {
//是否是第一次使用
private boolean isFirstUse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
initView();
SharedPreferences preferences = getSharedPreferences("isFirstUse", MODE_PRIVATE);
isFirstUse = preferences.getBoolean("isFirstUse", true);
/**
*如果用户不是第一次使用则直接调转到显示界面,否则调转到引导界面
*/
if (isFirstUse) {
startActivity(new Intent(act, GuideActivity.class));
} else {
startActivity(new Intent(act, HandlerActivity.class));
}
finish();
//实例化Editor对象
SharedPreferences.Editor editor = preferences.edit();
//存入数据
editor.putBoolean("isFirstUse", false);
//提交修改
editor.commit();
}
@Override
protected int getLayoutID() {
return R.layout.activity_splash;
}
@Override
protected void initListener() {
}
@Override
protected void initView() {
}
@Override
protected void initData() {
}
}
activity_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
2.第一次进入则到引导页
activity_guide.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:id="@+id/activity_guide"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/vp_guide"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/start_btn"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="100dp"
android:background="@drawable/shape_boder"
android:gravity="center"
android:padding="10dp"
android:text="点击进入"
android:textColor="@color/Qblue"
android:visibility="invisible" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="60dp">
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"></LinearLayout>
<ImageView
android:id="@+id/iv_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:src="@drawable/shape_point2" />
</RelativeLayout>
</RelativeLayout>
drawable下的shape_point1.xml自定义小圆点
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/Qblue" />
<size
android:width="10dp"
android:height="10dp" />
</shape>
drawable下的shape_point2.xml自定义椭圆长点
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/Qblue" />
<size
android:width="30dp"
android:height="10dp" />
<!-- 边角圆弧的半径 -->
<corners android:radius="10dp" />
</shape>
java代码
package com.fb.hckjfb.activity;
import android.content.Intent;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.fb.hckjfb.DepthPageTransformer;
import com.fb.hckjfb.R;
import java.util.ArrayList;
/**
* 引导页
*/
public class GuideActivity extends BaseActivity {
private ViewPager mViewPager;
private int[] mImageIds = new int[]{R.drawable.iv_ydy1, R.drawable.iv_ydy2, R.drawable.iv_ydy3};
private ArrayList<ImageView> mImageViewList;
private LinearLayout llContainer;
private ImageView ivRedPoint;
private int mPaintDis;
private Button start_btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_guide);
initView();
}
@Override
protected int getLayoutID() {
return R.layout.activity_guide;
}
@Override
protected void initListener() {
}
@Override
protected void initView() {
mViewPager = (ViewPager) findViewById(R.id.vp_guide);
llContainer = (LinearLayout) findViewById(R.id.ll_container);
ivRedPoint = (ImageView) findViewById(R.id.iv_red);
start_btn = (Button) findViewById(R.id.start_btn);
start_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击进入的时候直接跳转到登录界面
Intent intent = new Intent(act, LoginActivity.class);
startActivity(intent);
finish();
}
});
initData();
GuideAdapter adapter = new GuideAdapter();
//添加动画效果
mViewPager.setPageTransformer(true, new DepthPageTransformer());
mViewPager.setAdapter(adapter);
//监听布局是否已经完成 布局的位置是否已经确定
ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//避免重复回调 出于兼容性考虑,使用了过时的方法
ivRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//布局完成了就获取第一个小灰点和第二个之间left的距离
mPaintDis = llContainer.getChildAt(1).getLeft() - llContainer.getChildAt(0).getLeft();
System.out.println("距离:" + mPaintDis);
}
});
//ViewPager滑动Pager监听
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
//滑动过程中的回调
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//当滑到第二个Pager的时候,positionOffset百分比会变成0,position会变成1,所以后面要加上position*mPaintDis
int letfMargin = (int) (mPaintDis * positionOffset) + position * mPaintDis;
//在父布局控件中设置他的leftMargin边距
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) ivRedPoint.getLayoutParams();
params.leftMargin = letfMargin;
ivRedPoint.setLayoutParams(params);
}
/**
* 设置按钮最后一页显示,其他页面隐藏
* @param position
*/
@Override
public void onPageSelected(int position) {
System.out.println("position:" + position);
if (position == mImageViewList.size() - 1) {
start_btn.setVisibility(View.VISIBLE);
} else {
start_btn.setVisibility(View.GONE);
}
}
@Override
public void onPageScrollStateChanged(int state) {
System.out.println("state:" + state);
}
});
}
class GuideAdapter extends PagerAdapter {
//item的个数
@Override
public int getCount() {
return mImageViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
//初始化item布局
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView view = mImageViewList.get(position);
container.addView(view);
return view;
}
//销毁item
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
@Override
protected void initData() {
mImageViewList = new ArrayList<>();
for (int i = 0; i < mImageIds.length; i++) {
//创建ImageView把mImgaeViewIds放进去
ImageView view = new ImageView(this);
view.setBackgroundResource(mImageIds[i]);
//添加到ImageView的集合中
mImageViewList.add(view);
//小圆点
ImageView pointView = new ImageView(this);
pointView.setImageResource(R.drawable.shape_point1);
//初始化布局参数,父控件是谁,就初始化谁的布局参数
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
if (i > 0) {
//当添加的小圆点的个数超过一个的时候就设置当前小圆点的左边距为20dp;
params.leftMargin = 20;
}
//设置小灰点的宽高包裹内容
pointView.setLayoutParams(params);
//将小灰点添加到LinearLayout中
llContainer.addView(pointView);
}
}
}
到第三张引导页时点击进入后达到登录页面
3.当第二次再进入的时候直接就进入了欢迎界面,3秒后自动跳转到登录界面
欢迎界面activity_handler.xml(这里只放了一张图片,如果有兴趣可以自定义布局)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/iv_handler">
</LinearLayout>
java代码
package com.fb.hckjfb.activity;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import android.view.WindowManager;
import com.fb.hckjfb.R;
public class HandlerActivity extends BaseActivity {
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_handler);
initView();
handler.sendEmptyMessageDelayed(0, 3000);
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
intent = new Intent(act, LoginActivity.class);
startActivity(intent);
//执行一次后销毁本页面
finish();
}
};
@Override
protected int getLayoutID() {
return R.layout.activity_handler;
}
@Override
protected void initListener() {
}
@Override
protected void initView() {
}
@Override
protected void initData() {
}
}
就这样一个引导和欢迎进入就完成了,收藏一下不用每次就费好大劲去找资料了。
优化
效果
SharedPreferences优化为MMKV,加入沉浸状态栏immersionbar,使用viewBinding
MMKV依赖库地址:https://github.com/Tencent/MMKV
immersionbar依赖库:https://github.com/gyf-dev/ImmersionBar
viewPage切换动画
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static float MIN_SCALE = 0.75f;
@Override
public void transformPage(@NonNull View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}