Add support for Modal in Android
Summary: This diff implements Modal for Android in Fabric Reviewed By: JoshuaGross Differential Revision: D15069863 fbshipit-source-id: 4171c9590a4a7a1f4f80cf9b08ea9a9e94b9097a
This commit is contained in:
Родитель
ecdb239eaa
Коммит
532afbde6e
|
@ -87,6 +87,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||||
sComponentNames.put("Image", "RCTImageView");
|
sComponentNames.put("Image", "RCTImageView");
|
||||||
sComponentNames.put("ScrollView", "RCTScrollView");
|
sComponentNames.put("ScrollView", "RCTScrollView");
|
||||||
sComponentNames.put("Slider", "RCTSlider");
|
sComponentNames.put("Slider", "RCTSlider");
|
||||||
|
sComponentNames.put("ModalHostView", "RCTModalHostView");
|
||||||
sComponentNames.put("Paragraph", "RCTText");
|
sComponentNames.put("Paragraph", "RCTText");
|
||||||
sComponentNames.put("Text", "RCText");
|
sComponentNames.put("Text", "RCText");
|
||||||
sComponentNames.put("RawText", "RCTRawText");
|
sComponentNames.put("RawText", "RCTRawText");
|
||||||
|
|
|
@ -8,9 +8,14 @@
|
||||||
package com.facebook.react.views.modal;
|
package com.facebook.react.views.modal;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.bridge.WritableNativeMap;
|
||||||
import com.facebook.react.common.MapBuilder;
|
import com.facebook.react.common.MapBuilder;
|
||||||
import com.facebook.react.module.annotations.ReactModule;
|
import com.facebook.react.module.annotations.ReactModule;
|
||||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||||
|
import com.facebook.react.uimanager.PixelUtil;
|
||||||
|
import com.facebook.react.uimanager.StateWrapper;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
import com.facebook.react.uimanager.ViewGroupManager;
|
import com.facebook.react.uimanager.ViewGroupManager;
|
||||||
|
@ -102,4 +107,13 @@ public class ReactModalHostManager extends ViewGroupManager<ReactModalHostView>
|
||||||
super.onAfterUpdateTransaction(view);
|
super.onAfterUpdateTransaction(view);
|
||||||
view.showOrUpdate();
|
view.showOrUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(ReactModalHostView view, StateWrapper stateWrapper) {
|
||||||
|
Point modalSize = ModalHostHelper.getModalHostSize(view.getContext());
|
||||||
|
WritableMap map = new WritableNativeMap();
|
||||||
|
map.putDouble("screenWidth", PixelUtil.toDIPFromPixel(modalSize.x));
|
||||||
|
map.putDouble("screenHeight", PixelUtil.toDIPFromPixel(modalSize.y));
|
||||||
|
stateWrapper.updateState(map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_debug_preprocessor_flags")
|
||||||
|
load(
|
||||||
|
"//tools/build_defs/oss:rn_defs.bzl",
|
||||||
|
"ANDROID",
|
||||||
|
"APPLE",
|
||||||
|
"fb_xplat_cxx_test",
|
||||||
|
"get_apple_compiler_flags",
|
||||||
|
"get_apple_inspector_flags",
|
||||||
|
"react_native_target",
|
||||||
|
"react_native_xplat_target",
|
||||||
|
"rn_xplat_cxx_library",
|
||||||
|
"subdir_glob",
|
||||||
|
)
|
||||||
|
|
||||||
|
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
|
||||||
|
|
||||||
|
rn_xplat_cxx_library(
|
||||||
|
name = "modal",
|
||||||
|
srcs = glob(
|
||||||
|
["**/*.cpp"],
|
||||||
|
exclude = glob([
|
||||||
|
"tests/**/*.cpp",
|
||||||
|
"platform/**/*.cpp",
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
headers = [],
|
||||||
|
header_namespace = "",
|
||||||
|
exported_headers = subdir_glob(
|
||||||
|
[
|
||||||
|
("", "*.h"),
|
||||||
|
],
|
||||||
|
prefix = "react/components/modal",
|
||||||
|
),
|
||||||
|
compiler_flags = [
|
||||||
|
"-fexceptions",
|
||||||
|
"-frtti",
|
||||||
|
"-std=c++14",
|
||||||
|
"-Wall",
|
||||||
|
],
|
||||||
|
fbandroid_deps = [
|
||||||
|
react_native_target("jni/react/jni:jni"),
|
||||||
|
],
|
||||||
|
fbandroid_exported_headers = subdir_glob(
|
||||||
|
[
|
||||||
|
("", "*.h"),
|
||||||
|
("platform/android", "*.h"),
|
||||||
|
],
|
||||||
|
prefix = "react/components/modal",
|
||||||
|
),
|
||||||
|
fbandroid_headers = glob(
|
||||||
|
["platform/android/*.h"],
|
||||||
|
),
|
||||||
|
fbandroid_srcs = glob(
|
||||||
|
["platform/android/*.cpp"],
|
||||||
|
),
|
||||||
|
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
|
||||||
|
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
|
||||||
|
force_static = True,
|
||||||
|
ios_exported_headers = subdir_glob(
|
||||||
|
[
|
||||||
|
("", "*.h"),
|
||||||
|
("platform/ios", "*.h"),
|
||||||
|
],
|
||||||
|
prefix = "react/components/modal",
|
||||||
|
),
|
||||||
|
macosx_tests_override = [],
|
||||||
|
platforms = (ANDROID, APPLE),
|
||||||
|
preprocessor_flags = [
|
||||||
|
"-DLOG_TAG=\"ReactNative\"",
|
||||||
|
"-DWITH_FBSYSTRACE=1",
|
||||||
|
],
|
||||||
|
tests = [":tests"],
|
||||||
|
visibility = ["PUBLIC"],
|
||||||
|
deps = [
|
||||||
|
"fbsource//xplat/fbsystrace:fbsystrace",
|
||||||
|
"fbsource//xplat/folly:headers_only",
|
||||||
|
"fbsource//xplat/folly:memory",
|
||||||
|
"fbsource//xplat/folly:molly",
|
||||||
|
"fbsource//xplat/third-party/glog:glog",
|
||||||
|
"fbsource//xplat/yoga:yoga",
|
||||||
|
react_native_xplat_target("fabric/debug:debug"),
|
||||||
|
react_native_xplat_target("fabric/core:core"),
|
||||||
|
react_native_xplat_target("fabric/components/image:image"),
|
||||||
|
react_native_xplat_target("fabric/components/view:view"),
|
||||||
|
react_native_xplat_target("fabric/graphics:graphics"),
|
||||||
|
react_native_xplat_target("fabric/imagemanager:imagemanager"),
|
||||||
|
react_native_xplat_target("fabric/uimanager:uimanager"),
|
||||||
|
"fbsource//xplat/js/react-native-github:generated_components-rncore",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
fb_xplat_cxx_test(
|
||||||
|
name = "tests",
|
||||||
|
srcs = glob(["tests/**/*.cpp"]),
|
||||||
|
headers = glob(["tests/**/*.h"]),
|
||||||
|
compiler_flags = [
|
||||||
|
"-fexceptions",
|
||||||
|
"-frtti",
|
||||||
|
"-std=c++14",
|
||||||
|
"-Wall",
|
||||||
|
],
|
||||||
|
contacts = ["oncall+react_native@xmail.facebook.com"],
|
||||||
|
platforms = (ANDROID, APPLE),
|
||||||
|
deps = [
|
||||||
|
"fbsource//xplat/folly:molly",
|
||||||
|
"fbsource//xplat/third-party/gmock:gtest",
|
||||||
|
":modal",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <react/components/modal/ModalHostViewShadowNode.h>
|
||||||
|
#include <react/core/ConcreteComponentDescriptor.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Descriptor for <BottomSheet> component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ModalHostViewComponentDescriptor final
|
||||||
|
: public ConcreteComponentDescriptor<ModalHostViewShadowNode> {
|
||||||
|
public:
|
||||||
|
ModalHostViewComponentDescriptor(EventDispatcher::Shared eventDispatcher)
|
||||||
|
: ConcreteComponentDescriptor(eventDispatcher) {}
|
||||||
|
|
||||||
|
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||||
|
assert(std::dynamic_pointer_cast<ModalHostViewShadowNode>(shadowNode));
|
||||||
|
auto modalShadowNode =
|
||||||
|
std::static_pointer_cast<ModalHostViewShadowNode>(shadowNode);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
std::dynamic_pointer_cast<YogaLayoutableShadowNode>(modalShadowNode));
|
||||||
|
auto layoutableShadowNode =
|
||||||
|
std::static_pointer_cast<YogaLayoutableShadowNode>(modalShadowNode);
|
||||||
|
|
||||||
|
auto state =
|
||||||
|
std::static_pointer_cast<const ModalHostViewShadowNode::ConcreteState>(
|
||||||
|
shadowNode->getState());
|
||||||
|
auto stateData = state->getData();
|
||||||
|
|
||||||
|
layoutableShadowNode->setSize(
|
||||||
|
Size{stateData.screenSize.width, stateData.screenSize.height});
|
||||||
|
layoutableShadowNode->setPositionType(YGPositionTypeAbsolute);
|
||||||
|
|
||||||
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ModalHostViewShadowNode.h"
|
||||||
|
|
||||||
|
#include <react/components/modal/ModalHostViewShadowNode.h>
|
||||||
|
#include <react/core/LayoutContext.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
extern const char ModalHostViewComponentName[] = "ModalHostView";
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <react/components/modal/ModalHostViewState.h>
|
||||||
|
#include <react/components/rncore/EventEmitters.h>
|
||||||
|
#include <react/components/rncore/Props.h>
|
||||||
|
#include <react/components/view/ConcreteViewShadowNode.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
extern const char ModalHostViewComponentName[];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `ShadowNode` for <Slider> component.
|
||||||
|
*/
|
||||||
|
class ModalHostViewShadowNode final : public ConcreteViewShadowNode<
|
||||||
|
ModalHostViewComponentName,
|
||||||
|
ModalHostViewProps,
|
||||||
|
ModalHostViewEventEmitter,
|
||||||
|
ModalHostViewState> {
|
||||||
|
public:
|
||||||
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
|
@ -0,0 +1,26 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ModalHostViewState.h"
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include <folly/dynamic.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
const folly::dynamic ModalHostViewState::getDynamic() const {
|
||||||
|
return folly::dynamic::object("screenWidth", screenSize.width)(
|
||||||
|
"screenHeight", screenSize.height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <react/core/StateData.h>
|
||||||
|
#include <react/graphics/Float.h>
|
||||||
|
#include <react/graphics/Geometry.h>
|
||||||
|
#include <react/graphics/conversions.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State for <BottomSheetView> component.
|
||||||
|
*/
|
||||||
|
class ModalHostViewState : public StateData {
|
||||||
|
public:
|
||||||
|
using Shared = std::shared_ptr<const ModalHostViewState>;
|
||||||
|
|
||||||
|
ModalHostViewState(){};
|
||||||
|
ModalHostViewState(Size screenSize_) : screenSize(screenSize_){};
|
||||||
|
virtual ~ModalHostViewState() = default;
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
ModalHostViewState(folly::dynamic data)
|
||||||
|
: screenSize(Size{(Float)data["screenWidth"].getDouble(),
|
||||||
|
(Float)data["screenHeight"].getDouble()}){};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const Size screenSize{};
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
virtual const folly::dynamic getDynamic() const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma mark - Getters
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
Загрузка…
Ссылка в новой задаче