0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在鸿蒙中如何实现一屏多页

OpenHarmony技术社区 来源:鸿蒙技术社区 作者:开鸿HOS小鸿 2021-09-28 09:46 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

众所周知,PageSlider 是用于页面之间切换的组件,它通过响应滑动事件完成页面间的切换,而 PageFlipper 可能知道的人就比较少了。

其实 PageFlipper 和 PageSlider 类似,都是视图切换组件,它们都继承自 StackLayout,因此可以将多个 component 层叠在一起,每次只显示一个组件。

当视图从一个 component 切换到另一个 component 时,PageFlipper 支持指定动画效果。

区别:

PageFlipper 通过 addComponent() 添加 component,可使用动画控制多个 component 之间的切换效果,是个轻量级的组件,适合展示少量静态数据。

而 PageSlide 是由 provider 来提供 component 的,更适用复杂的视图切换,实现数据的动态加载。

下面是一个 PageSlider 和 PageFlipper 结合起来的使用效果,页面中间的卡片使用的是 PageSlider,背景图片和底部的数字指示器用的是 PageFlipper。

PageSlider

PageSlider 可以说是鸿蒙中最常用的视图切换组件了,使用方法不用多做介绍,官方文档有详细的说明,这里主要说一下一个特殊的效果。

①一屏多页效果

其实鸿蒙本身有提供一个 setClipEnabled() 的方法,作用是设置是否允许在组件超出其父布局时自动裁剪组件。

理论上通过给 pageSlider 父布局设置 setClipEnabled(false),加上给子组件设置合适的宽度可以实现一屏多页效果,但是经过测试并没达到效果。

这个方法我也单独拿出来在其他场景验证过确实无效,下面是验证的效果。

但是鸿蒙却提供了另外一个方法 setPageMargin(),它的作用是设置 PageSlider 中子组件边距的,当传入一个合适的负数时(必须是负数),就能实现一屏同时显示多个子组件的效果:

②动态设置缩放透明度变化

设置透明度和缩放比例就不细说了,主要就是在 PageSlider 子组件加载完成后和页面切换中的回调方法中改变 alpha 值和 scale 值。

直接上代码:

public final class AlphaScalePageTransformer {

/**

* 缩放

*/

public static final float INACTIVE_SCALE = 0.8f;

/**

* 透明度

*/

public static final float INACTIVE_ALPHA = 0.5f;

/**

* 设置初始状态的缩放和透明度

*

* @param child

* @param position

* @param current

*/

public static void defaultPage(ListContainer child, int position, float current) {

if (position != current) {

child.setAlpha(INACTIVE_ALPHA);

child.setScaleX(INACTIVE_SCALE);

child.setScaleY(INACTIVE_SCALE);

}

}

/**

* 设置滑动中的缩放和透明度

*

* @param childList

* @param position

* @param offset

* @param direction

*/

public static void transformPage(List《ListContainer》 childList, int position, float offset, float direction) {

Component child = childList.get(position);

float scale = INACTIVE_SCALE + (1 - INACTIVE_SCALE) * (1 - Math.abs(offset));

float alpha = INACTIVE_ALPHA + (1 - INACTIVE_ALPHA) * (1 - Math.abs(offset));

child.setScaleX(scale);

child.setScaleY(scale);

child.setAlpha(alpha);

if (direction 》 0) {

if (position 《 childList.size() - 1) {

child = childList.get(position + 1);

}

} else {

if (position 》= 1) {

child = childList.get(position - 1);

}

}

scale = INACTIVE_SCALE + (1 - INACTIVE_SCALE) * Math.abs(offset);

alpha = INACTIVE_ALPHA + (1 - INACTIVE_ALPHA) * Math.abs(offset);

child.setScaleX(scale);

child.setScaleY(scale);

child.setAlpha(alpha);

}

}

设置两边的 component 透明度和缩放效果:

//设置初始状态缩放和透明度

AlphaScalePageTransformer.defaultPage(image, i, pageSlider.getCurrentPage());

//设置页面切换中缩放和透明度

pageSlider.addPageChangedListener(new PageChangedListener() {

@Override

public void onPageSliding(int position, float positionOffset, int positionOffsetPixels) {

AlphaScalePageTransformer.transformPage(listContainers, position,

positionOffset, positionOffsetPixels);

}

});

PageFlipper(翻页器)

PageFlipper 是一个翻页器,当它有两个或多个子组件时,切换过程中可以轻松设置入场动画和出场动画,以达到意想不到的效果。

虽然 PageFlipper 的使用率远不及 PageSlider,但这并不意味着 PageFlipper 就不强大。

他能通过简单的代码实现许多动画效果,比如淘宝头条的效果,日历翻页效果,背景图淡入淡出效果等等。

常用方法:

getCurrentComponent()//获取当前组件

showNext():显示下一个组件(如果当前子组件是最后一个,则显示第一个子组件)

showPrevious():显示上一个组件(如果当前子组件是第一个,则显示最后一个子组件)

getFlipInterval() :获取自动翻转时间

setFlipPeriod(int period) :设置翻转周期

startFlipping() :开启自动翻转

stopFlipping() :停止自动翻转

addComponent() :添加组件

setIncomingAnimationA() :设置转入动画

setOutgoingAnimation() :设置转出动画

下面通过设置文字翻页效果来了解下它的使用方法:

代码如下:

public class IndicatorComponent extends DirectionalLayout {

/**

* 文字大小

*/

private static final int TEXT_SIZE = 130;

/**

* 动画时长

*/

private static final int DURATION = 600;

private PageFlipper textSwitcher;

private Text textcomponent;

/**

* ItemsCountcomponent

*

* @param context

* @param attrSet

*/

public IndicatorComponent(Context context, AttrSet attrSet) {

super(context, attrSet);

init(context);

}

private void init(Context context) {

setOrientation(ComponentContainer.HORIZONTAL);

textSwitcher = new PageFlipper(context);

//理论上PageFlipper只需要添加两个子component就能实现动画效果,但是实际测试发现如果切换速度太快就导致子组件衔接不上出现组件消失的额情况,

//因此这里通过实践多添加了几个子component,防止滑动过快出现bug

textSwitcher.addComponent(createcomponentForTextSwitcher(context));

textSwitcher.addComponent(createcomponentForTextSwitcher(context));

textSwitcher.addComponent(createcomponentForTextSwitcher(context));

textSwitcher.addComponent(createcomponentForTextSwitcher(context));

addComponent(textSwitcher, new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT,

ComponentContainer.LayoutConfig.MATCH_CONTENT));

textcomponent = new Text(context);

textcomponent.setTextSize(TEXT_SIZE);

textcomponent.setFont(Font.DEFAULT_BOLD);

textcomponent.setTextColor(new Color(Color.getIntColor(“#8cffffff”)));

addComponent(textcomponent, new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT,

ComponentContainer.LayoutConfig.MATCH_CONTENT));

}

/**

* 创建组件

*

* @param context 上下文

* @return text

*/

private Text createcomponentForTextSwitcher(Context context) {

Text text = new Text(context);

text.setTextSize(TEXT_SIZE);

text.setFont(Font.DEFAULT_BOLD);

text.setTextColor(Color.WHITE);

text.setLayoutConfig(new PageFlipper.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT,

PageFlipper.LayoutConfig.MATCH_CONTENT));

return text;

}

/**

* update

*

* @param newPosition 新位置

* @param oldPosition 旧位置

* @param totalElements 总数

*/

public void update(int newPosition, int oldPosition, int totalElements) {

textcomponent.setText(“ / ” + totalElements);

int offset = textSwitcher.getHeight();

if (newPosition 》 oldPosition) {

//设置组件进入和退出的动画

textSwitcher.setIncomingAnimation(createPositionAnimation(-offset, 0, 0f, 1f, DURATION));

textSwitcher.setOutgoingAnimation(createPositionAnimation(0, offset, 1f, 0f, DURATION));

} else if (oldPosition 》 newPosition) {

textSwitcher.setIncomingAnimation(createPositionAnimation(offset, 0, 0f, 1f, DURATION));

textSwitcher.setOutgoingAnimation(createPositionAnimation(0, -offset, 1f, 0f, DURATION));

}

//显示下一个组件并执行动画

textSwitcher.showNext();

Text text = (Text) textSwitcher.getCurrentComponent();

text.setText(String.valueOf(newPosition + 1));

}

/**

* 创建属性动画

*

* @param fromY

* @param toY

* @param fromAlpha

* @param toAlpha

* @param duration

* @return

*/

private AnimatorProperty createPositionAnimation(int fromY, int toY, float fromAlpha, float toAlpha, int duration) {

AnimatorProperty animatorProperty = new AnimatorProperty();

animatorProperty.setCurveType(Animator.CurveType.DECELERATE);

animatorProperty.alphaFrom(fromAlpha);

animatorProperty.alpha(toAlpha);

animatorProperty.moveFromY(fromY);

animatorProperty.moveToY(toY);

animatorProperty.setDuration(duration);

return animatorProperty;

}

}

结束

以上主要介绍了 PageSlider 和 PageFlipper 的一些简单使用,最后补充一个小功能,设置渐变效果,这个简单的效果可能很多人还不知道如何设置。

首先生成一个 foreground_gradient.xml:

《shape

xmlns:ohos=“http://schemas.huawei.com/res/ohos”

ohos:shape=“rectangle”》

//设置填充的颜色,可以根据实际需要设置多个

《solid

ohos:colors=“#000000,#00ffffff,#d8000000”/》

//设置渐变方向,有三个值可供选择:linear_gradient,radial_gradient,sweep_gradient

《gradient

ohos:shader_type=“linear_gradient”

/》《/shape》

然后给目标组件设置前景色即可:

ohos:foreground_element=“$graphic:foreground_gradient”

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2642

    浏览量

    69402
  • HarmonyOS
    +关注

    关注

    80

    文章

    2147

    浏览量

    35668

原文标题:在鸿蒙上实现一屏多页效果!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    AcrelEMS-EDU:一屏掌控高校能源,驱动绿色校园智慧转型

    优化资源配置,推动节能降耗与绿色校园建设。 、全局掌控:一屏纵览能源脉动 一屏纵览全校能源脉搏。通过动态图表实时展示各校区教学楼、实验室、宿舍等区域的用电、用水总量,支持能耗折算与趋势分析,清晰呈现日、周用能变化,让管理者快速
    的头像 发表于 09-17 23:16 697次阅读
    AcrelEMS-EDU:<b class='flag-5'>一屏</b>掌控高校能源,驱动绿色校园智慧转型

    【节能学院】搞定校区、满足需求!AcrelEMS-EDU成高校综合能源管理 “硬核帮手”

    建设。、全局掌控:一屏纵览能源脉动一屏纵览全校能源脉搏。通过动态图表实时展示各校区教学楼、实验室、宿舍等区域的用电、用水总量,支持能耗折算与趋势分析,清晰呈现日、
    的头像 发表于 08-28 08:05 423次阅读
    【节能学院】搞定<b class='flag-5'>多</b>校区、满足<b class='flag-5'>多</b>需求!AcrelEMS-EDU成高校综合能源管理 “硬核帮手”

    淘宝API跨平台数据同步,店管理一屏搞定!

    ​ 痛点:平台数据孤岛 当商家同时淘宝、天猫、抖音等平台运营店铺时,常面临: 库存数据不同步导致超卖 订单分散多个后台,处理效率低 商品信息需重复编辑 销售报表需人工汇总 解决方案:API数据
    的头像 发表于 07-30 14:41 459次阅读
    淘宝API跨平台数据同步,<b class='flag-5'>多</b>店管理<b class='flag-5'>一屏</b>搞定!

    鸿蒙Next实现瀑布流布局

    高度或宽高比,减少动态测量开销 合理实现懒加载:对于非首内容或图片资源,定要实现懒加载 渐进式增强体验:先确保基础功能可用,再添加动画和交互效果 测试与优化:
    发表于 06-10 14:17

    开源鸿蒙生态分论坛圆满举办

    近日,开源鸿蒙开发者大会2025(OHDC.2025)深圳成功举办。主论坛上隆重举行了“开源鸿蒙TV SIG”成立仪式,开源鸿蒙TV S
    的头像 发表于 06-05 15:27 1072次阅读

    鸿蒙5开发宝藏案例分享---自由流转的拖拽联动

    ? 【干货预警】鸿蒙开发宝藏案例大揭秘!手把手教你玩转常用功能**?** 大家好呀~,今天扒拉鸿蒙文档的时候,突然发现官方竟然藏了堆超实用的开发案例! ?** 之前总觉得
    发表于 06-03 18:50

    鸿蒙5开发宝藏案例分享---多开发实例(地图导航)

    ,欢迎评论区扔需求~ 下期准备扒拉「智能家居跨设备联动」的实战案例,想看的同学记得三连催更! #HarmonyOS #鸿蒙开发 #一多适配 #实战教程
    发表于 06-03 16:17

    鸿蒙5开发宝藏案例分享---多开发实例(图片美化)

    ?【鸿蒙开发宝藏案例分享】次搞定多端适配的图片美化应用开发思路!? Hey小伙伴们~ 今天鸿蒙文档时挖到个超实用的大宝藏!原来官方早
    发表于 06-03 16:09

    鸿蒙5开发宝藏案例分享---折叠悬停态开发实践

    HarmonyOS早就准备好了超实用案例,今天必须带大家解锁\"悬停态\"开发的正确姿势,手慢无哦~ ?** 先来点干货:什么是悬停态?** 就是把折叠像笔记本电脑那样半折立桌上
    发表于 06-03 12:04

    鸿蒙5开发宝藏案例分享---多分栏开发实践

    ?【HarmonyOS开发者的宝藏指南】次搞定设备分栏布局,原来还能这么玩! 大家好呀!今天鸿蒙社区挖到个超实用的大宝藏——原来官方
    发表于 06-03 12:03

    Aqara 智能温控器 W400 震撼上市:一屏开启全屋智慧温控新时代

    设备,为用户带来高效、便捷、智能的全方位解决方案,全面开启智慧家居温控新时代。 三合设备接入,一屏轻松驾驭传统暖通 Aqara 智能温控器 W400 打破传统限制,支持同时接入中央空调(氟机 / 水机)、新风、地暖设备,无需复杂改造即可
    的头像 发表于 04-16 17:26 812次阅读

    DevEco Studio构建分析工具Build Analyzer 为原生鸿蒙应用开发提速

    原生鸿蒙应用开发过程,随着项目复杂度的增加,开发者花费构建上的时间越来越长,导致开发效率降低。为了帮助开发者解决构建效率的问题,华为
    发表于 02-17 18:06

    Altium Designer原理图绘制基础

    电子发烧友网站提供《Altium Designer原理图绘制基础.pdf》资料免费下载
    发表于 01-22 17:11 9次下载
    Altium Designer<b class='flag-5'>多</b><b class='flag-5'>页</b>原理图绘制基础

    DisplayPort显示的配置方法

    现代办公和娱乐环境显示已经成为提升效率和体验的重要工具。DisplayPort作为种先进的显示接口技术,不仅支持高分辨率和高刷新
    的头像 发表于 12-27 18:08 3360次阅读

    鸿蒙Flutter实战:14-现有Flutter 项目支持鸿蒙 II

    引言 之前的文章鸿蒙Flutter实战:09-现有Flutter项目支持鸿蒙,介绍了如何改造项目,适配鸿蒙平台。 文中讲述了整体的理念和
    发表于 12-26 14:59