当前位置: 首页 > article >正文

【每日学点鸿蒙知识】Hap 安装失败、ArkTS 与C++ 数组转换、渐变遮罩效果等

1、在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install failed due to older sdk version in the device”错误信息。

这是由于编译打包所使用的SDK版本与设备镜像版本不匹配。不匹配的场景包括:

场景一:设备上的镜像版本低于编译打包的SDK版本,请更新设备镜像版本。查询设备镜像版本命令:

hdc shell param get const.ohos.apiversion

如果镜像提供的api版本为10,且应用编译所使用的SDK版本也为10,仍出现该报错,可能是由于镜像版本较低,未兼容新版本SDK校验规则,请将镜像版本更新为最新版本。

场景二:对于需要运行在OpenHarmony设备上的应用,请确认runtimeOS已改为OpenHarmony。

2、在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install sign info inconsistent”错误信息。

这由于设备上已安装的应用与新安装的应用中签名不一致。如果在Edit Configurations中勾选了“Keep Application Data”(不卸载应用,覆盖安装),并且重新进行了签名,将导致该报错。
卸载设备上已安装的应用,或取消勾选“Keep Application Data”后,重新安装新的应用。

3、如何实现RichEditor和Component成为一个整体?

RichEditor上面有个Component,现在希望RichEditor和Component成为一个整体,能够自适应光标位置进行滚动,应该如何实现,目前用Scroller无法获取RichEditor中光标的具体坐标(光标基于RichEditor的x和y位置),无法实现滚动。

可以用Scroll将RichEditor和Component包裹,通过onAreaChange的回调,调用scroller.scrollBy的能力,以此来改变滚动组件的高度。

可以参考代码:

@Entry
@Component
struct Index {
  editorController = new RichEditorController()
  scroller: Scroller = new Scroller()

  build() {
    Column() {
      Scroll(this.scroller) {
        Column() {
          Image($r('app.media.startIcon'))
            .width('100%')
            .height(200)
            .margin({ bottom: 20 })
          RichEditor({ controller: this.editorController })
            .id('RichEditor')
            .width('100%')
            .backgroundColor(Color.Yellow)
            .onReady(() => {
              this.editorController.addImageSpan($r("app.media.startIcon"),
                {
                  imageStyle:
                  {
                    size: ["100px", "100px"]
                  }
                })
              this.editorController.addTextSpan('男生女生向前冲',
                {
                  style:
                  {
                    fontColor: Color.Blue,
                    fontSize: 30
                  }
                })
            })
            .onAreaChange((_, value) => {
              if (_.height !== value.height) {
                this.scroller.scrollBy(0, Number(value.height) - 200)
              }
            })
          Button('getSpans-文字').onClick((event: ClickEvent) => {
            let getSpans = this.editorController.getSpans({ start: 0 })
            // 必须进行强转才能获取文字信息或者图片信息
            let span0 = getSpans[0] as RichEditorTextSpanResult
          })
          Button('getSpans-图片').onClick((event: ClickEvent) => {
            let getSpans = this.editorController.getSpans({ start: 0 })
            let span1 = getSpans[1] as RichEditorImageSpanResult
          })
          Button('RichEditor获焦').onClick(() => {
            focusControl.requestFocus('RichEditor')
          })
        }
      }
      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
      .scrollBar(BarState.On) // 滚动条常驻显示
      .scrollBarColor(Color.Gray) // 滚动条颜色
    }
  }
}

4、如何实现ArkTS与C/C++的数组转换?

TS2NAPI
TS侧代码:

Button("TS2NAPI")
  .fontSize(50)
  .fontWeight(FontWeight.Bold)
  .onClick(() => {
    let napiArray: Int32Array = new Int32Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    console.info("TS2NAPI: JS   " + napiArray)
    testNapi.TS2NAPI(napiArray)
  })

NAPI侧代码:

// TS array 传到NAPI层
static napi_value TS2NAPI(napi_env env, napi_callback_info info) {
  // 获取TS层传来的参数
  size_t argc = 1;
  napi_value args;
  napi_get_cb_info(env, info, &argc, &args, NULL, NULL);
  napi_value input_array = args;

  // 获取传入数组typedarray生成input_buffer
  napi_typedarray_type type; // 数据类型
  napi_value input_buffer;
  size_t byte_offset; // 数据偏移
  size_t i, length;   // 数据字节大小
  napi_get_typedarray_info(env, input_array, &type, &length, NULL, &input_buffer, &byte_offset);

  // 获取数组数据
  void *data;
  size_t byte_length;
  napi_get_arraybuffer_info(env, input_buffer, &data, &byte_length);

  if (type == napi_int32_array) {
    int32_t *data_bytes = (int32_t *)(data);
    int32_t num = length / sizeof(int32_t);

    string str = "";
    for (int32_t i = 0; i < num; i++) {
      int32_t tmp = *((int32_t *)(data_bytes) + i);
      str += (to_string(tmp) + ' ');
    }
    OH_LOG_INFO(LOG_APP, "TS2NAPI: C++  %{public}s", str.c_str());
  }

  return NULL;
}

NAPI2TS
TS侧代码:

Button("NAPI2TS")
  .fontSize(50)
  .fontWeight(FontWeight.Bold)
  .onClick(() => {
    let napiArray: Int32Array = testNapi.NAPI2TS()
    console.info("NAPI2TS: JS   " + napiArray)
  })

NAPI侧代码:

// NAPI层 array 传到TS层
static napi_value NAPI2TS(napi_env env, napi_callback_info info) {
  // 数据个数
  int num = 10;

  // 创建output_buffer
  napi_value output_buffer;
  void *output_ptr = NULL;
  napi_create_arraybuffer(env, num * sizeof(int32_t), &output_ptr, &output_buffer);

  // output_array
  napi_value output_array;
  napi_create_typedarray(env, napi_int32_array, num, output_buffer, 0, &output_array);

  // 给output_ptr、output_buffer赋值
  int32_t *output_bytes = (int32_t *)output_ptr;
  for (int32_t i = 0; i < num; i++) {
    output_bytes[i] = i;
  }

  string str = "";
  for (int32_t i = 0; i < num; i++) {
    int32_t tmp = *((int32_t *)(output_ptr) + i);
    str += (to_string(tmp) + ' ');
  }
  OH_LOG_INFO(LOG_APP, "NAPI2TS: C++  %{public}s", str.c_str());

  return output_array;
}

实用场景:
ArkTS侧读取rawfile的图片,传递到NAPI侧进行处理,然后传回ArkTS进行展示:

Button("Test")
  .fontSize(50)
  .fontWeight(FontWeight.Bold)
  .onClick(() => {

    getContext().resourceManager.getRawFileContent('test.png').then(value => {
      hilog.info(0x0000, 'getRawFileContent', '%{public}s', 'OK');
      const fileData: Uint8Array = value;
      // 获取图片的ArrayBuffer
      let buffer = fileData.buffer;

      let input = new Uint8Array(buffer)
      let output = testNapi.TEST(input);

      let decodingOptions: image.DecodingOptions = {
        editable: true,
        desiredPixelFormat: 3,
      }
      let imageSource = image.createImageSource(output.buffer);
      imageSource.createPixelMap(decodingOptions).then(map => {
        this.imageSrc = map;
      })
    }).catch((err: BusinessError) => {
      hilog.error(0x0000, 'getRawFileContent', '%{public}s', err.message);
    })
  })

Image(this.imageSrc)
  .height(100)
  .width(100)

5、如何实现顶部渐变遮罩效果?

直播间的弹幕列表顶部需要渐变遮罩效果,如何实现呢?

使用overlay通过属性linearGradient同时使用blendMode让当前浮层与下方list混合实现渐变遮罩效果。
效果图如下:
在这里插入图片描述

参考代码:

@Entry
@Component
struct Index {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  @Builder
  overlayBuilder() {
    Stack()
      .height("100%")
      .width("100%")
      .linearGradient({
        direction: GradientDirection.Bottom, // 渐变方向
        colors: [["#00FFFFFF", 0.0], ["#FFFFFFFF", 0.3]] // 数组末尾元素占比小于1时满足重复着色效果
      })
      .blendMode(BlendMode.DST_IN, BlendApplyType.OFFSCREEN)
      .hitTestBehavior(HitTestMode.None)
  }

  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.arr, (item: number) => {
          ListItem() {
            Text('' + item)
              .width('100%')
              .height(100)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
          }
          .onClick(() => {
            console.log('is click')
          })
        }, (item: string) => item)
      }.width('90%')
      .scrollBar(BarState.Off)
      .overlay(this.overlayBuilder())
      .blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN)
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }
}

http://www.kler.cn/a/470752.html

相关文章:

  • Element-plus表单总结
  • HackMyVM-Again靶机的测试报告
  • nginx http反向代理
  • 路由组件与一般组件的区别
  • 初学STM32 --- USMART
  • 数学建模入门——描述性统计分析
  • 从源码编译Qt5
  • RWKV 语言模型
  • 2025年的加密软件市场如何?
  • 原型模式详解与实践
  • 【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
  • el-date-picker 不响应change事件的解决办法
  • 【每日学点鸿蒙知识】字体大小,镜像语言间距、禁止分屏、Router与Navigation
  • 【Python系列】使用 `psycopg2` 连接 PostgreSQL 数据库
  • 一文理解区块链
  • 【老白学 Java】保存 / 恢复对象状态
  • 【AI落地】AI生成测试用例,claude or gpt?(提效至少 50%)
  • 基于Java的宠物领养与寄养系统(源码+lw+部署文档+讲解),源码可白嫖!
  • Aleo项目参与指南——DePIN360
  • Java内存管理:不可达对象分析与内存泄漏优化技巧 Eclipse Memory Analyzer
  • ChromeDriver 版本不匹配问题解决,ChromeDriver最新版本下载安装教程
  • 【SQL】COUNT()函数 用法详解
  • Java 集合 Collection、List、Set
  • 【一个HTTP请求和一个HTTP会话的区别】
  • 安装Anaconda搭建Python环境,并使用VSCode作为IDE运行Python脚本
  • Android Telephony | 协议测试针对 test SIM attach network 的问题解决(3GPP TS 36523-1-i60)