讨论广场 问答详情
navigation处于分栏状态,如何对textinput进行键盘避让?
ijdiosho 2026-03-10 21:17:41
955 评论 分享

navigation处于分栏状态,右边navDestination页面底部放置一个textinput,如何对textinput实现软键盘避让处理,类似于qq聊天对话那种,有Demo可以参考一下吗?

955 评论 分享
写回答
全部评论(5)
5 楼

自定义标题效果是一样的,可以实现键盘避让,且自定义标题不动,其他的内容随着软键盘弹起。是否可以提供一下您的测试demo方便复现定位。

// Index.ets
@Builder
export function PageOneBuilder(name: string, param: Object) {
  PageOne()
}



@Builder
function titleBuilder(){
  Column(){
    Text('自定义标题')
  }
}

@Component
export struct PageOne {
  pageInfos: NavPathStack = new NavPathStack();

  build() {
    NavDestination(){
      Column(){
        TextInput()
        Button('返回首页')
          .onClick(() => {
            this.pageInfos.pop()
          })
      }.height('100%').justifyContent(FlexAlign.End)
    }
    .title(titleBuilder)
    .onReady((context: NavDestinationContext) => {
      this.pageInfos = context.pathStack;
    })
  }
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  pageInfos: NavPathStack = new NavPathStack();
  @State barStyle: BarStyle = BarStyle.STANDARD;
  build() {
    Navigation(this.pageInfos){
      Column() {
        Button('跳转页面')
          .onClick(() => {
            this.pageInfos.pushPathByName('PageOne', null)
          })
      }
      .height('100%')
      .width('100%')
    }
    .title({
      main: 'NavTitle',
      sub: 'subtitle'
    },
      {
        backgroundBlurStyle: BlurStyle.COMPONENT_THICK,
        barStyle: this.barStyle,
      })
    .titleMode(NavigationTitleMode.Full)
    .hideTitleBar(false)
    .mode(NavigationMode.Split)
  }
}

 

2026-03-16 15:29:18
4 楼

开发者您好,这边验证分栏模式下是可以自动完成键盘避让的,您这边如果没有实现键盘避让是否方便提供一下您的复现代码,方便我们这边进一步分析复现问题。 我这边验证代码如下:

// Index.ets
@Builder
export function PageOneBuilder(name: string, param: Object) {
  PageOne()
}
// 自定义弹窗
@Builder
function customDialogBuilder() {
  Column() {
    Text('自定义弹窗信息').fontSize(20).height(100)
  }.padding(20)
}

@Component
export struct PageOne {
  pageInfos: NavPathStack = new NavPathStack();
  @Builder
  customDialogComponent() {
    customDialogBuilder();
  }

  build() {
    NavDestination(){
      Column(){
        TextInput()
        Button('返回首页')
          .onClick(() => {
            this.pageInfos.pop()
          })
      }.height('100%').justifyContent(FlexAlign.End)
    }
    .title('pageOne')
    .onReady((context: NavDestinationContext) => {
      this.pageInfos = context.pathStack;
    })
  }
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  pageInfos: NavPathStack = new NavPathStack();

  build() {
    Navigation(this.pageInfos){
      Column() {
        Button('跳转页面')
          .onClick(() => {
            this.pageInfos.pushPathByName('PageOne', null)
          })
      }
      .height('100%')
      .width('100%')
    }
    .title('首页')
    .mode(NavigationMode.Split)
  }
}

 

2026-03-13 16:43:55
2026-03-13 16:49:50
如果把NavDestination的title换成自定义组件,要求自定义标题不动,,其他的内容随着软键盘弹起,textinput对text键盘避让
2026-03-13 16:49:50
import router from '@ohos.router';
import window from '@ohos.window';

@Entry
@Component
struct NavigationSplitDemo {
  @State keyboardHeight: number = 0; // 键盘高度
  @State inputText: string = "";
  private context = getContext(this) as common.UIAbilityContext;

  build() {
    Navigation() {
      // 左侧分栏(菜单)
      NavRouter() {
        List() {
          ListItem() {
            NavLink() {
              Text("聊天窗口")
                .fontSize(16)
                .padding(12)
            }
            .to("chatPage")
          }
        }
      }
      .width(200)

      // 右侧分栏(内容页)
      NavDestination() {
        Column() {
          // 聊天记录区域(占满剩余空间)
          Column() {
            Text("聊天记录列表...")
              .fontSize(14)
              .padding(20)
          }
          .flexGrow(1)
          .width('100%')

          // 输入框容器(关键:根据键盘高度调整bottom)
          Row({ space: 8 }) {
            TextInput({ placeholder: "请输入消息..." })
              .value(this.inputText)
              .onChange((val) => {
                this.inputText = val;
              })
              .flexGrow(1)
              .height(40)
              .padding(8)
              .border({ width: 1, radius: 20 })
            
            Button("发送")
              .width(60)
              .height(40)
              .borderRadius(20)
          }
          .width('100%')
          .padding(12)
          .backgroundColor(Color.White)
          // 核心:动态设置底部间距为键盘高度
          .margin({ bottom: this.keyboardHeight })
        }
        .width('100%')
        .height('100%')
        .backgroundColor(Color("#f5f5f5"))
      }
      .title("聊天窗口")
    }
    .splitRatio(0.2) // 分栏比例
    .onAppear(() => {
      // 页面显示时监听键盘高度变化
      this.listenKeyboardHeight();
    })
  }

  // 监听软键盘高度变化
  listenKeyboardHeight() {
    try {
      const lastWindow = window.getLastWindow(this.context);
      lastWindow.onKeyboardHeightChange((height) => {
        // height为0时键盘收起,非0时是键盘高度
        this.keyboardHeight = height;
      });
    } catch (e) {
      console.error("监听键盘高度失败:", e);
    }
  }
}

 

2026-03-12 13:45:09

Window.getLastWindow(getContext()).onKeyboardHeightChange 监听键盘高度变化,动态调整输入框容器的底部间距!

2026-03-12 13:44:32