android初次进入,用户引导页(蒙层效果)实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/smileiam/article/details/79668739
在一般app中,初次安装使用时,除了有用户引导图外,还经常会看到类似于新手使用手册的使用引导页,类似于activity添加了一层遮罩图。这种效果实现一般是在原activity上覆盖一层view,可以用自定义view来实现,也可以用设计师做好和屏幕匹配的图片后,
直接全部覆盖在activity上。因为一般引导图上的文字都会设计得比较活泼好看点,所以项目中这种也比较常见。
在github上有个标星很高的项目GuideView,确实实现了在原activity上添加引导图效果,但代码较多,但若想替换成设计师做好的图片,完全覆盖在原activity上,此工程并不能满足要求。
博主又从网上找了其他人的相关实现,android 半透明图层用户引导、用户指导、用户教导,教用户怎么使用app的页面制作,基本思想通过activity获取windowManager,在WindowManager层添加引导图,这样做不好的一点是,需要应用请求SYSTEM_ALERT_WINDOW权限(使弹窗显示在其他应用之上),这在以前6.0以下的机器下还好,毕竟所有权限都在安装时只要AndroidMainfest.xml中设定好,就可以使用。可是android6.0以后,此权限需要显式请求,为了显示个引导图,还需要单独请求权限,这对客户来说,非常不友好。而且android8.0以上的系统,单单一个SYSTEM_ALERT_WINDOW权限,还不足以在WindowManager上addView,在声明SYSTEM_ALERT_WINDOW 权限后,选择使用TYPE_SYSTEM_ALERT等;在Android O系统上的应用直接使用TYPE_APPLICATION_OVERLAY显示Alter Window。这样你的弹框可能还是在别人的弹窗之下,适配Android 8.0,请使用TYPE_APPLICATION_OVERLAY弹出悬浮窗,还需要申请OVERLAY的权限。
其实我们完全不需要在WindowManager层去addView,只要在ContentView层去addView就好了。WindowManager就是下图中的PhoneWindow,contentView在它的下一级。
在WindowManager层addView还会导致在显示引导图时,按了home键,引导图还显示在屏幕上,因为它是允许弹窗在其他应用之上,在windowManager上addView,使view添加在其他应用之上了,这反而是一个bug。所以我们只需要通过activity获取它的ContentView,并在ContentView层上addView添加我们的蒙层即可。即将原博主写的
 windowManager = context.getWindowManager(); 
 改成
ViewGroup content = (ViewGroup) context.findViewById(android.R.id.content);
即可。
具体实现代码如下:
1. 先定义好GuideUtil工具类
public class GuideUtil {
    private Context context;
    private ImageView imgView;
    private ViewGroup content;
    private static GuideUtil instance = null;
    /** 是否第一次进入该程序 **/
    private boolean isFirst = true;
    private int i =0;
    int img[] = new int[]{R.mipmap.kaipian_pic,R.mipmap.all_pic};
    int detailImageArray[] = new int[]{R.mipmap.zhangjie_pic, R.mipmap.banben_pic, R.mipmap.xuxie_pic};


    private GuideUtil() {
    }


    public static GuideUtil getInstance() {
        synchronized (GuideUtil.class) {
            if (null == instance) {
                instance = new GuideUtil();
            }
        }
        return instance;
    }


    private Handler handler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 1:
                    // 设置LayoutParams参数
                    final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
                    params.type = WindowManager.LayoutParams.TYPE_PHONE;
                    // 设置显示格式
                    params.format = PixelFormat.RGBA_8888;
                    // 设置对齐方式
                    params.gravity = Gravity.LEFT | Gravity.BOTTOM;
                    // 设置宽高
                    params.width = Util.getScreenWidth(context);
                    params.height = Util.getScreenHeight(context);
                    // 设置动画
//                    params.windowAnimations = R.style.view_anim;
                    // 添加到当前的界面上
                    content.addView(imgView, params);
                    break;
            }
        };
    };


    public void initGuide(Activity context, int mipmapRourcesId, int flag) {
        if (!isFirst) {
            return;
        }
        this.context = context;
        content = (ViewGroup) context.findViewById(android.R.id.content);
        // 动态初始化图层
        imgView = new ImageView(context);
        imgView.setLayoutParams(new WindowManager.LayoutParams(
                android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                android.view.ViewGroup.LayoutParams.MATCH_PARENT));
        imgView.setScaleType(ImageView.ScaleType.FIT_XY);
        imgView.setImageResource(mipmapRourcesId);
        handler.sendEmptyMessage(1);


        // 点击图层之后,将图层移除
        imgView.setOnClickListener(new View.OnClickListener() {


            @Override
            public void onClick(View arg0) {
                int[] stepImageArray = new int[]{};
                if (flag == 0) {//首页
                    stepImageArray = img;
                } else if (flag == 1) {
                    stepImageArray = detailImageArray;
                }
                if (i < stepImageArray.length) {
                    imgView.setImageResource(stepImageArray[i]);
                }
                if (i<stepImageArray.length){
                    i++;
                }else if (i==stepImageArray.length){
                    i=0;
                    content.removeView(imgView);
                }
            }
        });
    }


}

2. Activity中引用

先在相应的Activity中定义好需要显示的蒙层图

int img[] = new int[]{R.mipmap.num1,R.mipmap.num2}; 

使用guideUtil.initGuide()方法显示蒙层图

  1. GuideUtil guideUtil = GuideUtil.getInstance();  
  2. guideUtil.initGuide(MainActivity.this, img[0]);  

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页