UE4中对移动端键盘弹出/监听的处理

19 篇文章 1 订阅

UE4中对移动端键盘弹出/监听的处理

1.简述

背景:现有UE4的EditableText控件实现了输入文本并发送的基本功能。但是,点击输入框才可以弹出系统键盘,如果需要达到比如微信朋友圈的功能,比如自定义时机弹出,或对键盘弹出时监听等操作,则还需要一定的改造。可以发散思路,对可任意编辑文本框的控件进行改造,实现对获取文本、文本修改、键盘弹出、弹出监听等的功能来达到以上效果。

UE4中支持使用标准弹出对话框输入框或操作系统的虚拟键盘,启用方式可以参考
UE4Android虚拟键盘

2.处理方法

继承和调用关系:
UChatWidget(项目实际使用的Widget,访问公开API接口)— XXXInputPanel(包含输入框的面板)—SEditableText(输入框)— 基类SWidget

需要注意的是:
UWidget:是Widget Blueprint里面的可视化编辑控件,解决了SWidget编辑困难的问题,在运行时会转换为SWidget
SWidget:是UE运行时的真正控件,我们可以直接通过代码New进行创建

如果迷惑改哪个类,为何改,可以参考这篇科普文章:Slate/UMG/UWidget/SWidget的差别

具体实现:

以下实现对获取文本、文本修改、键盘弹出、弹出监听等的功能新增部分(可参考注释理解):

UChatWidget.h 声明委托和定义委托变量/函数

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTextFocus);

class EMOTIONPLUGIN_API UChatWidget: public UWidget
{
public:
	UPROPERTY(BlueprintAssignable, Category="InputBox|Event")
	FTextFocus TextFocusEvent;
	...//函数定义略
}

UChatWidget.cpp 主要处理对外接口

TSharedRef<SWidget> UChatWidget::RebuildWidget()
{
	SAssignNew(InputPanel, XXXInputPanel)
	.OnSend(BIND_UOBJECT_DELEGATE(FOnSend, OnInputPanelSend))//发送的绑定委托
	.OnTextFocus(BIND_UOBJECT_DELEGATE(FOnTextFocus, OnTextFocus))//键盘弹出的绑定委托
	return InputPanel.ToSharedRef();
}

//键盘弹出监听
void UChatWidget::OnTextFocus() const
{
   TextFocusEvent.Broadcast();
}
//设置键盘主动弹出
void UChatWidget::SetInputFocus()
{
   if (InputPanel.IsValid())
   {
      InputPanel->SetInputFocus();
   }
}
//设置编辑框内文本
void UChatWidget::SetInputText(FText InText)
{
   if ( InputPanel.IsValid() )
   {
      //与 Slate数据绑定
      const TAttribute<FText> TextBinding = TAttribute<FText>(InText);
      InputPanel->SetInputText(TextBinding);
   }
}
//获取编辑框内文本
FString UChatWidget::GetInputText()
{
   if (InputPanel.IsValid())
   {
      return InputPanel->GetInputText();
   }
   else
   {
      return "";
   }
}

XXXInputPanel.h

DECLARE_DELEGATE(FOnTextFocus)

class XXX_API XXXInputPanel: public SXXWidget
{
	SLATE_EVENT(FOnTextFocus, OnTextFocus)
public: //定义func,略
	...
private:
	FOnTextFocus OnTextFocusEvent;
}

XXXInputPanel.cpp 主要在输入框构造函数内做如下处理

void XXXInputPanel::Construct(const FArguments& InArgs)
{
OnTextFocusEvent = InArgs._OnTextFocus;
...
ChildSlot
[
SAssignNew(InputBox, SEditableText)
.ReturnKeyType(EReturnKeyType::ReturnKey_Go)
.VirtualKeyboardTrigger(EVirtualKeyboardTrigger::OnAllFocusEvents)  //将键盘触发方式改成所有,只有这样才可以接收我们代码控制的SetFocus事件,默认只接收点击事件
.VirtualKeyboardDismissAction(EVirtualKeyboardDismissAction::TextCommitOnAccept)
.HintText(InArgs._HintText)
.OnTextChanged(this, &XXXInputPanel::OnInputTextChange)
.OnTextCommitted(this, &XXXInputPanel::OnInputTextCommitted)
.OnEditableTextFocus(this, &XXXInputPanel::HandleOnFocus) //这里绑定处理键盘打开后的广播,后由Lua处建立监听
]
...
}

//执行委托触发相应的对象的函数
void XXXInputPanel::HandleOnFocus()
{
   OnTextFocusEvent.ExecuteIfBound();
}

//主动打开键盘
void XXXInputPanel::SetInputFocus()
{
   FSlateApplication::Get().SetKeyboardFocus(InputBox, EFocusCause::SetDirectly);
   FSlateApplication::Get().SetUserFocus(0, InputBox, EFocusCause::SetDirectly);
}

//设置编辑框内文本
void XXXInputPanel::SetInputText(TAttribute<FText> Text)
{
   InputBox.Get()->SetText(Text);
}

//获取编辑框内文本
FString XXXInputPanel::GetInputText()
{
   SEditableText* EditableTextPtr = InputBox.Get();
   return EditableTextPtr->GetText().ToString();
}

SEditableText.cpp :需监听键盘打开时,在父类SEditableText添加绑定

//这里由 Slate 事件返回给系统,通知并处理接收到事件Focus
FReply SEditableText::OnFocusReceived( const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent )
{
   EditableTextLayout->HandleFocusReceived(InFocusEvent);
   OnEditableTextFocus(); //这里添加调用委托,与上文使用套路一致
   return FReply::Handled();
}

void SEditableText::OnEditableTextFocus()
{
   OnEditableTextFocusCallback.ExecuteIfBound();
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值