鸿蒙应用框架开发【自绘编辑框】 输入法框架

news2024/11/28 19:00:02

自绘编辑框

介绍

本示例通过输入法框架实现自会编辑框,可以绑定输入法应用,从输入法应用输入内容,显示和隐藏输入法。

效果预览

1

使用说明

1.点击编辑框可以绑定并拉起输入法,可以从输入法键盘输入内容到编辑框。

2.可以点击attach/dettachshow/hideon/off按钮来绑定/解绑、显示/隐藏、开启监听/关闭监听。

3.输入光标信息后点击updateCursor向输入法应用发送光标信息,发送成功会右toast提示。

4.输入选中文本的开始和结束位置,点击changeSelection可以选中文本。

5.选择文本输入类型和Enter键类型后,点击updateAttribute可以更新拉起的输入法的输入类型和Enter键类型,依赖输入法应用是否适配。

具体实现

  • 自绘编辑框

    • 使用输入法框架实现组件绑定输入法应用,监听输入法事件,显示和隐藏输入法,发送光标和编辑框属性到输入法应用功能。
    • 源码链接:[Index.ets]
/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { inputMethod } from '@kit.IMEKit';
import { promptAction } from '@kit.ArkUI';
import { CustomInputText } from '../components/CustomInputText';
import { inputAttribute } from '../utils/InputAttributeInit';
import { logger } from '../utils/Logger';
import { BusinessError } from '@kit.BasicServicesKit';


@Extend(Button) function buttonStyle() {
  .type(ButtonType.Capsule)
  .backgroundColor($r('app.color.button_color'))
  .fontColor(Color.White)
  .fontSize(16)
  .height(40)
  .fontWeight(500)
  .width('100%')
}

@Extend(Select) function selectStyle() {
  .fontColor($r('app.color.text_color'))
  .font({ size: 16, weight: 500 })
}

@Extend(Text) function textStyle() {
  .fontColor($r('app.color.text_color'))
  .fontSize(16)
  .fontWeight(500)
}

@Extend(TextInput) function inputStyle() {
  .type(InputType.Number)
  .height(40)
  .placeholderFont({ size: 14 })
  .margin({ top: 8, bottom: 8 })
  .maxLength(4)
  .layoutWeight(1)
}

@Styles function cardStyle() {
  .padding(12)
  .width('100%')
  .backgroundColor(Color.White)
  .borderRadius(23)
}

@Entry
@Component
struct Index {
  private inputTypeArray: Array<SelectOption> = [];
  private enterKeyArray: Array<SelectOption> = []
  private inputController: inputMethod.InputMethodController = inputMethod.getController();
  private cursorInfo: inputMethod.CursorInfo = { top: 0, left: 0, width: 0, height: 0 };
  @Provide selectStart: number = 0;
  @Provide selectEnd: number = 0;
  @Provide isAttached: boolean = false;
  @Provide isOn: boolean = false;
  @Provide isShow: boolean = false;
  @Provide isChangeSelection: boolean = false;
  @Provide inputTypeIndex: number = 0;
  @Provide enterKeyIndex: number = 0;

  build() {
    Scroll() {
      Column({ space: 12 }) {
        CustomInputText({ inputController: this.inputController })
        this.OperateView()
        this.UpdateView()
        this.AttributeView()
      }
      .width('100%')
    }
    .padding(12)
    .height('100%')
    .width('100%')
    .align(Alignment.Top)
    .backgroundColor($r('app.color.background'))
  }

  @Builder
  OperateView() {
    GridRow({
      columns: { sm: 2, md: 3, lg: 3 }, gutter: 12 }) {
      GridCol({ span: 1 }) {
        Button(this.isAttached ? $r('app.string.detach') : $r('app.string.attach'))
          .buttonStyle(ButtonStyleMode.NORMAL)
          .id('btnAttach')
          .onClick(() => {
            this.isAttached = !this.isAttached;
          })
      }

      GridCol({ span: 1 }) {
        Button(this.isShow ? $r('app.string.hide') : $r('app.string.show'))
          .buttonStyle(ButtonStyleMode.NORMAL)
          .id('btnShow')
          .onClick(() => {
            if (!this.isAttached) {
              promptAction.showToast({ message: $r('app.string.noattach_tips'), bottom: 100 });
              return;
            }
            this.isShow = !this.isShow;
          })
      }

      GridCol({ span: { sm: 2, md: 1, lg: 1 } }) {
        Button(this.isOn ? $r('app.string.off') : $r('app.string.on'))
          .buttonStyle(ButtonStyleMode.NORMAL)
          .id('btnOn')
          .onClick(() => {
            if (!this.isAttached) {
              promptAction.showToast({ message: $r('app.string.noattach_tips'), bottom: 100 });
              return;
            }
            this.isOn = !this.isOn;
          })
      }
    }
    .cardStyle()
  }

  @Builder
  UpdateView() {
    Column({ space: 12 }) {
      Row({ space: 8 }) {
        TextInput({ placeholder: 'left' })
          .inputStyle()
          .id('cursorLeft')
          .enableKeyboardOnFocus(false)
          .onChange((value: string) => {
            this.cursorInfo.left = Number(value).valueOf();
          })
        TextInput({ placeholder: 'top' })
          .inputStyle()
          .id('cursorTop')
          .enableKeyboardOnFocus(false)
          .onChange((value: string) => {
            this.cursorInfo.top = Number(value).valueOf();
          })
        TextInput({ placeholder: 'width' })
          .inputStyle()
          .id('cursorWidth')
          .enableKeyboardOnFocus(false)
          .onChange((value: string) => {
            this.cursorInfo.width = Number(value).valueOf();
          })

        TextInput({ placeholder: 'height' })
          .inputStyle()
          .id('cursorHeight')
          .enableKeyboardOnFocus(false)
          .onChange((value: string) => {
            this.cursorInfo.height = Number(value).valueOf();
          })
      }
      .width('100%')

      Button($r('app.string.update_cursor'))
        .buttonStyle(ButtonStyleMode.NORMAL)
        .id('btnUpdateCursor')
        .onClick(() => {
          this.inputController.updateCursor(this.cursorInfo, (err:BusinessError) =>{
            promptAction.showToast({ message: $r('app.string.update_cursor_tips'), bottom: 100 });
          });
        })
      Row({ space: 8 }) {
        TextInput({ placeholder: 'start' })
          .inputStyle()
          .id('selectStart')
          .enableKeyboardOnFocus(false)
          .onChange((value: string) => {
            this.selectStart = Number(value).valueOf();
          })
        TextInput({ placeholder: 'end' })
          .inputStyle()
          .id('selectEnd')
          .enableKeyboardOnFocus(false)
          .onChange((value: string) => {
            this.selectEnd = Number(value).valueOf();
          })
      }
      .width('100%')

      Button($r('app.string.change_selection'))
        .buttonStyle(ButtonStyleMode.NORMAL)
        .id('btnChangeSelection')
        .onClick(() => {
          this.isChangeSelection = true;
        })
    }
    .cardStyle()
  }

  @Builder
  AttributeView() {
    Column({ space: 12 }) {
      Row() {
        Row() {
          Text($r('app.string.text_input_type'))
            .textStyle()
          Select(this.inputTypeArray)
            .value(inputAttribute.getInputTypeValue(this.inputTypeIndex))
            .selectStyle()
            .id('inputTypeSelect')
            .onSelect((index: number) => {
              this.inputTypeIndex = index;
              focusControl.requestFocus('inputTypeSelect')
            })
        }
        .layoutWeight(1)
        .justifyContent(FlexAlign.Center)

        Row() {
          Text($r('app.string.enter_key_type'))
            .textStyle()
          Select(this.enterKeyArray)
            .value(inputAttribute.getEnterTypeValue(this.enterKeyIndex))
            .selectStyle()
            .id('enterKeySelect')
            .onSelect((index: number) => {
              this.enterKeyIndex = index;
              focusControl.requestFocus('enterKeySelect')
            })
        }
        .layoutWeight(1)
        .justifyContent(FlexAlign.Center)
      }

      Button($r('app.string.update_attribute'))
        .buttonStyle(ButtonStyleMode.NORMAL)
        .id('btnUpdateAttribute')
        .onClick(() => {
          this.inputController.updateAttribute({
            textInputType: inputAttribute.getInputType(this.inputTypeIndex),
            enterKeyType: inputAttribute.getEnterType(this.enterKeyIndex)
          })
          promptAction.showToast({ message: $r('app.string.update_attribute'), bottom: 100 });
        })
    }
    .cardStyle()
  }

  aboutToDisappear() {
    logger.info('Index', 'aboutToDisappear')
    this.inputController.stopInputSession();
  }

  aboutToAppear() {
    logger.info('Index', 'aboutToAppear')
    inputAttribute.getInputTypeSource().forEach((item: Resource) => {
      this.inputTypeArray.push({ value: item });
    })
    inputAttribute.getEnterTypeSource().forEach((item: Resource) => {
      this.enterKeyArray.push({ value: item });
    })
  }
}

源码:[CustomInputText.ets]

/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { inputMethod } from '@kit.IMEKit';
import { promptAction } from '@kit.ArkUI';
import { logger } from '../utils/Logger';
import { inputAttribute } from '../utils/InputAttributeInit';

const LINE_HEIGHT: number = 20;
const END_FLAG: number = 1000;
const TAG: string = 'CustomInputText';

@Component
export struct CustomInputText {
  @State inputText: string = '';
  @State lastInput: string = '';
  @State selectInput: string = '';
  @State cursorInfo: inputMethod.CursorInfo = { top: 0, left: 0, width: 1, height: 25 };
  @State cursorLeft: number = 0;
  @State cursorIndex: number = 0;
  @State selectIndex: number = 0;
  @State inputWidth: number = 320;
  @Consume @Watch('isAttachedChange') isAttached: boolean;
  @Consume @Watch('isOnChange') isOn: boolean;
  @Consume @Watch('isShowChange') isShow: boolean;
  @Consume @Watch('changeSelection') isChangeSelection: boolean;
  @Consume enterKeyIndex: number;
  @Consume inputTypeIndex: number;
  @Consume selectStart: number;
  @Consume selectEnd: number;
  private inputController: inputMethod.InputMethodController = inputMethod.getController();
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);

  build() {
    Stack() {
      Row() {
        Text(this.inputText)
          .fontSize(16)
          .fontFamily('sans-serif')
          .id('inputText')
          .lineHeight(LINE_HEIGHT)
          .maxLines(1)
          .constraintSize({ maxWidth: this.inputWidth })
        Text(this.selectInput)
          .fontSize(16)
          .fontFamily('sans-serif')
          .lineHeight(LINE_HEIGHT)
          .id('selectInput')
          .maxLines(1)
          .backgroundColor($r('app.color.select_color'))
        Text(this.lastInput)
          .fontSize(16)
          .fontFamily('sans-serif')
          .lineHeight(LINE_HEIGHT)
          .id('lastInput')
          .maxLines(1)
      }
      .width(this.inputWidth)

      Text('')
        .width(this.cursorInfo.width)
        .height(this.cursorInfo.height)
        .backgroundColor($r('app.color.cursor_color'))
        .margin({ top: 5 })
        .position({ x: this.cursorLeft, y: 0 })
        .onAreaChange((oldArea: Area, newArea: Area) => {
          if (newArea.globalPosition.x as number !== this.cursorInfo.left) {
            this.cursorInfo.left = newArea.globalPosition.x as number;
            this.cursorInfo.top = newArea.position.y as number;
            this.cursorInfo.width = newArea.width as number;
            this.cursorInfo.height = newArea.height as number;
            logger.info(TAG, `cursor change: this.cursorInfo=${JSON.stringify(this.cursorInfo)}`);
            this.inputController.updateCursor(this.cursorInfo);
          }
        })

      Canvas(this.context)
        .width('100%')
        .height(45)
        .onReady(() => {
          let px = vp2px(16);
          this.context.font = px + 'px sans-serif';
          this.inputWidth = this.context.width;
        })
    }
    .id('customInputText')
    .width('100%')
    .borderRadius(20)
    .backgroundColor($r('app.color.input_text_background'))
    .padding({ left: 10, right: 10, top: 5, bottom: 5 })
    .height(45)
    .onClick((event?: ClickEvent) => {
      if (event) {
        logger.info(TAG, `click event= ${JSON.stringify(event)}`);
        this.initTextInput(event);
      }
    })
  }

  async initTextInput(event: ClickEvent): Promise<void> {
    focusControl.requestFocus('customInputText');
    this.inputController.updateAttribute({
      textInputType: inputAttribute.getInputType(this.inputTypeIndex),
      enterKeyType: inputAttribute.getEnterType(this.enterKeyIndex)
    })
    await this.inputController.attach(false, {
      inputAttribute: {
        textInputType: inputAttribute.getInputType(this.inputTypeIndex),
        enterKeyType: inputAttribute.getEnterType(this.enterKeyIndex)
      }
    });
    this.inputController.showTextInput();
    this.isAttached = true;
    this.isShow = true;
    this.isOn = true;
    this.calculateCursor(event.x);
  }

  async isAttachedChange(): Promise<void> {
    if (this.isAttached) {
      focusControl.requestFocus('customInputText');
      await this.inputController.attach(false, {
        inputAttribute: {
          textInputType: inputAttribute.getInputType(this.inputTypeIndex),
          enterKeyType: inputAttribute.getEnterType(this.enterKeyIndex)
        }
      });
    } else {
      this.detach();
    }
  }

  isShowChange(): void {
    if (this.isShow) {
      inputMethod.getController().showTextInput();
    } else {
      inputMethod.getController().hideTextInput();
    }
  }

  isOnChange(): void {
    if (this.isOn) {
      this.initListener();
    } else {
      this.off();
    }
  }

  changeSelection(): void {
    if (this.isChangeSelection) {
      let message = this.inputText + this.selectInput + this.lastInput;
      if (this.selectStart <= this.selectEnd) {
        this.selectIndex = this.selectStart;
        this.cursorIndex = this.selectEnd;
      }
      if (this.selectStart > this.selectEnd) {
        this.selectIndex = this.selectEnd;
        this.cursorIndex = this.selectStart;
      }
      if (this.cursorIndex > message.length) {
        this.cursorIndex = message.length;
      }
      this.inputText = message.substring(0, this.selectIndex);
      this.selectInput = message.substring(this.selectIndex, this.cursorIndex);
      this.lastInput = message.substring(this.cursorIndex, message.length);
      let cursorText = this.inputText + this.selectInput;
      this.cursorLeft = this.context.measureText(cursorText).width;
      this.isChangeSelection = false;
    }
  }

  async detach(): Promise<void> {
    logger.info(TAG, `detach`);
    await this.off();
    this.isOn = false;
    this.isShow = false;
    this.inputController.detach();
  }

  async off(): Promise<void> {
    logger.info(TAG, `off`);
    this.inputController.off('insertText');
    this.inputController.off('deleteLeft');
    this.inputController.off('deleteRight');
    this.inputController.off('moveCursor');
    this.inputController.off('selectByMovement');
    this.inputController.off('selectByRange');
    this.inputController.off('sendFunctionKey')
    this.inputController.off('handleExtendAction');
    this.inputController.off('sendKeyboardStatus');
  }

  initListener(): void {
    this.inputController.on('insertText', (text: string) => {
      logger.info(TAG, `insertText, text: ${text}`);
      if ((this.cursorLeft + this.context.measureText(text).width + this.context.measureText(this.lastInput)
        .width) > this.context.width) {
        return;
      }
      this.inputText += text;
      this.cursorIndex = this.inputText.length;
      this.selectIndex = this.cursorIndex;
      this.selectInput = '';
      this.cursorLeft = this.context.measureText(this.inputText).width;
    })
    this.inputController.on('deleteRight', (length: number) => {
      let message = this.inputText + this.selectInput + this.lastInput;
      if (this.cursorIndex < message.length) {
        this.selectIndex = this.cursorIndex;
        this.selectInput = '';
        let deleteIndex = this.cursorIndex + length;
        if (deleteIndex > message.length) {
          deleteIndex = message.length;
        }
        this.lastInput = message.substring(this.cursorIndex + length, message.length);
      }
    })
    this.inputController.on('deleteLeft', (length: number) => {
      this.inputText = this.inputText.substring(0, this.inputText.length - length);
      this.cursorIndex = this.inputText.length;
      this.selectIndex = this.cursorIndex;
      this.cursorLeft = this.context.measureText(this.inputText).width;
    })
    this.inputController.on('moveCursor', (direction: inputMethod.Direction) => {
      logger.info(TAG, `Succeeded in moveCursor, direction: ${direction}`);
      let message = this.inputText + this.selectInput + this.lastInput;
      this.selectInput = '';
      if (direction === inputMethod.Direction.CURSOR_UP) {
        this.cursorIndex = 0;
      }
      if (direction === inputMethod.Direction.CURSOR_DOWN) {
        this.cursorIndex = message.length;
      }
      if (direction === inputMethod.Direction.CURSOR_LEFT) {
        this.cursorIndex--;
      }
      if (direction === inputMethod.Direction.CURSOR_RIGHT) {
        if (this.cursorIndex < message.length) {
          this.cursorIndex++;
        }
      }
      this.selectIndex = this.cursorIndex;
      this.inputText = message.substring(0, this.cursorIndex);
      this.lastInput = message.substring(this.cursorIndex, message.length);
      this.cursorLeft = this.context.measureText(this.inputText).width;
    });
    this.inputController.on('selectByMovement', (movement: inputMethod.Movement) => {
      logger.info(TAG, `Succeeded in selectByMovement, direction: ${movement.direction}`);
      let message = this.inputText + this.selectInput + this.lastInput;
      if (movement.direction === inputMethod.Direction.CURSOR_UP) {
        this.selectIndex = 0;
      }
      if (movement.direction === inputMethod.Direction.CURSOR_LEFT) {
        if (this.selectIndex > 0) {
          this.selectIndex--;
        }
      }
      if (movement.direction === inputMethod.Direction.CURSOR_RIGHT) {
        if (this.selectIndex < message.length) {
          this.selectIndex++;
        }
      }
      if (movement.direction === inputMethod.Direction.CURSOR_DOWN) {
        this.selectIndex = message.length;
      }
      if (this.selectIndex > this.cursorIndex) {
        this.inputText = message.substring(0, this.cursorIndex);
        this.selectInput = message.substring(this.cursorIndex, this.selectIndex);
        this.lastInput = message.substring(this.selectIndex, message.length);
      } else {
        this.inputText = message.substring(0, this.selectIndex);
        this.selectInput = message.substring(this.selectIndex, this.cursorIndex);
        this.lastInput = message.substring(this.cursorIndex, message.length);
      }
    });
    this.inputController.on('selectByRange', (range: inputMethod.Range) => {
      logger.info(TAG, `selectByRange this.range: ${JSON.stringify(range)}`);
      let message = this.inputText + this.selectInput + this.lastInput;
      if (range.start === 0 && range.end === 0) {
        this.cursorIndex = 0;
        let message = this.inputText + this.selectInput + this.lastInput;
        this.selectInput = '';
        this.selectIndex = this.cursorIndex;
        this.inputText = message.substring(0, this.cursorIndex);
        this.lastInput = message.substring(this.cursorIndex, message.length);
        this.cursorLeft = this.context.measureText(this.inputText).width;
      } else if (range.end > range.start) {
        if (range.end === END_FLAG) {
          this.lastInput = '';
          this.selectIndex = message.length;
          this.inputText = message.substring(0, this.cursorIndex);
          this.selectInput = message.substring(this.cursorIndex, this.selectIndex);
        } else {
          this.selectIndex = 0;
          this.inputText = ''
          this.selectInput = message.substring(0, this.cursorIndex);
          this.lastInput = message.substring(this.cursorIndex, message.length);
        }
      } else {
        this.cursorIndex = message.length;
        this.selectIndex = this.cursorIndex;
        this.inputText = message.substring(0, this.cursorIndex);
        this.lastInput = message.substring(this.cursorIndex, message.length);
        this.cursorLeft = this.context.measureText(this.inputText).width;
      }
      logger.info(TAG, `selectByRange this.selectInput: ${this.selectInput}`);
    })
    this.inputController.on('sendFunctionKey', (enterKey: inputMethod.FunctionKey) => {
      promptAction.showToast({ message: `enterKey Clicked ${enterKey.enterKeyType.toString()}`, bottom: 500 });
    })
    this.inputController.on('sendKeyboardStatus', (keyBoardStatus: inputMethod.KeyboardStatus) => {
      logger.info(TAG, `sendKeyboardStatus keyBoardStatus: ${keyBoardStatus}`);
    });
    this.inputController.on('handleExtendAction', (action: inputMethod.ExtendAction) => {
      if (action === inputMethod.ExtendAction.SELECT_ALL) {
        let message = this.inputText + this.selectInput + this.lastInput;
        this.cursorIndex = message.length;
        this.selectIndex = 0;
        this.inputText = ''
        this.selectInput = message.substring(0, this.cursorIndex);
        this.lastInput = '';
        this.cursorLeft = this.context.measureText(this.selectInput).width;
      }
    })
  }

  calculateCursor(x: number): void {
    let message = this.inputText + this.selectInput + this.lastInput;
    let charWidth = this.context.measureText(message).width / message.length;
    this.cursorIndex = Math.floor(x / charWidth);
    if (this.cursorIndex < 0) {
      this.cursorIndex = 0;
      this.inputText = '';
      this.lastInput = message;
    } else if (this.cursorIndex > message.length) {
      this.cursorIndex = message.length;
      this.inputText = message;
      this.lastInput = '';
    } else {
      this.inputText = message.substring(0, this.cursorIndex);
      this.lastInput = message.substring(this.cursorIndex, message.length);
    }
    this.selectIndex = this.cursorIndex;
    this.selectInput = '';
    this.cursorLeft = this.context.measureText(message.substring(0, this.cursorIndex)).width;
  }
}
  • 参考接口:@ohos.inputMethod

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

在这里插入图片描述

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM老人服务管理系统小程序-计算机毕业设计源码91022

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

跨网段 IP 地址通信故障分析

现如今计算机网络的规模和复杂性不断增加&#xff0c;跨网段通信成为网络运行中的常见需求。但如果设备处于不同网段且路由设置出现偏差时就会导致通信故障&#xff0c;严重影响网络的正常运行和数据传输。 1.跨网段通信的基本原理 跨网段通信依赖于路由器的路由功能。路由器根…

vue3.0 入门基础知识汇总【1】 全面 精简 推荐

这篇博文主要对一些刚入门vue框架的同学&#xff0c;以及对vue基本知识进行巩固的&#xff0c;最后就是精简一下基本知识&#xff0c;以方便自己查看&#xff0c;感谢参考&#xff0c;有问题评论区交流&#xff0c;谢谢。 目录 1.component组件的基本结构和使用 2.method方法…

全网最适合入门的面向对象编程教程:28 类和对象的Python实现-Python编程原则、哲学和规范大汇总

全网最适合入门的面向对象编程教程&#xff1a;28 类和对象的 Python 实现-Python 编程原则、哲学和规范大汇总 摘要&#xff1a; 本文主要介绍了在使用 Python 进行面向对象编程时&#xff0c;Python 异常处理的原则-“请求谅解&#xff0c;而非许可”&#xff0c;以及软件设…

什么是安全编程?

安全编程&#xff08;Secure Programming&#xff09;是一种编程方法论&#xff0c;旨在通过编写安全可靠的代码来保护计算机系统和数据的安全性。它涵盖了软件设计、开发、测试和维护的整个生命周期&#xff0c;旨在最大程度地降低软件漏洞和安全缺陷的风险。以下是对安全编程…

【前端 20】Element-UI快速入门

探索Element UI组件库&#xff1a;快速搭建Vue应用的必备工具 在现代Web开发中&#xff0c;Vue.js以其轻量级和灵活性赢得了广泛的关注。而Element UI&#xff0c;作为Vue.js的一个UI组件库&#xff0c;更是为开发者们提供了丰富、易用的前端组件&#xff0c;极大地加速了开发过…

Spring源码(八)--Spring实例化的策略

Spring实例化的策略有几种 &#xff0c;可以看一下 InstantiationStrategy 相关的类。 UML 结构图 InstantiationStrategy的实现类有 SimpleInstantiationStrategy。 CglibSubclassingInstantiationStrategy 又继承了SimpleInstantiationStrategy。 InstantiationStrategy I…

Java----反射

什么是反射&#xff1f; 反射就是允许对成员变量、成员方法和构造方法的信息进行编程访问。换句话来讲&#xff0c;就是通过反射&#xff0c;我们可以在不需要创建其对象的情况下就可以获取其定义的各种属性值以及方法。常见的应用就是IDEA中的提示功能&#xff0c;当我…

摆弄it:越走越深

在英语中&#xff0c;it是一个单词&#xff0c;就是“它”&#xff0c;这是众所周知的事情。今天&#xff0c;我们就来摆弄一下it&#xff0c;摆弄一下“它”&#xff0c;看看能摆弄出什么名堂来。 一、它是它自己 it 大家都知道&#xff0c;同样&#xff0c;itself&#xff0…

大模型算法面试题(十七)

本系列收纳各种大模型面试题及答案。 1、LoRA权重是否可以合入原模型 LoRA权重可以合入原模型。LoRA&#xff08;Low-Rank Adaptation of Large Language Models&#xff09;是一种用于微调大型语言模型的低秩适应技术。它通过训练低秩矩阵&#xff0c;并将这些参数注入到原始…

onlyoffice用nginx反向代理

我对于onlyoffice的需求就是当个在线编辑器使用。在集成react的时候之前都是写的绝对路径的地址&#xff0c;这样在需要迁移应用的时候就造成了巨大的麻烦&#xff0c;所以我决定用nginx做反向代理&#xff0c;这样我集成的时候就不用每次都修改源码中的地址了。 一开始写的代…

LINUX进程间的通信(IPC)--信号

一、概念 信号通信&#xff0c;其实就是内核向用户空间进程发送信号&#xff0c;只有内核才能发信号&#xff0c;用户空间进程不能发送信号。信号已经是存在内核中的了&#xff0c;不需要用户自己创建。 信号通信的框架 * 信号的发送&#xff08;发送信号进程&#xff09;&am…

阿联酋云手机怎么做TikTok引流?

根据字节跳动广告资源的数据显示&#xff0c;2024年初&#xff0c;TikTok在阿联酋拥有1073万18岁及以上用户&#xff0c;其广告覆盖率达到当地互联网用户群的113%。从2023年初到2024年初&#xff0c;TikTok在阿联酋的潜在广告覆盖率增加了250万&#xff0c;增长率达30.4%。特别…

基于ant-design-vue3多功能操作表格,表头序号为动态添加记录按钮,鼠标在表格记录行,当前行序号显示删除按钮

由于项目需要&#xff0c;并考虑到尽可能让空间利用率高&#xff0c;因此定制开发一个表格组件&#xff0c;组件功能主要是在序号表头位置为添加按钮&#xff0c;点击按钮&#xff0c;新增一行表格数据&#xff1b;表格数据删除不同于以往表格在操作栏定义删除按钮&#xff0c;…

深度学习(概念相关)

深度学习&#xff08;论文相关&#xff09; 深度学习一些概念 通过阅读论文可以理解提取数据特征的重要性 深度学习学习怎么去提取特征 应用领域 深度学习应用&#xff1a; 输入&#xff1a;图像输入或者文字输入 算法&#xff1a;还是基础的模块计算 神经网络中的参数几千…

[JavaScript] 动态获取方法参数名

JavaScript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript基于原型编程、多范式的动态脚本语言&am…

Java导出Excel给每一列设置不同样式示例

Excel导出这里不讲&#xff0c;方法很多&#xff0c;原生的POI可以参照 Java原生POI实现的Excel导入导出&#xff08;简单易懂&#xff09; 这里只说怎么给Excel每一列设置不同的样式&#xff0c;比如下面这样的 直接上代码 Overridepublic void exportTemplate(HttpServletRe…

昇思25天学习打卡营第23天|CV-ResNet50迁移学习

打卡 目录 打卡 迁移学习 实战练习 数据准备 数据处理 数据处理函数 数据处理流程 数据可视化 训练模型 构建Resnet50网络 固定特征进行训练 network 的输出 训练和评估 可视化模型预测 通过本文&#xff0c;了解迁移学习的重点在于&#xff0c;了解你的模型结构…

LGA-4500激光气体分析仪说明手册

目 录 阅 读 说 明 I 用户须知 I 概况 I 注意和警示信息 I 供货和运输 III 质保和维修 III 联系方式 III 一、简介 1 1.1概要 1 1.2测量原理 1 1.2.1单线光谱技术 1 1.2.2激光频率扫描技术 2 1.2.3谱线展宽自动修正技术 2 1.3系统组成 2 1.4系统特点 3 1.5系统指标 4 1.6激光产…

决策树可解释性分析

决策树可解释性分析 决策树是一种广泛使用的机器学习算法&#xff0c;以其直观的结构和可解释性而闻名。在许多应用场景中&#xff0c;尤其是金融、医疗等领域&#xff0c;模型的可解释性至关重要。本文将从决策路径、节点信息、特征重要性等多个方面分析决策树的可解释性&…