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

    文章

    2604

    浏览量

    65249
  • HarmonyOS
    +关注

    关注

    79

    文章

    1779

    浏览量

    29233

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

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

收藏 人收藏

    评论

    相关推荐

    loongarch是如何区分大和基本页的?

    开发loongarch架构的操作系统的时候,我遇到了这样的问题:我不知道硬件是如何区分大和基本页的。 如图,关于基本页和大的格式在手册是这样的叙述的: 即便手册
    发表于 03-30 12:05

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

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

    TLE9867QXA20如何实现从?

    您好,团队,我我的应用程序中使用 TLE9867QXA20,从,现在我想为我的应用实现
    发表于 03-04 07:26

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

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

    鸿蒙这么大声势,为何迟迟看不见岗位?最新数据来了

    。 话不多说,我们直接看详细资料鸿蒙(OpenHarmony )学习手册(共计1236)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家技术的道路上更进
    发表于 02-29 20:53

    学习鸿蒙背后的价值?星河版开放如何学习?

    ,很难找到入口。从而导致学起来比较混乱。下面我分享张梳理完成的鸿蒙开发学习曲线图: 由于内容较多看不清,可以qr23.cn/AKFP8k或喔主页保存高清完整版。并且可获(鸿蒙星河
    发表于 02-22 20:55

    很多人质疑鸿蒙,那它算不算国产操作系统?

    、汽车等。这意味着鸿蒙可以多个设备之间实现无缝切换和共享数据。 安卓系统则主要用于移动设备,如手机和平板电脑。 2、系统架构 鸿蒙的核心是分布式技术架构,通过分布式技术
    发表于 01-17 22:04

    鸿蒙千帆起】《开心消消乐》完成鸿蒙原生应用开发,创新多端联动用户体验

    技术还为用户打造出创新的分布式游戏玩法。通过与 HarmonyOS 分布式有机结合,可实现设备协同的分布式 PK 场景。在此场景下,用户操作各自的 HarmonyOS 设备,使用智慧实时显示对战
    发表于 01-03 10:22

    鸿蒙千帆起】《钢岚》成为首款基于HarmonyOS NEXT开发的战棋新游

    通过元服务一屏或桌面呈现,为玩家带来更便捷的游戏体验;另方面保证用户安全与隐私的前提下,AI 大模型可以识别用户意图,实现服务精准投
    发表于 12-28 10:24

    鸿蒙原生应用开发-元服务分发方式的调整及趋势

    些精选的元服务将在专栏推荐露出,后续是元服务主要分发渠道。 2.负一屏:具备搜索能力,但后续仅展示精品元服务。 3.服务中心:具备搜索能力,但会逐步日落,融合至负一屏。 因为服务
    发表于 11-14 16:02

    华为鸿蒙系统

    操作系统,创造个超级虚拟终端互联的世界,将人、设备、场景有机地联系在起,将消费者全场景生活接触的多种智能终端,实现极速发现、极速连接
    发表于 11-02 19:39

    鸿蒙操作系统的前世今生

    数据无缝衔接,让跨设备数据处理如同本地样便捷。 分布式任务调度:能够选择最合适的设备运行分布式任务,并实现设备间的能力互助。 分布式设备虚拟化:匹配并选择能力最佳的执行硬件,让业务连续地
    发表于 10-08 19:55

    专访深开鸿CEO王成录:做成鸿蒙生态 需要家万亿市值的公司

    让所有设备都用同个系统,讲同种语言,这样的想法在华为内部曾经讨论了两年,最终鸿蒙方案激辩诞生。随着搭载
    发表于 06-15 14:46

    HarmonyOS元服务分发新体验负一屏搜索、应用市场元服务专区

    我们看到,相比以前的原子化服务的分发途径,没有了服务中心;增加了负一屏的搜索和华为应用市场元服务的分类,我们认为是元服务进入流量分发主战场的个标志。 负一屏 打开负一屏搜索
    发表于 06-06 16:14

    昆仑通态视频教程-13-一屏机 #昆仑通态视频教程 #昆仑通态与欧姆龙

    plc触摸
    学习电子知识
    发布于 :2023年05月21日 20:49:04