HarmonyOS 鸿蒙Next Webview组件加载地图并在其上放置其他组件时Webview不响应点击事件

HarmonyOS 鸿蒙Next Webview组件加载地图并在其上放置其他组件时Webview不响应点击事件

因为没有原生的地图加载方式,所以用了H5的方式加载,但现在有个问题,需要在地图上覆盖其他组件,但这些组件会拦截事件透传,即时是一个Row组件,详看代码

import { CommonConstants } from '../../common/CommonConstants'
import webview from '@ohos.web.webview'

@Component
export default struct car {
  webController: webview.WebviewController = new webview.WebviewController();

  build() {
    RelativeContainer() {
      Web({
        src: $rawfile("map.html"),
        controller: this.webController
      })
        .alignRules({
          top:{anchor:'__container',align:VerticalAlign.Top}
        })
        .height(CommonConstants.FULL_PARAM)
        .width(CommonConstants.FULL_PARAM)
        .javaScriptAccess(true)
        .onTouch((event) => {
          console.log('web' + JSON.stringify(event));
        })
        .id('web')
      Row () {
        Text('11')
          .width('20%')
          .textAlign(TextAlign.Center)
          .height('40%')
          .fontColor(Color.White)
          .fontSize(16)
          .backgroundColor('#6d0054ff')
      }
      .alignRules({
        top:{anchor:'__container',align:VerticalAlign.Top}
      })
      .alignItems(VerticalAlign.Center)
      .backgroundColor('#6d62ff00')
      //这里设置为false就好了,但肯定不行,上层组件拥有其他交互
      //.enable(false)
      .height(CommonConstants.FULL_PARAM)
      .width(CommonConstants.FULL_PARAM)
      .id('Row')
    }
    .height(CommonConstants.FULL_PARAM)
    .width(CommonConstants.FULL_PARAM)
  }


  aboutToAppear() {
    webview.WebviewController.setWebDebuggingAccess(true)
    console.log('appear')
  }

  aboutToDisappear() {
    console.log('disappear')
  }
}

更多关于HarmonyOS 鸿蒙Next Webview组件加载地图并在其上放置其他组件时Webview不响应点击事件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

19 回复

这个应该是可以实现,展示汽车列表并且可以收放。

1、折叠状态:

2、半屏

3、全屏

图片

图片

图片

更多关于HarmonyOS 鸿蒙Next Webview组件加载地图并在其上放置其他组件时Webview不响应点击事件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


很nice了,

基本信息

这是深色代码主题

虽然与实际需求有点出入,但鸿蒙这里只能勉之了,

现在只能先这么干,把地图web塞进list处理

List({
  'scroller': this.listController
}) {
  ForEach(this.arr, (item, i) => {
    ListItem() {
      if (i == 0) {
        Web({
          src: $rawfile("map.html"),
          controller: this.webController
        })
          .alignRules({
            top: { anchor: '__container', align: VerticalAlign.Top }
          })
          .height('70%')
          .width(CommonConstants.FULL_PARAM)
          .javaScriptAccess(true)
          .id('web')
      } else{
        Text(`${item}`)
          .width('100%')
          .height(150)
          .backgroundColor( 0xFFFFFF)
      }
    }
  }, item => item)
}

这样就都能交互了,但是地图没全屏,体验怪怪的

cke_2737.jpeg

cke_3272.jpeg

你的视频呢?

我懂了,你这个是车辆列表,可以展开的对吧,

你这个很简单,

点击查看,不能塞视频进来。录屏

现在能想到的就是实时设置responseRegion的参数了,

再不行就只能通过动画的方式进行位移了T^T,

import web_webview from '@ohos.web.webview'

@Entry
@Component
struct Index {

    webController: web_webview.WebviewController = new web_webview.WebviewController()
    scrollController: Scroller = new Scroller()
    listController: Scroller = new Scroller()
    @State listPosition: number = 0
    @State arr: string[] = ["1", "2"]
    @State rowRatio: number = 0

    @State stackHeight: number = 0
    @State stackWidth: number = 0

    build() {

        Stack() {
            Web({
                src: $rawfile("map.html"),
                controller: this.webController
            })
                .height(CommonConstants.FULL_PARAM)
                .width(CommonConstants.FULL_PARAM)
                .javaScriptAccess(true)
                .id('web')

            Scroll(this.scrollController) {
                Column() {
                    Row()
                        .height('70%')
                        .width(CommonConstants.FULL_PARAM)
                        .enabled(false)
                        .onVisibleAreaChange([0.0, 1.0], (_, ratio) => {
                            this.rowRatio = ratio;
                        })
                    List({
                        'scroller': this.listController
                    }) {
                        ForEach(this.arr, (item, i) => {
                            ListItem() {
                                Text(`${item}`)
                                    .width('100%')
                                    .height(150)
                                    .backgroundColor(0xFFFFFF)
                                    .enabled(i != 0)
                            }
                        }, item => item)
                    }
                    .edgeEffect(EdgeEffect.None)
                    .width(CommonConstants.FULL_PARAM)
                    .onReachStart(() => {
                        this.listPosition = 0;
                    })
                    .onReachEnd(() => {
                        this.listPosition = 2;
                    })
                    .onTouch((event) => {
                        console.log('111list')
                    })
                    .onScrollFrameBegin((offset) => {
                        if (this.rowRatio <= 1 && this.rowRatio > 0) {
                            this.scrollController.scrollBy(0, offset)
                            return { offsetRemain: 0 }
                        }
                        if (this.rowRatio == 0) {
                            if ((this.listPosition == 0 && offset <= 0) /*|| this.listPosition == 2 && offset >= 0*/) {
                                this.scrollController.scrollBy(0, offset)
                                return { offsetRemain: 0 }
                            }
                            return { offsetRemain: offset }
                        }
                    })
                }
                .height(CommonConstants.FULL_PARAM)
                .width(CommonConstants.FULL_PARAM)
            }
            .height("10%")
            .width(CommonConstants.FULL_PARAM)
            .id('cardList')
            .border({width: 2, color: Color.Orange, style: BorderStyle.Dashed})
            .position({
                x: 0,
                y: 0
            })

            Row() {
                Text('11').backgroundColor(Color.Blue)
            }
            .id('menuList')
            .backgroundColor(Color.Green)
            .width('10%')
            .height('50%')
            .position({
                x: this.stackWidth * 0.9,
                y: 0
            })
        }
        .height(CommonConstants.FULL_PARAM)
        .width(CommonConstants.FULL_PARAM)
        .onAreaChange((_, newValue: Area) => {
            this.stackHeight = newValue.height as number
            this.stackWidth = newValue.width as number
        })
    }
}

class CommonConstants{
    static FULL_PARAM = "100%"
}

大佬,scroll需求就是全屏麻烦看看楼下视频呢,谢谢。

想解决的就是空白那一块 操作事件给到map,scroll不相应。

用叠加容器组件,

stack?也是一样的就是从stack换成relative的,

没遇到过,叠加容易,我用着很正常,叠加组件都可以按,要不要检查下先后顺序和布局大小?

我扔个源码试试?大佬瞅瞅呢?

build() { RelativeContainer() { Web({ src: “map.html”, controller: this.webController }) .alignRules({ top: { anchor: ‘__container’, align: VerticalAlign.Top } }) .height(CommonConstants.FULL_PARAM) .width(CommonConstants.FULL_PARAM) .javaScriptAccess(true) .id(‘web’) Scroll(this.scrollController) { Column() { //不需要任何事件 Row() .height(‘70%’) .width(CommonConstants.FULL_PARAM) .enabled(false) .onVisibleAreaChange([0.0, 1.0], (_, ratio) => { this.rowRatio = ratio; }) List({ ‘scroller’: this.listController }) { ForEach(this.arr, (item, i) => { ListItem() { Text(${item}) .width(‘100%’) .height(150) .backgroundColor(0xFFFFFF) .enabled(i != 0) } }, item => item) } //嵌套list需要设置该属性否则ui有问题,滑动也有问题 .edgeEffect(EdgeEffect.None) // .height(‘60%’) .width(CommonConstants.FULL_PARAM) .onReachStart(() => { this.listPosition = 0; }) .onReachEnd(() => { this.listPosition = 2; }) .onTouch((event) => { this.a = event.type != TouchType.Up; console.log(‘111list’) }) //列表开始滑动是的事情 .onScrollFrameBegin((offset) => { if (this.rowRatio <= 1 && this.rowRatio > 0) { //区域没隐藏完 this.scrollController.scrollBy(0, offset) return { offsetRemain: 0 } } if (this.rowRatio == 0) { //隐藏完了 if ((this.listPosition == 0 && offset <= 0) /|| this.listPosition == 2 && offset >= 0/ ) { this.scrollController.scrollBy(0, offset) return { offsetRemain: 0 } } return { offsetRemain: offset } } }) } .height(CommonConstants.FULL_PARAM) .width(CommonConstants.FULL_PARAM) } .alignRules({ top: { anchor: ‘container’, align: VerticalAlign.Top } }) /.responseRegion({ x: 0, y: ‘70%’, width: ‘100%’, height: ‘100%’ })/ //触摸事件相关api // .hitTestBehavior(this.a ? HitTestMode.Default : HitTestMode.None) .height(CommonConstants.FULL_PARAM) .width(CommonConstants.FULL_PARAM) .id(‘cardList’) //右上角的菜单 Row() { Text(‘11’).backgroundColor(Color.Blue) } .alignRules({ top: { anchor: ‘container’, align: VerticalAlign.Top }, right: { anchor: ‘container’, align: HorizontalAlign.End } }) .id(‘menuList’) .backgroundColor(Color.Green) .width(‘10%’) .height(‘50%’) } .height(CommonConstants.FULL_PARAM) .width(CommonConstants.FULL_PARAM) }

https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-universal-attributes-hit-test-behavior-0000001427744800-V3

hitTestBehavior使用该api可以控制交互事件,但是两个组件都在响应同一事件,两个都在动,稍微有点蠢。

在HarmonyOS鸿蒙Next中,当使用Webview组件加载地图并在其上放置其他组件时,可能会出现Webview不响应点击事件的问题。这通常是由于Webview和其他组件的层级关系或事件传递机制导致的。鸿蒙系统的UI框架采用了基于ArkTS的声明式UI开发范式,Webview组件在加载外部网页时,可能会与上层放置的组件产生事件冲突。

具体来说,Webview组件在加载地图时,地图本身会处理大部分触摸事件,而覆盖在Webview上的其他组件可能会拦截这些事件,导致Webview无法正确响应。鸿蒙系统的事件分发机制会优先将事件传递给最上层的组件,如果这些组件没有正确处理或传递事件,Webview就无法接收到点击事件。

解决这一问题可以通过调整组件的层级关系或事件处理逻辑,确保事件能够正确传递到Webview组件。此外,也可以通过设置Webview的焦点或事件拦截属性,来优化事件的分发和处理流程。

回到顶部