Fivee

导航

UE4 安卓相关

1, 键盘弹起收回事件

/** Delegate for virtual keyboard being shown/hidden in case UI wants to slide out of the way */
GenericApplication::OnVirtualKeyboardShown()
GenericApplication::OnVirtualKeyboardHidden()

这里有一个小问题, Shown事件, 是通过android的 onGlobalLayout 事件来进行下发的, 而Hidden事件,是由Cpp自己触发的, 大体上没啥问题, 但是如果是小键盘自己的收起动作, Cpp这边会有一个状态的延迟.

修改方法(file:src\com\epicgames\ue4\GameActivity.java.template):

mainView.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener()
{
    ...
    if (bKeyboardShowing)
    {
      // nativeVirtualKeyboardShown( keyboardRect.left, keyboardRect.top, keyboardRect.right, keyboardRect.bottom);
      nativeVirtualKeyboardShown( keyboardRect.left, keyboardRect.top, keyboardRect.right, 0);
      
if (newVirtualKeyboardInput.getY() > 0) { // Log.debug("VK: hide"); newVirtualKeyboardInput.setVisibility(View.GONE); // 新增 nativeVirtualKeyboardVisible(false);//set offscreen newVirtualKeyboardInput.setY(-1000); } } }

 

通过判断mainview的显示区域, 来判断是不是有东西弹出了. 更精确一点的话, 可以参考 Stack Overflow

同时, 修改一下Cpp文件(file:Source\Runtime\Launch\Private\Android\AndroidJNI.cpp):

// Set GVirtualKeyboardShown.This function is declared in the Java-defined class, GameActivity.java: "public native void nativeVirtualKeyboardVisible(boolean bShown)"
JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardVisible(JNIEnv* jenv, jobject thiz, jboolean bShown)
{
    GVirtualKeyboardShown = bShown;

    // remove reference so the object can be clicked again to show the virtual keyboard
    if (!bShown)
    {
        VirtualKeyboardWidget.Reset();
     // broadcast keyboard hidden event
        if (FTaskGraphInterface::IsRunning())
        {
            FGraphEventRef VirtualKeyboardShown = FFunctionGraphTask::CreateAndDispatchWhenReady([&]()
                {
                    FAndroidApplication::Get()->OnVirtualKeyboardHidden().Broadcast();
                }, TStatId(), NULL, ENamedThreads::GameThread);
        }
    }
}

将键盘的收起事件广播, 交个java侧来调用

2, 键盘高度

OnVirtualKeyboardShown 事件是带参数的, 会把键盘view 的rect给传递下来, 但是OnGlobalLayout会在布局改变过程中不断调用, 所以会触发多次回调, 在使用时, 注意判断广播出来的是不是一个有效的rect.

具体的高度细节, 可以通过 onGlobalLayout() 中的日志来自己查看, 粗暴一点的话, visibleScreenYOffset 就是虚拟键盘的高度了.

UE给出了两种键盘模式, Dialog, VirtualKeyboard, 具体的选项位置, 自己查找吧.

Dialog模式,输入框是弹出在顶部, 所以不需要再判断输入框高度了

VirtualKeyboard模式, 输入框会紧贴在虚拟键盘上方, 但是 OnVirtualKeyboardShown 的回调参数中.并没有键盘的高度, 猜测是因为用户可以自定义这个键盘样式, 所以ue无法确定他的高度.

PS: 在IOS上,键盘的高度是固定的,跟屏幕的像素无关,所以IOS版本在处理键盘高度的时候,需要使用独立的策略,只关心 Frame.size.height 就可以了

 3, 键盘切换卡死问题

可以参考 Android EditText setText方法踩坑实录

设置一个标记位,在UE调用android 的时候, 将EditText 的 TextChangedListener 暂时停止响应

        // 57xx行左右
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) { if (settingTextFromProject) { Log.debug("VK onTextChanged settingTextFromProject"); return; }

在 processLastVirtualKeyboardCommand 函数中, 改变这个标记为即可。

 4, 某些机型无法唤起浏览器的问题

修改 GameActivity.java.template.AndroidThunkJava_LaunchURL

            // make sure there is a web browser to handle the URL before trying to start activity (or may crash!)
            if (BrowserIntent.resolveActivity(getPackageManager()) != null)
            {
                Log.debug("[JAVA} AndroidThunkJava_LaunchURL: Starting activity");
                startActivity(BrowserIntent);
            }
            else
            {
                Log.debug("[JAVA} AndroidThunkJava_LaunchURL: Could not find an application to receive the URL intent");
                startActivity(Intent.createChooser(BrowserIntent, "")); // add
            }

找不到默认浏览器,就弹框让他选!

posted on 2021-08-02 17:47  Fivee  阅读(372)  评论(0编辑  收藏  举报