【中软国际】HarmonyOS 通用的应用引导功能 原创 精华

发布于 2021-8-19 13:29
浏览
4收藏

手机APP的引导页是一个常见的功能,今天和大家一起分享在鸿蒙系统的撸引导页代码的经验。

一.应用引导页的功能

1.1为什么要做应用的引导功能?

      几乎所有的App都会有做一些界面引导,有的是页面交互的引导,有的是为了介绍新功能。

1.2通用的功能性引导大概分哪些呢?

      主功能引导、新功能引导和功能转移或改名引导。

1.3.通用的应用引导,需要注意哪些?

      引导的内容文字不宜太长,适当加入一些图案可以方便用户理解。言归正传吧,开始咱们今天的主题,如何实现应用的引导功能吧!

二.实现应用的引导功能具体步骤:

      首先来看看讨论的引导功能的效果吧!点击引导页,向上滑动过程,第一个界面图案和文字渐变消失的过程。而第二页界面的图片和文字渐渐清晰可见。底部Next 图标会下滑隐藏再弹出的动画效果。

【中软国际】HarmonyOS 通用的应用引导功能-开源基础软件社区

开发准备

      搭建鸿蒙开发环境,这里就不做介绍了,如果没有环境没有搭建好的同学可以进入学习安装环境, 安装好环境以后接下来我们就可以进行开发工作了。

2.1 设计思路

      首先我们做的是公用的组件,我们需要使用组件化思想去搭建我们的项目框架,接下来根据组件的需求我们先去设计一下界面,设计好之后我们需要对页面添加数据,添加完数据之后组件的大体界面已经展示给我们,下来就是在滑动page的时候添加底部button的回弹动画,并且在此时我们需要操作page的子view。最后我们要去使用我们的组件。

2.2 设计步骤

2.2.1 设计界面

      根据我们要实现的功能,我们可以使用PageSlider控件去实现界面布局文件,实现代码为:

<PageSlider
     ohos:id="$+id:vertical_view_pager"
     ohos:width="match_parent"
     ohos:height="match_parent" >
</PageSlider>

(1)添加数据、初始化数据

public void setData() {
	super.setData();
	pageColors = new ArrayList<>();
	pageColors.add(getString(ResourceTable.Color_colorAccent));
	pageColors.add(getString(ResourceTable.Color_color2));
	pageColors.add(getString(ResourceTable.Color_colorPrimary));
	pageColors.add(getString(ResourceTable.Color_color3));
	pageMoudles = getData();
}

private List<PageMoudle> getData() {
	String textValue = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
	PageMoudle pageMoudleOne = new PageMoudle();
	pageMoudleOne.setRecoureId(ResourceTable.Graphic_intro_second_vector);
    pageMoudleOne.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(0))));
	pageMoudleOne.setTitle("Lorem Ipsum Lorem Ipsum");

	pageMoudleOne.setText(textValue + textValue + textValue);
	pageMoudleOne.setTitleSize(17);
	pageMoudleOne.setTextSize(14);
	List<PageMoudle> datas = new ArrayList<>();
	datas.add(pageMoudleOne);

	PageMoudle pageMoudleTwo = new PageMoudle();
	pageMoudleTwo.setRecoureId(ResourceTable.Graphic_four);
		pageMoudleTwo.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(1))));
	pageMoudleTwo.setTitle("Lorem Ipsum Lorem Ipsum ");
	pageMoudleTwo.setText(textValue + textValue);
	datas.add(pageMoudleTwo);

	PageMoudle pageMoudleThree = new PageMoudle();
	pageMoudleThree.setRecoureId(ResourceTable.Graphic_ohos);
		pageMoudleThree.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(2))));
	pageMoudleThree.setTitle("Lorem Ipsum");
	pageMoudleThree.setText(textValue);
	datas.add(pageMoudleThree);

	PageMoudle pageMoudleFour = new PageMoudle();
	pageMoudleFour.setRecoureId(ResourceTable.Media_new_intro);
		pageMoudleFour.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(3))));
	pageMoudleFour.setTitle("Lorem Ipsum");
	pageMoudleFour.setText(textValue + textValue + textValue);
	datas.add(pageMoudleFour);
	return datas;
}

(2)设置provider

	pageSlider = (PageSlider) findComponentById(ResourceTable.Id_vertical_view_pager);
	pageSlider.setOrientation(Component.VERTICAL);
	pageSlider.addPageChangedListener(this);
	pageSlider.setTouchEventListener(this::onTouchEvent);
	adapter = new VerticalIntroPagerAdapter(this, pageMoudles);
	pageSlider.setProvider(adapter);

2.2.2 添加动画

      这里我们使用属性动画去完成底部button的上弹和下弹操作,上弹和下弹是和我们手指滑动的方向是有关系的,所以这里我们必须实现手指的触摸事件,在触摸事件中获取我们手机滑动的距离,如果距离大于0则是下滑,如果小于0则是下滑.

(1) 获取是上滑还是下滑代码如下:

@Override
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
		int action = touchEvent.getAction();
		switch (action) {
			case TouchEvent.PRIMARY_POINT_DOWN:
				pageSlider.setSlidingPossible(true);
				startPointY = getTouchY(touchEvent, 0, component);
				return true;
			case TouchEvent.POINT_MOVE:
				movePointY = getTouchY(touchEvent, touchEvent.getIndex(), component) - startPointY;
				if (page != 0 && movePointY > 0) {
					WindowManager.getInstance().getTopWindow().get().setStatusBarColor(getColorByString(pageColors.get(page - 1)));
				}
				return true;
			case TouchEvent.PRIMARY_POINT_UP:
				return true;
			default:
		}
		return false;
}

(2) 获取到上滑还是下滑后,接下来就去给底部button设置动画.动画用的是属性动画,属性动画大体实现是初始化动画,设置动画持续时间,实现动画属性值变化监听事件,最后启动动画。大体代码如下:

private void startChangeButtonBg(int direction, int duration) {
        if (animatorValue == null) {
            animatorValue = new AnimatorValue();
        }
        animatorValue.setCurveType(Animator.CurveType.LINEAR);
        animatorValue.setDuration(duration);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                if (direction <= 0) {
                    double value = ((1 - (double)v) * nextHeight) * direction;
                    next.setMarginBottom((int) value);
                } else {
                    float value = -(v * nextHeight);
                    next.setMarginBottom((int) value);
                    if (v > 0.9) {
                        if (page == 3) {
                            skip.setVisibility(Component.INVISIBLE);
                            next.setText("DONE");
                            next.setNormalColor(pageColors.get(1));
                        } else {
                            skip.setVisibility(Component.VISIBLE);
                            next.setText("NEXT");
                            next.setNormalColor(pageColors.get(page + 1));
                        }
                        next.setMarginBottom(0);
                    }
                }
            }
        });
        setAnimStateChangeList(direction);
        animatorValue.start();
}

private void setAnimStateChangeList(int direction) {
        animatorValue.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                if (direction <= 0) {
                    if (page == 3) {
                        skip.setVisibility(Component.INVISIBLE);
                        next.setText("DONE");
                        next.setNormalColor(pageColors.get(1));
                    } else {
                        skip.setVisibility(Component.VISIBLE);
                        next.setText("NEXT");
                        next.setNormalColor(pageColors.get(page + 1));
                    }
                }
            }
            @Override
            public void onStop(Animator animator) {
            }
            @Override
            public void onCancel(Animator animator) {
            }
            @Override
            public void onEnd(Animator animator) {
                movePointY = 0;
            }
            @Override
            public void onPause(Animator animator) {
            }
            @Override
            public void onResume(Animator animator) {
            }
        });
    }

2.2.3 操作子view

      如何去操作子view呢?首先我们先去看看PageSlider是否有子view的操作监听接口,查看api后没有这样的接口获取方法,那就得我们自己去考虑怎么实现呢,我这里的实现思路是在PageSlider设置provider的时候保存所有的子view对象,然后再使用的时候拿出子view再进行操作。我们这里例子是改变子view的透明度.代码实现如下:

(1) 保存子view

public class VerticalIntroPagerAdapter extends PageSliderProvider {
	LinkedHashMap<Integer, Component> pageComonents;
		public VerticalIntroPagerAdapter(Context context, List<PageMoudle> datas) {
			this.context = context;
			this.datas = datas;
			pageComonent = new ArrayList<>();
	// 初始化用来添加子view的集合,注意这里是一个有序集合
			pageComonents = new LinkedHashMap<Integer, Component>();
	}
	//添加子view
	@Override
	public Object createPageInContainer(ComponentContainer componentContainer, int i) {
		if (!pageComonents.containsValue(component)) {
				pageComonents.put(i, component);
			}
	}
}

(2) 操作子view

private void setPageApale(int currentPage, int targetPage, float offset) {
        if (adapter.pageComonents != null && adapter.pageComonents.get(currentPage) != null
            && adapter.pageComonents.get(targetPage) != null) {
            float alpha = new BigDecimal(1.0f).subtract(new BigDecimal(offset).multiply(new BigDecimal(2))).floatValue();
            if (offset >= 0.4 && offset <= 0.9) {
                offset = new BigDecimal(offset).subtract(new BigDecimal( 0.4f)).floatValue();
            } else if (offset < 0.4) {
                offset = 0.0f;
            } else {
                offset = 1.0f;
            }
            setApale(currentPage, targetPage, alpha, offset);
        }
}

      到这里我们的竖直引导工具组件就已经封装好了。
2.2.4 使用组件

      如何去使用我们的组件呢?这里我们用的是组件化思想.所以我们呢只需要在我们的项目中引入我们的组件,然后再我们的ablity中集成我们封装好的VerticalIntroSlice对象就行,最后我们再把封装一个添加数据的接口,把我们的数据变成动态添加的就行。

三. 结语

      到此我们的整个设计流程就完了,通过上面的操作,相信小伙伴们就可以实现应用引导功能了。

作者:焦俊盈

更多原创内容请关注:中软国际 HarmonyOS 技术学院

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-8-19 15:17:25修改
5
收藏 4
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐