mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-03-06 22:37:14 +08:00
Enable Slider component
Summary:
Enable Slider component in Fabric on Android.
{F151706188}
Reviewed By: mdvacca
Differential Revision: D14220147
fbshipit-source-id: 10b29112e950c8de98cba995839780c4f4e8d3b6
This commit is contained in:
committed by
Facebook Github Bot
parent
57afad1c1f
commit
3c1114eea7
@@ -77,6 +77,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
sComponentNames.put("View", "RCTView");
|
||||
sComponentNames.put("Image", "RCTImageView");
|
||||
sComponentNames.put("ScrollView", "RCTScrollView");
|
||||
sComponentNames.put("Slider", "RCTSlider");
|
||||
sComponentNames.put("ReactPerformanceLoggerFlag", "ReactPerformanceLoggerFlag");
|
||||
sComponentNames.put("Paragraph", "RCTText");
|
||||
sComponentNames.put("Text", "RCText");
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.SeekBar;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
import com.facebook.react.uimanager.ReactShadowNodeImpl;
|
||||
@@ -192,4 +193,22 @@ public class ReactSliderManager extends SimpleViewManager<ReactSlider> {
|
||||
ReactSlidingCompleteEvent.EVENT_NAME,
|
||||
MapBuilder.of("registrationName", "onSlidingComplete"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long measure(
|
||||
ReactContext context,
|
||||
ReadableMap localData,
|
||||
ReadableMap props,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode) {
|
||||
SeekBar reactSlider = new ReactSlider(context, null, STYLE);
|
||||
final int spec = View.MeasureSpec.makeMeasureSpec(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
View.MeasureSpec.UNSPECIFIED);
|
||||
reactSlider.measure(spec, spec);
|
||||
|
||||
return YogaMeasureOutput.make(reactSlider.getMeasuredWidth(), reactSlider.getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ public class ReactTextViewManager
|
||||
return MapBuilder.of("topTextLayout", MapBuilder.of("registrationName", "onTextLayout"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long measure(
|
||||
ReactContext context,
|
||||
ReadableMap localData,
|
||||
|
||||
@@ -25,11 +25,19 @@ class ImageComponentDescriptor final
|
||||
SharedEventDispatcher eventDispatcher,
|
||||
const SharedContextContainer &contextContainer)
|
||||
: ConcreteComponentDescriptor(eventDispatcher),
|
||||
// TODO (39486757): implement image manager on Android, currently Android does
|
||||
// not have an ImageManager so this will crash
|
||||
#ifndef ANDROID
|
||||
imageManager_(
|
||||
contextContainer
|
||||
? contextContainer->getInstance<SharedImageManager>(
|
||||
"ImageManager")
|
||||
: nullptr) {}
|
||||
: nullptr) {
|
||||
}
|
||||
#else
|
||||
imageManager_(nullptr) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||
|
||||
@@ -6,6 +6,7 @@ load(
|
||||
"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",
|
||||
@@ -17,7 +18,10 @@ rn_xplat_cxx_library(
|
||||
name = "slider",
|
||||
srcs = glob(
|
||||
["**/*.cpp"],
|
||||
exclude = glob(["tests/**/*.cpp"]),
|
||||
exclude = glob([
|
||||
"tests/**/*.cpp",
|
||||
"platform/**/*.cpp",
|
||||
]),
|
||||
),
|
||||
headers = [],
|
||||
header_namespace = "",
|
||||
@@ -33,8 +37,38 @@ rn_xplat_cxx_library(
|
||||
"-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/slider",
|
||||
),
|
||||
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/slider",
|
||||
),
|
||||
ios_headers = glob(
|
||||
["platform/ios/*.h"],
|
||||
),
|
||||
ios_srcs = glob(
|
||||
["platform/ios/*.cpp"],
|
||||
),
|
||||
macosx_tests_override = [],
|
||||
platforms = (ANDROID, APPLE),
|
||||
preprocessor_flags = [
|
||||
@@ -56,6 +90,7 @@ rn_xplat_cxx_library(
|
||||
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"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/components/slider/SliderMeasurementsManager.h>
|
||||
#include <react/components/slider/SliderShadowNode.h>
|
||||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
|
||||
@@ -23,11 +24,20 @@ class SliderComponentDescriptor final
|
||||
SharedEventDispatcher eventDispatcher,
|
||||
const SharedContextContainer &contextContainer)
|
||||
: ConcreteComponentDescriptor(eventDispatcher),
|
||||
// TODO (39486757): implement image manager on Android, currently Android does
|
||||
// not have an ImageManager so this will crash
|
||||
#ifndef ANDROID
|
||||
imageManager_(
|
||||
contextContainer
|
||||
? contextContainer->getInstance<SharedImageManager>(
|
||||
"ImageManager")
|
||||
: nullptr) {}
|
||||
: nullptr),
|
||||
#else
|
||||
imageManager_(nullptr),
|
||||
#endif
|
||||
measurementsManager_(
|
||||
std::make_shared<SliderMeasurementsManager>(contextContainer)) {
|
||||
}
|
||||
|
||||
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||
@@ -39,10 +49,19 @@ class SliderComponentDescriptor final
|
||||
// `SliderShadowNode` uses `ImageManager` to initiate image loading and
|
||||
// communicate the loading state and results to mounting layer.
|
||||
sliderShadowNode->setImageManager(imageManager_);
|
||||
|
||||
// `SliderShadowNode` uses `SliderMeasurementsManager` to
|
||||
// provide measurements to Yoga.
|
||||
sliderShadowNode->setSliderMeasurementsManager(measurementsManager_);
|
||||
|
||||
// All `SliderShadowNode`s must have leaf Yoga nodes with properly
|
||||
// setup measure function.
|
||||
sliderShadowNode->enableMeasurement();
|
||||
}
|
||||
|
||||
private:
|
||||
const SharedImageManager imageManager_;
|
||||
const std::shared_ptr<SliderMeasurementsManager> measurementsManager_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -21,6 +21,12 @@ void SliderShadowNode::setImageManager(const SharedImageManager &imageManager) {
|
||||
imageManager_ = imageManager;
|
||||
}
|
||||
|
||||
void SliderShadowNode::setSliderMeasurementsManager(
|
||||
const std::shared_ptr<SliderMeasurementsManager> &measurementsManager) {
|
||||
ensureUnsealed();
|
||||
measurementsManager_ = measurementsManager;
|
||||
}
|
||||
|
||||
void SliderShadowNode::updateLocalData() {
|
||||
const auto &newTrackImageSource = getTrackImageSource();
|
||||
const auto &newMinimumTrackImageSource = getMinimumTrackImageSource();
|
||||
@@ -86,6 +92,14 @@ ImageSource SliderShadowNode::getThumbImageSource() const {
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
Size SliderShadowNode::measure(LayoutConstraints layoutConstraints) const {
|
||||
if (measurementsManager_->shouldMeasureSlider()) {
|
||||
return measurementsManager_->measure(layoutConstraints);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void SliderShadowNode::layout(LayoutContext layoutContext) {
|
||||
updateLocalData();
|
||||
ConcreteViewShadowNode::layout(layoutContext);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <react/components/slider/SliderEventEmitter.h>
|
||||
#include <react/components/slider/SliderMeasurementsManager.h>
|
||||
#include <react/components/slider/SliderProps.h>
|
||||
#include <react/components/view/ConcreteViewShadowNode.h>
|
||||
#include <react/imagemanager/ImageManager.h>
|
||||
@@ -31,8 +32,13 @@ class SliderShadowNode final : public ConcreteViewShadowNode<
|
||||
// Associates a shared `ImageManager` with the node.
|
||||
void setImageManager(const SharedImageManager &imageManager);
|
||||
|
||||
// Associates a shared `SliderMeasurementsManager` with the node.
|
||||
void setSliderMeasurementsManager(
|
||||
const std::shared_ptr<SliderMeasurementsManager> &measurementsManager);
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
Size measure(LayoutConstraints layoutConstraints) const override;
|
||||
void layout(LayoutContext layoutContext) override;
|
||||
|
||||
private:
|
||||
@@ -45,6 +51,7 @@ class SliderShadowNode final : public ConcreteViewShadowNode<
|
||||
ImageSource getThumbImageSource() const;
|
||||
|
||||
SharedImageManager imageManager_;
|
||||
std::shared_ptr<SliderMeasurementsManager> measurementsManager_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 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 "SliderMeasurementsManager.h"
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
#include <react/core/conversions.h>
|
||||
#include <react/jni/ReadableNativeMap.h>
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
const bool SliderMeasurementsManager::shouldMeasureSlider() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
Size SliderMeasurementsManager::measure(
|
||||
LayoutConstraints layoutConstraints) const {
|
||||
const jni::global_ref<jobject> &fabricUIManager =
|
||||
contextContainer_->getInstance<jni::global_ref<jobject>>(
|
||||
"FabricUIManager");
|
||||
|
||||
static auto measure =
|
||||
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
|
||||
->getMethod<jlong(
|
||||
jstring,
|
||||
ReadableMap::javaobject,
|
||||
ReadableMap::javaobject,
|
||||
jint,
|
||||
jint,
|
||||
jint,
|
||||
jint)>("measure");
|
||||
|
||||
auto minimumSize = layoutConstraints.minimumSize;
|
||||
auto maximumSize = layoutConstraints.maximumSize;
|
||||
int minWidth = (int)minimumSize.width;
|
||||
int minHeight = (int)minimumSize.height;
|
||||
int maxWidth = (int)maximumSize.width;
|
||||
int maxHeight = (int)maximumSize.height;
|
||||
|
||||
local_ref<JString> componentName = make_jstring("RCTSlider");
|
||||
|
||||
return yogaMeassureToSize(measure(
|
||||
fabricUIManager,
|
||||
componentName.get(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
minWidth,
|
||||
maxWidth,
|
||||
minHeight,
|
||||
maxHeight));
|
||||
}
|
||||
|
||||
} // 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/core/ConcreteComponentDescriptor.h>
|
||||
#include <react/core/LayoutConstraints.h>
|
||||
#include <react/uimanager/ContextContainer.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/**
|
||||
* Class that manages slider measurements across platforms.
|
||||
* On iOS it is a noop, since the height is passed in from JS on iOS only.
|
||||
*/
|
||||
class SliderMeasurementsManager {
|
||||
public:
|
||||
SliderMeasurementsManager(const SharedContextContainer &contextContainer)
|
||||
: contextContainer_(contextContainer) {}
|
||||
const bool shouldMeasureSlider() const;
|
||||
Size measure(LayoutConstraints layoutConstraints) const;
|
||||
|
||||
private:
|
||||
const SharedContextContainer contextContainer_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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 "SliderMeasurementsManager.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
const bool SliderMeasurementsManager::shouldMeasureSlider() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Size SliderMeasurementsManager::measure(
|
||||
LayoutConstraints layoutConstraints) const {
|
||||
assert(false); // should never reach this point
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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/ConcreteComponentDescriptor.h>
|
||||
#include <react/core/LayoutConstraints.h>
|
||||
#include <react/uimanager/ContextContainer.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/**
|
||||
* Class that manages slider measurements across platforms.
|
||||
* On iOS it is a noop, since the height is passed in from JS on iOS only.
|
||||
*/
|
||||
class SliderMeasurementsManager {
|
||||
public:
|
||||
SliderMeasurementsManager(const SharedContextContainer &contextContainer) {}
|
||||
const bool shouldMeasureSlider() const;
|
||||
Size measure(LayoutConstraints layoutConstraints) const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
Reference in New Issue
Block a user