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 主要在输入框构造函数内做如下处理文章来源:https://www.toymoban.com/news/detail-497274.html
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添加绑定文章来源地址https://www.toymoban.com/news/detail-497274.html
//这里由 Slate 事件返回给系统,通知并处理接收到事件Focus
FReply SEditableText::OnFocusReceived( const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent )
{
EditableTextLayout->HandleFocusReceived(InFocusEvent);
OnEditableTextFocus(); //这里添加调用委托,与上文使用套路一致
return FReply::Handled();
}
void SEditableText::OnEditableTextFocus()
{
OnEditableTextFocusCallback.ExecuteIfBound();
}
到了这里,关于UE4中对移动端键盘弹出/监听的处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!