zl程序教程

您现在的位置是:首页 >  APP

当前栏目

HarmonyOS 通用的应用引导功能

2023-03-15 22:45:06 时间

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

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

一.应用引导页的功能

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

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

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

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

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

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

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

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

开发准备

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

2.1 设计思路

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

2.2 设计步骤

2.2.1 设计界面

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

  1. <PageSlider 
  2.      ohos:id="$+id:vertical_view_pager" 
  3.      ohos:width="match_parent" 
  4.      ohos:height="match_parent" > 
  5. </PageSlider> 

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

  1. public void setData() { 
  2.     super.setData(); 
  3.     pageColors = new ArrayList<>(); 
  4.     pageColors.add(getString(ResourceTable.Color_colorAccent)); 
  5.     pageColors.add(getString(ResourceTable.Color_color2)); 
  6.     pageColors.add(getString(ResourceTable.Color_colorPrimary)); 
  7.     pageColors.add(getString(ResourceTable.Color_color3)); 
  8.     pageMoudles = getData(); 
  9.  
  10. private List<PageMoudle> getData() { 
  11.     String textValue = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
  12.     PageMoudle pageMoudleOne = new PageMoudle(); 
  13.     pageMoudleOne.setRecoureId(ResourceTable.Graphic_intro_second_vector); 
  14.     pageMoudleOne.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(0)))); 
  15.     pageMoudleOne.setTitle("Lorem Ipsum Lorem Ipsum"); 
  16.  
  17.     pageMoudleOne.setText(textValue + textValue + textValue); 
  18.     pageMoudleOne.setTitleSize(17); 
  19.     pageMoudleOne.setTextSize(14); 
  20.     List<PageMoudle> datas = new ArrayList<>(); 
  21.     datas.add(pageMoudleOne); 
  22.  
  23.     PageMoudle pageMoudleTwo = new PageMoudle(); 
  24.     pageMoudleTwo.setRecoureId(ResourceTable.Graphic_four); 
  25.         pageMoudleTwo.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(1)))); 
  26.     pageMoudleTwo.setTitle("Lorem Ipsum Lorem Ipsum "); 
  27.     pageMoudleTwo.setText(textValue + textValue); 
  28.     datas.add(pageMoudleTwo); 
  29.  
  30.     PageMoudle pageMoudleThree = new PageMoudle(); 
  31.     pageMoudleThree.setRecoureId(ResourceTable.Graphic_ohos); 
  32.         pageMoudleThree.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(2)))); 
  33.     pageMoudleThree.setTitle("Lorem Ipsum"); 
  34.     pageMoudleThree.setText(textValue); 
  35.     datas.add(pageMoudleThree); 
  36.  
  37.     PageMoudle pageMoudleFour = new PageMoudle(); 
  38.     pageMoudleFour.setRecoureId(ResourceTable.Media_new_intro); 
  39.         pageMoudleFour.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(3)))); 
  40.     pageMoudleFour.setTitle("Lorem Ipsum"); 
  41.     pageMoudleFour.setText(textValue + textValue + textValue); 
  42.     datas.add(pageMoudleFour); 
  43.     return datas; 

 (2)设置provider

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

2.2.2 添加动画

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

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

  1. @Override 
  2. public boolean onTouchEvent(Component component, TouchEvent touchEvent) { 
  3.         int action = touchEvent.getAction(); 
  4.         switch (action) { 
  5.             case TouchEvent.PRIMARY_POINT_DOWN: 
  6.                 pageSlider.setSlidingPossible(true); 
  7.                 startPointY = getTouchY(touchEvent, 0, component); 
  8.                 return true
  9.             case TouchEvent.POINT_MOVE: 
  10.                 movePointY = getTouchY(touchEvent, touchEvent.getIndex(), component) - startPointY; 
  11.                 if (page != 0 && movePointY > 0) { 
  12.                     WindowManager.getInstance().getTopWindow().get().setStatusBarColor(getColorByString(pageColors.get(page - 1))); 
  13.                 } 
  14.                 return true
  15.             case TouchEvent.PRIMARY_POINT_UP: 
  16.                 return true
  17.             default
  18.         } 
  19.         return false

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

  1. private void startChangeButtonBg(int direction, int duration) { 
  2.         if (animatorValue == null) { 
  3.             animatorValue = new AnimatorValue(); 
  4.         } 
  5.         animatorValue.setCurveType(Animator.CurveType.LINEAR); 
  6.         animatorValue.setDuration(duration); 
  7.         animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() { 
  8.             @Override 
  9.             public void onUpdate(AnimatorValue animatorValue, float v) { 
  10.                 if (direction <= 0) { 
  11.                     double value = ((1 - (double)v) * nextHeight) * direction; 
  12.                     next.setMarginBottom((int) value); 
  13.                 } else { 
  14.                     float value = -(v * nextHeight); 
  15.                     next.setMarginBottom((int) value); 
  16.                     if (v > 0.9) { 
  17.                         if (page == 3) { 
  18.                             skip.setVisibility(Component.INVISIBLE); 
  19.                             next.setText("DONE"); 
  20.                             next.setNormalColor(pageColors.get(1)); 
  21.                         } else { 
  22.                             skip.setVisibility(Component.VISIBLE); 
  23.                             next.setText("NEXT"); 
  24.                             next.setNormalColor(pageColors.get(page + 1)); 
  25.                         } 
  26.                         next.setMarginBottom(0); 
  27.                     } 
  28.                 } 
  29.             } 
  30.         }); 
  31.         setAnimStateChangeList(direction); 
  32.         animatorValue.start(); 
  33.  
  34. private void setAnimStateChangeList(int direction) { 
  35.         animatorValue.setStateChangedListener(new Animator.StateChangedListener() { 
  36.             @Override 
  37.             public void onStart(Animator animator) { 
  38.                 if (direction <= 0) { 
  39.                     if (page == 3) { 
  40.                         skip.setVisibility(Component.INVISIBLE); 
  41.                         next.setText("DONE"); 
  42.                         next.setNormalColor(pageColors.get(1)); 
  43.                     } else { 
  44.                         skip.setVisibility(Component.VISIBLE); 
  45.                         next.setText("NEXT"); 
  46.                         next.setNormalColor(pageColors.get(page + 1)); 
  47.                     } 
  48.                 } 
  49.             } 
  50.             @Override 
  51.             public void onStop(Animator animator) { 
  52.             } 
  53.             @Override 
  54.             public void onCancel(Animator animator) { 
  55.             } 
  56.             @Override 
  57.             public void onEnd(Animator animator) { 
  58.                 movePointY = 0; 
  59.             } 
  60.             @Override 
  61.             public void onPause(Animator animator) { 
  62.             } 
  63.             @Override 
  64.             public void onResume(Animator animator) { 
  65.             } 
  66.         }); 
  67.     } 

2.2.3 操作子view

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

(1) 保存子view

  1. public class VerticalIntroPagerAdapter extends PageSliderProvider { 
  2.     LinkedHashMap<Integer, Component> pageComonents; 
  3.         public VerticalIntroPagerAdapter(Context context, List<PageMoudle> datas) { 
  4.             this.context = context; 
  5.             this.datas = datas; 
  6.             pageComonent = new ArrayList<>(); 
  7.     // 初始化用来添加子view的集合,注意这里是一个有序集合 
  8.             pageComonents = new LinkedHashMap<Integer, Component>(); 
  9.     } 
  10.     //添加子view 
  11.     @Override 
  12.     public Object createPageInContainer(ComponentContainer componentContainer, int i) { 
  13.         if (!pageComonents.containsValue(component)) { 
  14.                 pageComonents.put(i, component); 
  15.             } 
  16.     } 

(2) 操作子view

  1. private void setPageApale(int currentPage, int targetPage, float offset) { 
  2.         if (adapter.pageComonents != null && adapter.pageComonents.get(currentPage) != null 
  3.             && adapter.pageComonents.get(targetPage) != null) { 
  4.             float alpha = new BigDecimal(1.0f).subtract(new BigDecimal(offset).multiply(new BigDecimal(2))).floatValue(); 
  5.             if (offset >= 0.4 && offset <= 0.9) { 
  6.                 offset = new BigDecimal(offset).subtract(new BigDecimal( 0.4f)).floatValue(); 
  7.             } else if (offset < 0.4) { 
  8.                 offset = 0.0f; 
  9.             } else { 
  10.                 offset = 1.0f; 
  11.             } 
  12.             setApale(currentPage, targetPage, alpha, offset); 
  13.         } 

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

2.2.4 使用组件

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

三. 结语

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

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com