安卓NewbieGuide实现蒙版引导层效果

本文详细介绍了如何在Android项目中使用NewbieGuide库,包括导入依赖、配置动画、添加高亮区域、设置引导页布局及事件监听,以及如何实现多引导页切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导入

项目的build.gradle添加

allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

module的build.gradle添加

dependencies {
	  compile 'com.github.huburt-Hu:NewbieGuide:v2.4.0'
	}

确保你的项目中已经依赖了appcompat-v7。

使用


Animation enterAnimation = new AlphaAnimation(0f, 1f);
        enterAnimation.setDuration(600);
        enterAnimation.setFillAfter(true);

        Animation exitAnimation = new AlphaAnimation(1f, 0f);
        exitAnimation.setDuration(600);
        exitAnimation.setFillAfter(true);

NewbieGuide.with(mActivity)
                    .setLabel("guide1")
                    //.setShowCounts(3)//控制次数
                    .alwaysShow(true)//总是显示,调试时可以打开
                    // 引导层显示隐藏监听
                    .setOnGuideChangedListener(new OnGuideChangedListener() {
                        @Override
                        public void onShowed(Controller controller) {
                            // 引导层显示

                        }

                        @Override
                        public void onRemoved(Controller controller) {
                            // 引导层消失,发送通知打开第二个蒙版引导层
                            ToastUtil.showShort(mContext,"引导层消失了");
                            EventBus.getDefault().post(new OpenGuideNext());

                        }
                    })
                    .addGuidePage(GuidePage.newInstance()
                            .addHighLight(view, HighLight.Shape.CIRCLE)
                            .setEverywhereCancelable(false)//是否点击任意位置消失引导页,默认为true
                            .setLayoutRes(R.layout.view_guide_simple,R.id.know)//引导页布局,点击跳转下一页或者消失引导层的控件id
                            // setOnLayoutInflatedListener设置布局填充完成的监听,当传入的xml(R.layout.view_guide_dialog)填充完成时会回答调用该监听,用于初始化自定布局的元素。
                            .setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
                                    @Override
                                    public void onLayoutInflated(View view, Controller controller) {
                                        // 引导页布局填充后回调,用于初始化
                                        Button tv = view.findViewById(R.id.clic);
                                        tv.setText("我是动态设置的文本");
                                        //当同一引导层包含多个引导页的时候可以在OnLayoutInflatedListener接口的回调方法中获取到controller对象,执行相应的操作
                                        controller.showPage(0);
                                    }
                                })
                            .setEnterAnimation(enterAnimation)//进入动画
                            .setExitAnimation(exitAnimation)//退出动画
                            .setBackgroundColor(getResources().getColor(R.color.title_light))//设置背景色,建议使用有透明度的颜色
                            // 为引导页布局中的某个控件添加点击事件监听
                            .setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
                                @Override
                                public void onLayoutInflated(View view, Controller controller) {
                                    Button btn = view.findViewById(R.id.clic);
                                    btn.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            Toast.makeText(mContext, "点击了按你", Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                }
                            }))
                    .show();
1,with方法可以传入Activity或者Fragment,获取引导页的依附者。Fragment中使用建议传入fragment,内部会添加监听,当依附的Fragment销毁时,引导层自动消失。
2,setLabel方法用于设置引导页的标签,区别不同的引导页,该方法必须调用设置,否则会抛出异常。内部使用该label控制引导页的显示次数。
3,addGuidePage方法添加一页引导页,这里的引导层可以有多个引导页,但至少需要一页。GuidePage.newInstance()即为创建一个引导页对象,并通过addHighLight添加一个或多个需要高亮的view,该方法有多个重载,可以设置高亮的形状,以及padding等(默认是矩形)。setLayoutRes方法用于引导页说明布局,就是上图的说明文字的布局。
4,show方法直接显示引导层,如果不想马上显示可以使用build方法返回一个Controller对象,完成构建。需要显示得时候再次调用Controller对象的show方法进行显示。
5,通常情况下引导页只在用户首次打开app的时候显示,第二次进入时不显示,因此默认只显示一次。当然你也可以通过.setShowCounts(3)自定义显示的次数,调试的时候可以使用.alwaysShow(true)设置每次都显示。就算设置了.alwaysShow(true),内部还是会记录显示得次数,之后改会setShowCounts(3)可能实际记录的次数早已超过限制,因此不会再次显示。使用Controller对象的resetLabel方法重置次数。(或者清除应用缓存也能重置次数)

主要方法说明:
1,addHighLight方法表示添加一个或多个需要高亮的view,即该方法可以重复调用,例如:

.addGuidePage(//添加一页引导页
    GuidePage.newInstance()//创建一个实例
       .addHighLight(button)//添加高亮的view
        .addHighLight(tvBottom, HighLight.Shape.RECTANGLE)
        .setLayoutRes(R.layout.view_guide)//设置引导页布局
        ...

同时该方法有多个重载,可以设置高亮的形状,以及padding等(默认是矩形),addHighLight方法有多个重写,完整参数如下:

/**
     * 添加需要高亮的view
     *
     * @param view          需要高亮的view
     * @param shape         高亮形状{@link com.app.hubert.guide.model.HighLight.Shape}
     * @param round         圆角尺寸,单位dp,仅{@link com.app.hubert.guide.model.HighLight.Shape#ROUND_RECTANGLE}有效
     * @param padding       高亮相对view的padding,单位px
     * @param relativeGuide 相对于高亮的引导布局
     */
    public GuidePage addHighLight(View view, HighLight.Shape shape, int round, int padding, @Nullable RelativeGuide relativeGuide)

一般我们只需要指定前两个参数即可,或者第一个参数即可:

.addHighLight(tvTitle) // 默认矩形
.addHighLight(tvTitle, HighLight.Shape.CIRCLE) // 设置为圆形

改进:
有些情况可能不太容易获得高亮view的引用,那么此时可以用添加高亮区域的方式来代替, 计算出需要高亮的view在anchor中位置,将获得的rectF传入addHighLight方法:

/**
     * 添加高亮区域
     *
     * @param rectF         高亮区域,相对于anchor view(默认是android.R.id.content)
     * @param shape         高亮形状{@link com.app.hubert.guide.model.HighLight.Shape}
     * @param round         圆角尺寸,单位dp,仅{@link com.app.hubert.guide.model.HighLight.Shape#ROUND_RECTANGLE}有效
     * @param relativeGuide 相对于高亮的引导布局
     */
    public GuidePage addHighLight(RectF rectF, HighLight.Shape shape, int round, @Nullable RelativeGuide relativeGuide)

例如:

 .addHighLight(new RectF(0, 800, 200, 1200))

多引导切换

上面说了addGuidePage方法用来添加一页引导页,这里的引导层可以有多个引导页,但至少需要一页,如果需要添加多个引导页,可以使用如下的形式:

private void showGuide() {
        Animation enterAnimation = new AlphaAnimation(0f, 1f);
        enterAnimation.setDuration(600);
        enterAnimation.setFillAfter(true);

        Animation exitAnimation = new AlphaAnimation(1f, 0f);
        exitAnimation.setDuration(600);
        exitAnimation.setFillAfter(true);


        NewbieGuide.with(mActivity)
                .setLabel("guide1")
                .alwaysShow(true)
                .setOnPageChangedListener(new OnPageChangedListener() {
                    @Override
                    public void onPageChanged(int page) {
                        //引导页切换,page为当前页位置,从0开始
                        Toast.makeText(mActivity, "引导页切换:" + page, Toast.LENGTH_SHORT).show();
                    }
                })
                .addGuidePage(//添加一页引导页
                        GuidePage.newInstance()//创建一个实例
                                .addHighLight(title01, HighLight.Shape.CIRCLE)//添加高亮的view
                                .setLayoutRes(R.layout.view_guide_simple)//设置引导页布局
                                .setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
                                    @Override
                                    public void onLayoutInflated(View view, Controller controller) {
                                        //引导页布局填充后回调,用于初始化
                                        Button tv = view.findViewById(R.id.clic);
                                        tv.setText("我是动态设置的文本");
                                        
                                    }
                                })
                                .setEnterAnimation(enterAnimation)//进入动画
                                .setExitAnimation(exitAnimation)//退出动画
                )
                .addGuidePage(
                        GuidePage.newInstance()
                                .addHighLight(title04, HighLight.Shape.CIRCLE)
                                .setLayoutRes(R.layout.view_guide_simple, R.id.know)//引导页布局,点击跳转下一页或者消失引导层的控件id
                                .setEverywhereCancelable(false)//是否点击任意地方跳转下一页或者消失引导层,默认true
//                                .setBackgroundColor(getResources().getColor(R.color.title_light))//设置背景色,建议使用有透明度的颜色
                                .setEnterAnimation(enterAnimation)//进入动画
                                .setExitAnimation(exitAnimation)//退出动画
                ).show();
    }

如果更多也可以继续.addGuidePage添加。

项目实际案例

在首页的srcollview中包含了多个RecyclerView模块,现在需求是需要某个RecyclerView中的第2个View高亮显示添加引导,一开始在Activity或者Fragment中通过manager.finidViewByPosition(1)和recycle.getchild(1),但是获取到的View对象一直为空,导致高亮区域不显示,最后索性将高亮设置的代码放置到了Adapter中,完美解决了问题,代码如下:

@Override
    protected void convert(BaseViewHolder helper, HomeTopItemBean item) {
       
       // ...

        LinearLayout view = helper.getView(R.id.root);
        
        // 获取当前item的索引
        int layoutPosition = helper.getLayoutPosition();

        if(layoutPosition == 1){
            NewbieGuide.with(mActivity)
                    .setLabel("guide1")
                    .alwaysShow(true)
                    .setOnGuideChangedListener(new OnGuideChangedListener() {
                        @Override
                        public void onShowed(Controller controller) {
                            // 引导层显示

                        }

                        @Override
                        public void onRemoved(Controller controller) {
                            // 引导层消失,发送通知打开第二个蒙版引导层
                            ToastUtil.showShort(mContext,"引导层消失了");
                            EventBus.getDefault().post(new OpenGuideNext());

                        }
                    })
                    .addGuidePage(GuidePage.newInstance()
                            .addHighLight(view, HighLight.Shape.CIRCLE)
                            .setEverywhereCancelable(false)//是否点击任意位置消失引导页,默认true
                            .setLayoutRes(R.layout.view_guide_simple,R.id.know)
                            .setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
                                @Override
                                public void onLayoutInflated(View view, Controller controller) {
                                    Button btn = view.findViewById(R.id.clic);
                                    btn.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            Toast.makeText(mContext, "点击了按你", Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                }
                            }))
                    .show();
        }
    }

适配器使用的是BaseRecyclerViewAdapterHelper,不会的同学可以看我的相关文章,但是这样又出现了一个新的问题,那就是现在需要多个引导页切换,而其他引导页的View引用并不在该Adapter中,比如第二个引导页是为首页其他另外模块内的某个控件添加,就无法像上面所说的,通过不断地追加.addGuidePage的方式来实现,我的解决方案是,监听adapter中引导层的显示和隐藏,当隐藏时借助EventBus发送一条通知,然后在指定位置接受该通知,继续显示另外的引导层,完美解决多引导切换问题。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

智玲君

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

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

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

打赏作者

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

抵扣说明:

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

余额充值