浏览代码

Merge pull request #91 from UnityTech/xwzhu

Android SAFE AREA + KEYBOARD SHOW/HIDE EVENT LISTENER
/main
GitHub 6 年前
当前提交
56dfa3bf
共有 11 个文件被更改,包括 314 次插入42 次删除
  1. 7
      README-ZH.md
  2. 11
      README.md
  3. 4
      Runtime/Plugins/platform/ios/UIWidgetsViewController.mm
  4. 87
      Runtime/engine/DisplayMetrics.cs
  5. 5
      Runtime/engine/UIWidgetsPanel.cs
  6. 8
      Runtime/Plugins/platform/android/view.meta
  7. 157
      Runtime/Plugins/platform/android/view/UIWidgetsViewController.java
  8. 32
      Runtime/Plugins/platform/android/view/UIWidgetsViewController.java.meta
  9. 13
      Runtime/Plugins/platform/android/view/UIWidgetsViewMetrics.java
  10. 32
      Runtime/Plugins/platform/android/view/UIWidgetsViewMetrics.java.meta

7
README-ZH.md


1. 选择**File** > **Build Settings...**打开Build Settings面板。
2. 选择目标平台,点击Build。 之后Unity编辑器将自动组装所有相关资源并生成最终的应用程序包。
#### 如何加载图像?
#### 五、如何加载图像?
1. 将你的图像文件,如image1.png,放在Resources文件夹中。
2. 你可以在同一文件夹中添加image1@2.png和image1@3.png以支持高清屏幕显示。
3. 使用Image.asset(“image1”)加载图像。 注意:因为是在Unity中,所以不需要添加.png后缀。

1. 假设你有一个loading1.gif文件,将其重命名为loading1.gif.bytes并复制到Resources文件夹。
2. 你可以在同一文件夹中添加loading1@2.gif.bytes和loading1@3.gif.bytes以支持高清屏幕显示。
3. 使用Image.asset(“loading1.gif”)加载gif图像。
#### 六、在安卓上显示状态栏
当一个Unity项目运行在Android设备上时,状态栏是默认隐藏且无法在编辑内进行调整的。
如果您希望在您的UIWidgets App中显示状态栏,您可以使用这个[解决方案](https://github.com/Over17/UnityShowAndroidStatusBar)。我们将尽快推出我们自己的解决方案,并保证届时开发者可以进行无缝切换。
## 调试UIWidgets应用程序

11
README.md


you need to enclose them with window scope.
Please see [HttpRequestSample](./Samples/UIWidgetSample/HttpRequestSample.cs) for detail.
For callback/event handler methods from UIWidgets (e.g ```Widget.build, State.initState...```), you don't need do
it yourself, since the framework ensure it's in window scope.
it yourself, since the framework ensure it's in window scope.
#### Show Status Bar on Android
Status bar is always hidden by default when an Unity project is running on an Android device. If you
want to show the status bar in your App, this
[solution](https://github.com/Over17/UnityShowAndroidStatusBar) seems to be
compatible to UIWidgets, therefore can be used as a good option before we release our
full support solution on this issue.
## Debug UIWidgets Application
#### Define UIWidgets_DEBUG

4
Runtime/Plugins/platform/ios/UIWidgetsViewController.mm


padding.top = cur_padding;
}
UIWidgetsMethodMessage(@"ViewportMatricsChanged", @"UIWidgetViewController.keyboardHide", @[]);
UIWidgetsMethodMessage(@"ViewportMatricsChanged", @"UIWidgetViewController.keyboardChanged", @[]);
}
-(void)keyboardWillChangeFrame:(NSNotification*)notification {

viewInsets.bottom = bottom * scale;
padding.bottom = 0;
UIWidgetsMethodMessage(@"ViewportMatricsChanged", @"UIWidgetViewController.keyboardHide", @[]);
UIWidgetsMethodMessage(@"ViewportMatricsChanged", @"UIWidgetViewController.keyboardChanged", @[]);
}
-(void)tryLaunch {

87
Runtime/engine/DisplayMetrics.cs


using UnityEngine;
namespace Unity.UIWidgets.engine {
[StructLayout(LayoutKind.Sequential)]
public struct viewMetrics {
public float insets_top;

void OnGUI();
void Update();
float devicePixelRatio { get; }
float devicePixelRatio { get; }
public class PlayerDisplayMetrics: DisplayMetrics {
public class PlayerDisplayMetrics : DisplayMetrics {
float _devicePixelRatio = 0;
viewMetrics? _viewMetrics = null;

public void OnGUI() {
}
public void Update() {

return this._devicePixelRatio;
}
#if UNITY_ANDROID
#if UNITY_ANDROID
#if UNITY_WEBGL
#if UNITY_WEBGL
#if UNITY_IOS
#if UNITY_IOS
this._devicePixelRatio = IOSDeviceScaleFactor();
#endif

return this._devicePixelRatio;
}
get {
get {
this.viewMetrics.padding_top,
this.viewMetrics.padding_right,
this.viewMetrics.padding_bottom);
this.viewMetrics.padding_top,
this.viewMetrics.padding_right,
this.viewMetrics.padding_bottom);
public WindowPadding viewInsets {
get {
return new WindowPadding(this.viewMetrics.insets_left,
this.viewMetrics.insets_top,
this.viewMetrics.insets_right,
this.viewMetrics.insets_bottom);
}
public WindowPadding viewInsets {
get {
return new WindowPadding(this.viewMetrics.insets_left,
this.viewMetrics.insets_top,
this.viewMetrics.insets_right,
this.viewMetrics.insets_bottom);
}
}
public viewMetrics viewMetrics {

}
this._viewMetrics = new viewMetrics {
insets_bottom = 0,
insets_left = 0,
insets_right = 0,
insets_top = 0,
padding_left = Screen.safeArea.x,
padding_top = Screen.safeArea.y,
padding_right = Screen.width - Screen.safeArea.width - Screen.safeArea.x,
padding_bottom = Screen.height - Screen.safeArea.height - Screen.safeArea.y
};
using (
AndroidJavaClass viewController =
new AndroidJavaClass("com.unity.uiwidgets.plugin.UIWidgetsViewController")
) {
AndroidJavaObject metrics = viewController.CallStatic<AndroidJavaObject>("getMetrics");
float insets_bottom = metrics.Get<float>("insets_bottom");
float insets_top = metrics.Get<float>("insets_top");
float insets_left = metrics.Get<float>("insets_left");
float insets_right = metrics.Get<float>("insets_right");
float padding_bottom = metrics.Get<float>("padding_bottom");
float padding_top = metrics.Get<float>("padding_top");
float padding_left = metrics.Get<float>("padding_left");
float padding_right = metrics.Get<float>("padding_right");
this._viewMetrics = new viewMetrics {
insets_bottom = insets_bottom,
insets_left = insets_left,
insets_right = insets_right,
insets_top = insets_top,
padding_left = padding_left,
padding_top = padding_top,
padding_right = padding_right,
padding_bottom = padding_bottom
};
}
#elif UNITY_WEBGL
this._viewMetrics = new viewMetrics {
insets_bottom = 0,

}
}
#if UNITY_ANDROID
#if UNITY_ANDROID
static float AndroidDevicePixelRatio() {
using (
AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")

[DllImport("__Internal")]
static extern viewMetrics IOSGetViewportPadding();
#endif
}
}

5
Runtime/engine/UIWidgetsPanel.cs


protected override void OnEnable() {
base.OnEnable();
#if UNITY_ANDROID
Screen.fullScreen = false;
#endif
//Disable the default touch -> mouse event conversion on mobile devices
Input.simulateMouseWithTouches = false;

8
Runtime/Plugins/platform/android/view.meta


fileFormatVersion: 2
guid: 33b91e29c97a04d1cb40bd11039c8078
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

157
Runtime/Plugins/platform/android/view/UIWidgetsViewController.java


package com.unity.uiwidgets.plugin;
import android.util.Log;
import com.unity3d.player.UnityPlayer;
import android.graphics.Rect;
import android.os.Build;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.Surface;
import java.util.Arrays;
import android.view.WindowManager;
import android.os.Handler;
public class UIWidgetsViewController {
private static UIWidgetsViewController _instance;
public static UIWidgetsViewController getInstance() {
if (_instance == null) {
_instance = new UIWidgetsViewController();
_instance.setup();
}
return _instance;
}
private UIWidgetsViewMetrics viewMetrics;
private boolean keyboardOpen;
private void setup() {
Log.i("tag", "On Setup");
keyboardOpen = false;
viewMetrics = new UIWidgetsViewMetrics();
updateViewMetrics();
setupViewMetricsChangedListener();
}
public static UIWidgetsViewMetrics getMetrics() {
UIWidgetsViewController controller = getInstance();
return controller.viewMetrics;
}
enum ZeroSides { NONE, LEFT, RIGHT, BOTH }
ZeroSides calculateShouldZeroSides(View unityView) {
Activity activity = UnityPlayer.currentActivity;
int orientation = activity.getResources().getConfiguration().orientation;
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (rotation == Surface.ROTATION_90) {
return ZeroSides.RIGHT;
}
else if (rotation == Surface.ROTATION_270) {
return Build.VERSION.SDK_INT >= 23 ? ZeroSides.LEFT : ZeroSides.RIGHT;
} else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
return ZeroSides.BOTH;
}
}
return ZeroSides.NONE;
}
public boolean lastStatusBarHidden = true;
private int calculateBottomKeyboardInset(Rect insets) {
if (keyboardOpen) {
return insets.bottom;
} else {
return 0;
}
}
public void updateViewMetrics() {
final View unityView = ((ViewGroup)UnityPlayer.currentActivity.findViewById(android.R.id.content)).getChildAt(0);
Rect rect = new Rect();
unityView.getWindowVisibleDisplayFrame(rect);
rect.bottom = unityView.getRootView().getHeight() - (rect.bottom - rect.top) - rect.top;
rect.right = unityView.getRootView().getWidth() - (rect.right - rect.left) - rect.left;
boolean statusBarHidden = (View.SYSTEM_UI_FLAG_FULLSCREEN & unityView.getWindowSystemUiVisibility()) != 0;
boolean navigationBarHidden = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION & unityView.getWindowSystemUiVisibility()) != 0;
ZeroSides zeroSides = ZeroSides.NONE;
if (navigationBarHidden) {
zeroSides = calculateShouldZeroSides(unityView);
}
viewMetrics.padding_top = rect.top;
viewMetrics.padding_right = zeroSides == ZeroSides.RIGHT || zeroSides == ZeroSides.BOTH ? 0 : rect.right;
viewMetrics.padding_bottom = 0;
viewMetrics.padding_left = zeroSides == ZeroSides.LEFT || zeroSides == ZeroSides.BOTH ? 0 : rect.left;
viewMetrics.insets_top = 0;
viewMetrics.insets_right = 0;
viewMetrics.insets_bottom = navigationBarHidden? calculateBottomKeyboardInset(rect) : rect.bottom;
viewMetrics.insets_left = 0;
}
public void setupViewMetricsChangedListener() {
final View unityView = ((ViewGroup)UnityPlayer.currentActivity.findViewById(android.R.id.content)).getChildAt(0);
UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
unityView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(final int visibility){
boolean statusBarHidden = (View.SYSTEM_UI_FLAG_FULLSCREEN & visibility) != 0;
unityView.setSystemUiVisibility(visibility);
UIWidgetsViewController controller = getInstance();
if (statusBarHidden != controller.lastStatusBarHidden) {
controller.onViewMetricsChanged();
}
}
});
}
});
unityView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private final int defaultKeyboardHeightDP = 100;
private final int estimatedKeyboardDP = defaultKeyboardHeightDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
private final Rect rect = new Rect();
@Override
public void onGlobalLayout() {
int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, estimatedKeyboardDP, unityView.getResources().getDisplayMetrics());
unityView.getWindowVisibleDisplayFrame(rect);
int heightDiff = unityView.getRootView().getHeight() - (rect.bottom - rect.top);
boolean isShown = heightDiff >= estimatedKeyboardHeight;
if (keyboardOpen == isShown) {
return;
}
keyboardOpen = isShown;
onViewMetricsChanged();
}
}
);
}
public void onViewMetricsChanged() {
updateViewMetrics();
UIWidgetsMessageManager.getInstance().UIWidgetsMethodMessage("ViewportMatricsChanged", "UIWidgetViewController.keyboardChanged",
Arrays.asList(""));
}
}

32
Runtime/Plugins/platform/android/view/UIWidgetsViewController.java.meta


fileFormatVersion: 2
guid: dd01a28ebf279449dace0dc8580a9ece
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

13
Runtime/Plugins/platform/android/view/UIWidgetsViewMetrics.java


package com.unity.uiwidgets.plugin;
public class UIWidgetsViewMetrics {
public float insets_top;
public float insets_bottom;
public float insets_left;
public float insets_right;
public float padding_top;
public float padding_bottom;
public float padding_left;
public float padding_right;
}

32
Runtime/Plugins/platform/android/view/UIWidgetsViewMetrics.java.meta


fileFormatVersion: 2
guid: efb8c112055a04b7dae8566ccf299bc7
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存