HarmonyOS 输入框与软键盘问题

Scroll容器中放入长内容,如果内容有多个TextInput,监听输入后,由于数据修改导致组件刷新,软键盘回消失然后在出现,闪一下。

HarmonyOS
1天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
aquaa

涉及到ForEach循环请把extInput抽成组件,请验证如下代码:

TestTextPage

// ViewModel classes
import { JSON } from '@kit.ArkTS';
import { inputMethod } from '@kit.IMEKit';

let nextId = 0;

@Observed
export class ObservedArray<T> extends Array<T> {
  constructor(args: T[]) {
    console.log(`ObservedArray: ${JSON.stringify(args)} `)
    if (args instanceof Array) {
      super(...args);
    } else {
      super(args)
    }
  }
}

@Observed
export class Address {
  street: string;
  zip: number;
  city: string;

  constructor(street: string,
    zip: number,
    city: string) {
    this.street = street;
    this.zip = zip;
    this.city = city;
  }
}

@Observed
export class Person {
  id_: string;
  name: string;
  address: Address;
  phones: ObservedArray<string>;

  constructor(name: string,
    street: string,
    zip: number,
    city: string,
    phones: string[]) {
    this.id_ = `${nextId}`;
    nextId++;
    this.name = name;
    this.address = new Address(street, zip, city);
    this.phones = new ObservedArray<string>(phones);
  }
}

export class AddressBook {
  me: Person;
  contacts: ObservedArray<Person>;

  constructor(me: Person, contacts: Person[]) {
    this.me = me;
    this.contacts = new ObservedArray<Person>(contacts);
  }
}

@Component
struct PersonView {
  @ObjectLink person: Person;
  @ObjectLink phones: ObservedArray<string>;
  @Link selectedPerson: Person;

  build() {
    Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
      Text(this.person.name)
      Text(JSON.stringify(this.person.address))
      if (this.phones.length) {
        Text(this.phones[0])
      }
    }
    .height(55)
    .backgroundColor(this.selectedPerson.name == this.person.name ? "#ffa0a0" : "#ffffff")
    .onClick(() => {
      this.selectedPerson = this.person;
    })
  }
}

@Component
struct phonesNumber {
  @ObjectLink phoneNumber: ObservedArray<string>
  // private controller = new TextInputController()
  build() {
    Column() {
      ForEach(this.phoneNumber,
        (phone: string, index?: number) => {
          Row(){
            Text(`联系人电话${1+(index??0)}`)
            phoneCom({
              phoneStr:phone
            })
          }
        },
        (phone: ResourceStr, index: number) => `${this.phoneNumber[index] + index}`
      )
    }
  }
}

@Component
struct phoneCom{
  @Prop phoneStr: string ;
  private controller = new TextInputController()
  build() {
    TextInput({ text: this.phoneStr ,controller:this.controller})
      .width(150)
      .key(`key`)
      .onChange((txt)=>{
        let inputMethodController = inputMethod.getController();
        this.phoneStr = txt
        console.log(`--------${txt}-----------${this.phoneStr}`)
        console.log(`--------${JSON.stringify(inputMethodController)}`)

      })
  }
}

@Component
struct PersonEditView {
  @Consume addrBook: AddressBook;
  /* 指向父组件selectedPerson的引用 */
  @Link selectedPerson: Person;
  /*在本地副本上编辑,直到点击保存*/
  @Prop name: string = "";
  @Prop address: Address = new Address("", 0, "");
  @Prop phones: ObservedArray<string> = [];

  selectedPersonIndex(): number {
    return this.addrBook.contacts.findIndex((person: Person) => person.id_ == this.selectedPerson.id_);
  }

  build() {
    Column() {
      TextInput({ text: this.name,controller:new TextInputController() })
        .onChange((value) => {
          this.name = value;
        }).type(InputType.Normal)
      TextInput({ text: this.address.street })
        .onChange((value) => {
          this.address.street = value;
        })

      TextInput({ text: this.address.city })
        .onChange((value) => {
          this.address.city = value;
        })

      TextInput({ text: this.address.zip.toString() })
        .onChange((value) => {
          const result = Number.parseInt(value);
          this.address.zip = Number.isNaN(result) ? 0 : result;
        })

      if (this.phones.length > 0) {
        phonesNumber({ phoneNumber: this.phones })
      }

      Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
        Text("Save Changes")
          .onClick(() => {
            this.selectedPerson.name = this.name;
            this.selectedPerson.address = new Address(this.address.street, this.address.zip, this.address.city)
            this.phones.forEach((phone: string, index: number) => {
              this.selectedPerson.phones[index] = phone
            });
          })
        if (this.selectedPersonIndex() != -1) {
          Text("Delete Contact")
            .onClick(() => {
              let index = this.selectedPersonIndex();
              console.log(`delete contact at index ${index}`);
              // 删除当前联系人
              this.addrBook.contacts.splice(index, 1);
              // 删除当前selectedPerson,选中态前移一位
              index = (index < this.addrBook.contacts.length) ? index : index - 1;
              // 如果contract被删除完,则设置me为选中态
              this.selectedPerson = (index >= 0) ? this.addrBook.contacts[index] : this.addrBook.me;
            })
        }
      }

    }
  }
}

@Component
struct AddressBookView {
  @ObjectLink me: Person;
  @ObjectLink contacts: ObservedArray<Person>;
  @State selectedPerson: Person = new Person("", "", 0, "", []);

  aboutToAppear() {
    this.selectedPerson = this.me;
  }

  build() {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start }) {
      Text("Me:")
      PersonView({
        person: this.me,
        phones: this.me.phones,
        selectedPerson: this.selectedPerson
      })
      Divider().height(8)
      ForEach(this.contacts, (contact: Person) => {
        PersonView({
          person: contact,
          phones: contact.phones as ObservedArray<string>,
          selectedPerson: this.selectedPerson
        })
      },
        (contact: Person): string => {
          return contact.id_;
        }
      )
      Divider().height(8)
      Text("Edit:")
      PersonEditView({
        selectedPerson: this.selectedPerson,
        name: this.selectedPerson.name,
        address: this.selectedPerson.address,
        phones: this.selectedPerson.phones
      })
    }
    .borderStyle(BorderStyle.Solid).borderWidth(5).borderColor(0xAFEEEE).borderRadius(5)
  }
}

@Entry
@Component
export struct TestTextPage { //PageEntry
  @Provide addrBook: AddressBook = new AddressBook(
    new Person("自己啊", "Itamerenkatu 9", 180, "Helsinki", ["18*********", "18*********", "18*********"]),
    [
      new Person("Oly", "Itamerenkatu 9", 180, "Helsinki", ["11*********", "12*********"]),
      new Person("Sam", "Itamerenkatu 9", 180, "Helsinki", ["13*********", "14*********"]),
      new Person("Vivi", "Itamerenkatu 9", 180, "Helsinki", ["15*********", "168*********"]),
    ]);

  build() {
    Column() {
      AddressBookView({
        me: this.addrBook.me,
        contacts: this.addrBook.contacts,
        selectedPerson: this.addrBook.me
      })
    }
  }
}
分享
微博
QQ
微信
回复
1天前
相关问题
CustomDialog软键盘问题
457浏览 • 1回复 待解决
H5页面输入框自动获焦弹起软键盘
1912浏览 • 1回复 待解决
HarmonyOS 键盘遮挡输入框
17浏览 • 1回复 待解决
HarmonyOS 软键盘挤压Toast弹
40浏览 • 1回复 待解决
HarmonyOS 软键盘弹出控制检测
4浏览 • 1回复 待解决
HarmonyOS 软键盘会变为非数字输入
30浏览 • 1回复 待解决
HarmonyOS 自定义键盘输入框焦点问题
115浏览 • 1回复 待解决
关于软键盘弹出遮挡问题
1279浏览 • 1回复 待解决
HarmonyOS 如何控制输入框弹出键盘
25浏览 • 1回复 待解决
HarmonyOS 键盘问题
5浏览 • 1回复 待解决