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

    文章

    2636

    浏览量

    66398
  • HarmonyOS
    +关注

    关注

    79

    文章

    1977

    浏览量

    30262

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

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

收藏 人收藏

    评论

    相关推荐

    DisplayPort显示的配置方法

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

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

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

    ShiMeta鸿蒙同步拼接解决方案

    ►►►方案概述鸿蒙同步解决方案ShiMeta鸿蒙数字标牌系统的基础上,通过信号处理器,实现
    的头像 发表于 12-13 16:45 142次阅读
    ShiMeta<b class='flag-5'>鸿蒙</b><b class='flag-5'>多</b><b class='flag-5'>屏</b>同步拼接解决方案

    玩转RK3588开发板基于connector-split 功能实现联动

    玩转RK3588开发板基于connector-split 功能实现联动
    的头像 发表于 12-02 16:05 321次阅读
    玩转RK3588开发板基于connector-split 功能<b class='flag-5'>实现</b><b class='flag-5'>多</b><b class='flag-5'>屏</b>联动

    鸿蒙原生开发手记:01-元服务开发

    同样的使用方法。 服务卡片 元服务可以添加服务卡片,详细介绍见《鸿蒙原生开发手记:02-服务卡片开发》 开发测试 DevEco 点击运行,设备上可以从负一屏上方的“搜索”按钮,点击进入我的元服务
    发表于 11-14 17:28

    鸿蒙北斗防爆手机巡检作业的表现

    鸿蒙北斗防爆手机以其卓越的高精度定位、智能互联及强大的防爆性能,巡检作业显著提升了工作效率与安全性,成为现代工业巡检不可或缺的智能设备。顶坚北斗防爆巡检终端顶坚鸿蒙北斗防爆手机
    的头像 发表于 11-11 11:32 210次阅读
    <b class='flag-5'>鸿蒙</b>北斗防爆手机<b class='flag-5'>在</b>巡检作业<b class='flag-5'>中</b>的表现

    设计院eplan 500项目图纸

    设计院eplan 500项目图纸
    发表于 10-28 10:49 76次下载

    鸿蒙生态设备超10亿!原生鸿蒙发布,国产操作系统实现自主可控

    10月22日晚间,原生鸿蒙之夜暨华为全场景新品发布会正式召开,华为常务董事、终端BG董事长、智能汽车解决方案BU董事长余承东宣布,搭载鸿蒙操作系统,包括Open Harmony的生态设备超过10亿。我们实现了同
    的头像 发表于 10-23 12:04 1735次阅读
    <b class='flag-5'>鸿蒙</b>生态设备超10亿!原生<b class='flag-5'>鸿蒙</b>发布,国产操作系统<b class='flag-5'>实现</b>自主可控

    鸿蒙跨端实践-JS虚拟机架构实现

    类似的框架,我们需要自行实现以确保核心基础能力的完整。 鸿蒙虚拟机的开发经历了从最初 ArkTs2V8 到 JSVM + Roma新架构方案 。在此过程,我们实现了完整的
    的头像 发表于 09-30 14:42 2436次阅读
    <b class='flag-5'>鸿蒙</b>跨端实践-JS虚拟机架构<b class='flag-5'>实现</b>

    元服务体验-服务使用

    服务使用 使用流程:通过元服务入口打开元服务→启动加载→元服务落地使用→退出元服务。 服务状态:服务状态可以系统多个地方实时显示和更新,包括锁、实况窗、负
    发表于 07-12 15:57

    一屏万象,场景无限: 蓝牙墨水标签多功能场景应用带您领略未来

    蓝牙墨水标签作为种创新的显示设备,通过提供API接口,助力各行各业共创智慧新生态。开放API是为了促进生态系统的共创和共赢,让更多的开发者和合作伙伴能够参与到蓝牙墨水标签的应用和创新
    的头像 发表于 05-27 11:11 463次阅读
    <b class='flag-5'>一屏</b>万象,场景无限: 蓝牙墨水<b class='flag-5'>屏</b>标签多功能<b class='flag-5'>多</b>场景应用带您领略未来

    鸿蒙OS开发学习:【尺寸适配实现

    鸿蒙开发,尺寸适配是个重要的概念,它可以帮助我们不同屏幕尺寸的设备上正确显示和布局我们的应用程序。本文将介绍如何在
    的头像 发表于 04-10 16:05 1773次阅读
    <b class='flag-5'>鸿蒙</b>OS开发学习:【尺寸适配<b class='flag-5'>实现</b>】

    深圳市24年,实现鸿蒙原生应用数占全国总量10%以上

    )学习手册(共计1236)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家技术的道路上更进步。 如需要,可在上方指定前往。也可在主页找我保存。 总结
    发表于 03-04 21:42

    鸿蒙实战项目开发:【短信服务】

    文档》 针对鸿蒙成长路线打造的鸿蒙学习文档 。话不多说,我们直接看详细资料 鸿蒙(OpenHarmony )学习手册(共计1236)与鸿蒙
    发表于 03-03 21:29

    鸿蒙ArkUI开发-实现增删Tab

    本文以浏览器增加或删除签为例,实现Tabs签的增删功能。
    的头像 发表于 01-29 18:43 1596次阅读
    <b class='flag-5'>鸿蒙</b>ArkUI开发-<b class='flag-5'>实现</b>增删Tab<b class='flag-5'>页</b>签