From 1b10c9afefd4e5097e6b138946b9c8c0c23f5b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Fri, 22 Jul 2022 15:27:27 +0200 Subject: [PATCH 01/14] Configure build.gradle --- package/android/build.gradle | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/package/android/build.gradle b/package/android/build.gradle index 5d78bc84..cd8a6636 100644 --- a/package/android/build.gradle +++ b/package/android/build.gradle @@ -11,6 +11,15 @@ buildscript { } } +def isNewArchitectureEnabled() { + return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" +} + +apply plugin: 'com.android.library' +if (isNewArchitectureEnabled()) { + apply plugin: 'com.facebook.react' +} + def getExtOrDefault(name) { return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactNativeSlider_' + name] } @@ -19,7 +28,6 @@ def getExtOrIntegerDefault(name) { return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['ReactNativeSlider_' + name]).toInteger() } -apply plugin: 'com.android.library' android { compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') @@ -28,6 +36,17 @@ android { defaultConfig { minSdkVersion getExtOrIntegerDefault('minSdkVersion') targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') + buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() + } + + sourceSets { + main { + if (isNewArchitectureEnabled()) { + java.srcDirs += ['src/newarch'] + } else { + java.srcDirs += ['src/oldarch'] + } + } } } @@ -40,3 +59,11 @@ dependencies { //noinspection GradleDynamicVersion api 'com.facebook.react:react-native:+' } + +if (isNewArchitectureEnabled()) { + react { + jsRootDir = file("../src/") + libraryName = "reactslider" + codegenJavaPackageName = "com.reactnativecommunity.slider" + } +} \ No newline at end of file From 533cf64e0c14852fd480158b91acea7f3000497e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 25 Jul 2022 12:42:15 +0200 Subject: [PATCH 02/14] Update libraryName on android --- package/android/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/android/build.gradle b/package/android/build.gradle index cd8a6636..60d6e960 100644 --- a/package/android/build.gradle +++ b/package/android/build.gradle @@ -62,8 +62,8 @@ dependencies { if (isNewArchitectureEnabled()) { react { - jsRootDir = file("../src/") - libraryName = "reactslider" + jsRootDir = file("../src") + libraryName = "ReactSlider" codegenJavaPackageName = "com.reactnativecommunity.slider" } } \ No newline at end of file From 2cdd58ab2ec84d24e50f5e6628224025e4a434a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 25 Jul 2022 12:42:36 +0200 Subject: [PATCH 03/14] Create ReactSlider shared implementation --- .../slider/ReactSliderManagerImpl.java | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java new file mode 100644 index 00000000..f59e9bb2 --- /dev/null +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java @@ -0,0 +1,133 @@ +package com.reactnativecommunity.slider; + +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.os.Build; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.uimanager.ThemedReactContext; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + +public class ReactSliderManagerImpl { + + public static final String REACT_CLASS = "RNCSlider"; + + public static ReactSlider createViewInstance(ThemedReactContext context) { + ReactSlider slider = new ReactSlider(context, null); + + if (Build.VERSION.SDK_INT >= 21) { + /** + * The "splitTrack" parameter should have "false" value, + * otherwise the SeekBar progress line doesn't appear when it is rotated. + */ + slider.setSplitTrack(false); + } + + return slider; + } + + public static void setValue(ReactSlider view, double value) { + if (view.isSliding() == false) { + view.setValue(value); + if (view.isAccessibilityFocused() && Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { + view.setupAccessibility((int)value); + } + } + } + + public static void setMinimumValue(ReactSlider view, float value) { + view.setMinValue(value); + } + + public static void setMaximumValue(ReactSlider view, float value) { + view.setMaxValue(value); + } + + public static void setStep(ReactSlider view, float value) { + view.setStep(value); + } + + public static void setEnabled(ReactSlider view, boolean enabled) { + view.setEnabled(enabled); + } + + public static void setThumbTintColor(ReactSlider view, Integer color) { + if (view.getThumb() != null) { + if (color == null) { + view.getThumb().clearColorFilter(); + } else { + view.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + } + } + + public static void setMinimumTrackTintColor(ReactSlider view, Integer color) { + LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); + Drawable progress = drawable.findDrawableByLayerId(android.R.id.progress); + if (color == null) { + progress.clearColorFilter(); + } else { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + progress.setColorFilter(new PorterDuffColorFilter((int)color, PorterDuff.Mode.SRC_IN)); + } + else { + progress.setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + } + } + + public static void setThumbImage(ReactSlider view, @Nullable ReadableMap source) { + String uri = null; + if (source != null) { + uri = source.getString("uri"); + } + view.setThumbImage(uri); + } + + public static void setMaximumTrackTintColor(ReactSlider view, Integer color) { + LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); + Drawable background = drawable.findDrawableByLayerId(android.R.id.background); + if (color == null) { + background.clearColorFilter(); + } else { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + background.setColorFilter(new PorterDuffColorFilter((int)color, PorterDuff.Mode.SRC_IN)); + } + else { + background.setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + } + } + + public static void setInverted(ReactSlider view, boolean inverted) { + if (inverted) view.setScaleX(-1f); + else view.setScaleX(1f); + } + + public static void setAccessibilityUnits(ReactSlider view, String accessibilityUnits) { + view.setAccessibilityUnits(accessibilityUnits); + } + + public static void setAccessibilityIncrements(ReactSlider view, ReadableArray accessibilityIncrements) { + List objectList = accessibilityIncrements.toArrayList(); + List stringList = new ArrayList<>(); + for(Object item: objectList) { + stringList.add((String)item); + } + view.setAccessibilityIncrements(stringList); + } + + public static Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of(ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingComplete"), + ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); + } +} From 5355cccbbe3299126f08e959822d4eade23186c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 25 Jul 2022 12:42:57 +0200 Subject: [PATCH 04/14] Split implementations into oldarch and newarch --- .../slider/ReactSliderManager.java | 251 ++++++++++++++++++ .../slider/ReactSliderManager.java | 2 +- 2 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java rename package/android/src/{main => oldarch}/java/com/reactnativecommunity/slider/ReactSliderManager.java (99%) diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java new file mode 100644 index 00000000..8e67905e --- /dev/null +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -0,0 +1,251 @@ +/** + * 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. + */ + +package com.reactnativecommunity.slider; + +import android.view.View; +import android.widget.SeekBar; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.uimanager.LayoutShadowNode; +import com.facebook.react.uimanager.SimpleViewManager; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.ViewManagerDelegate; +import com.facebook.react.uimanager.ViewProps; +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.yoga.YogaMeasureFunction; +import com.facebook.yoga.YogaMeasureMode; +import com.facebook.yoga.YogaMeasureOutput; +import com.facebook.yoga.YogaNode; +import java.util.Map; +import javax.annotation.Nullable; +import com.facebook.react.viewmanagers.RNCSliderManagerInterface; +import com.facebook.react.viewmanagers.RNCSliderManagerDelegate; +import com.facebook.react.module.annotations.ReactModule; + +/** + * Manages instances of {@code ReactSlider}. + */ +@ReactModule(name = ReactSliderManagerImpl.REACT_CLASS) +public class ReactSliderManager extends SimpleViewManager implements RNCSliderManagerInterface { + + private final ViewManagerDelegate mDelegate; + + public ReactSliderManager() { + mDelegate = new RNCSliderManagerDelegate<>(this); + } + + @Nullable + @Override + protected ViewManagerDelegate getDelegate() { + return mDelegate; + } + + static class ReactSliderShadowNode extends LayoutShadowNode implements + YogaMeasureFunction { + + private int mWidth; + private int mHeight; + private boolean mMeasured; + + private ReactSliderShadowNode() { + initMeasureFunction(); + } + + private void initMeasureFunction() { + setMeasureFunction(this); + } + + @Override + public long measure( + YogaNode node, + float width, + YogaMeasureMode widthMode, + float height, + YogaMeasureMode heightMode) { + if (!mMeasured) { + SeekBar reactSlider = new ReactSlider(getThemedContext(), null); + final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + reactSlider.measure(spec, spec); + mWidth = reactSlider.getMeasuredWidth(); + mHeight = reactSlider.getMeasuredHeight(); + mMeasured = true; + } + + return YogaMeasureOutput.make(mWidth, mHeight); + } + } + + private static final SeekBar.OnSeekBarChangeListener ON_CHANGE_LISTENER = + new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSliderEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekbar) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + ((ReactSlider)seekbar).isSliding(true); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSlidingStartEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); + } + + @Override + public void onStopTrackingTouch(SeekBar seekbar) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + ((ReactSlider)seekbar).isSliding(false); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSlidingCompleteEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSliderEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), + !((ReactSlider)seekbar).isSliding())); + } + }; + + @Override + public String getName() { + return ReactSliderManagerImpl.REACT_CLASS; + } + + @Override + public LayoutShadowNode createShadowNodeInstance() { + return new ReactSliderShadowNode(); + } + + @Override + public Class getShadowNodeClass() { + return ReactSliderShadowNode.class; + } + + @Override + protected ReactSlider createViewInstance(ThemedReactContext context) { + return ReactSliderManagerImpl.createViewInstance(context); + } + + @Override + @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) + public void setEnabled(ReactSlider view, boolean enabled) { + ReactSliderManagerImpl.setEnabled(view, enabled); + } + + @Override + @ReactProp(name = "value", defaultFloat = 0f) + public void setValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setValue(view, value); + } + + @Override + @ReactProp(name = "minimumValue", defaultFloat = 0f) + public void setMinimumValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setMinimumValue(view, value); + } + + @Override + @ReactProp(name = "maximumValue", defaultFloat = 0f) + public void setMaximumValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setMaximumValue(view, value); + } + + @Override + @ReactProp(name = "step", defaultFloat = 0f) + public void setStep(ReactSlider view, float value) { + ReactSliderManagerImpl.setStep(view, value); + } + + @Override + @ReactProp(name = "thumbTintColor", customType = "Color") + public void setThumbTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setThumbTintColor(view, color); + } + + + @Override + @ReactProp(name = "minimumTrackTintColor", customType = "Color") + public void setMinimumTrackTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setMinimumTrackTintColor(view, color); + } + + @Override + @ReactProp(name = "maximumTrackTintColor", customType = "Color") + public void setMaximumTrackTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setMaximumTrackTintColor(view, color); + } + + @Override + @ReactProp(name = "inverted", defaultBoolean = false) + public void setInverted(ReactSlider view, boolean inverted) { + ReactSliderManagerImpl.setInverted(view, inverted); + } + + @Override + @ReactProp(name = "accessibilityUnits") + public void setAccessibilityUnits(ReactSlider view, String accessibilityUnits) { + ReactSliderManagerImpl.setAccessibilityUnits(view, accessibilityUnits); + } + + @Override + @ReactProp(name = "accessibilityIncrements") + public void setAccessibilityIncrements(ReactSlider view, ReadableArray accessibilityIncrements) { + ReactSliderManagerImpl.setAccessibilityIncrements(view, accessibilityIncrements); + } + + @Override + @ReactProp(name = "thumbImage") + public void setThumbImage(ReactSlider reactSlider, @androidx.annotation.Nullable ReadableMap source) { + ReactSliderManagerImpl.setThumbImage(reactSlider, source); + } + + @Override + @ReactProp(name = "disabled") + public void setDisabled(ReactSlider reactSlider, boolean b) { + reactSlider.setEnabled(!b); + } + + @Override + protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) { + view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER); + } + + @Override + public Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of(ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingComplete"), + ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); + } + + // these props are not available on Android, however we must override their setters + @Override + public void setTestID(ReactSlider reactSlider, @androidx.annotation.Nullable String s) {} + + @Override + public void setMinimumTrackImage(ReactSlider reactSlider, @androidx.annotation.Nullable ReadableMap readableMap) {} + + @Override + public void setMaximumTrackImage(ReactSlider reactSlider, @androidx.annotation.Nullable ReadableMap readableMap) {} + + @Override + public void setTrackImage(ReactSlider view, @androidx.annotation.Nullable ReadableMap value) {} + + @Override + public void setTapToSeek(ReactSlider view, boolean value) {} + + @Override + public void setVertical(ReactSlider view, boolean value) {} +} diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java similarity index 99% rename from package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java rename to package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 65f7849f..796c0dda 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -114,7 +114,7 @@ public void onStopTrackingTouch(SeekBar seekbar) { @Override public String getName() { - return REACT_CLASS; + return ReactSliderManagerImpl.REACT_CLASS; } @Override From cbe260c9528bdb6ad26d9279bcdc9f055538e678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 25 Jul 2022 14:48:35 +0200 Subject: [PATCH 05/14] Dispatch events --- .../slider/ReactSliderManager.java | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 8e67905e..1109f866 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -16,10 +16,12 @@ import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.ViewManagerDelegate; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.yoga.YogaMeasureFunction; import com.facebook.yoga.YogaMeasureMode; import com.facebook.yoga.YogaMeasureOutput; @@ -88,18 +90,20 @@ public long measure( @Override public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { ReactContext reactContext = (ReactContext) seekbar.getContext(); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSliderEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); + EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag( + reactContext, seekbar.getId() + ); + eventDispatcher.dispatchEvent(new ReactSliderEvent(seekbar.getId(), ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); } @Override public void onStartTrackingTouch(SeekBar seekbar) { ReactContext reactContext = (ReactContext) seekbar.getContext(); + EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag( + reactContext, seekbar.getId() + ); ((ReactSlider)seekbar).isSliding(true); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSlidingStartEvent( + eventDispatcher.dispatchEvent(new ReactSlidingStartEvent( seekbar.getId(), ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); } @@ -108,15 +112,20 @@ public void onStartTrackingTouch(SeekBar seekbar) { public void onStopTrackingTouch(SeekBar seekbar) { ReactContext reactContext = (ReactContext) seekbar.getContext(); ((ReactSlider)seekbar).isSliding(false); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSlidingCompleteEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSliderEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), - !((ReactSlider)seekbar).isSliding())); + EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag( + reactContext, seekbar.getId() + ); + + eventDispatcher.dispatchEvent( + new ReactSlidingCompleteEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress())) + ); + eventDispatcher.dispatchEvent( + new ReactSliderEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), + !((ReactSlider)seekbar).isSliding())); } }; @@ -176,7 +185,6 @@ public void setThumbTintColor(ReactSlider view, Integer color) { ReactSliderManagerImpl.setThumbTintColor(view, color); } - @Override @ReactProp(name = "minimumTrackTintColor", customType = "Color") public void setMinimumTrackTintColor(ReactSlider view, Integer color) { From 5e7fc19cba32b05ff98fd088911bc2b0cbdfb12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 25 Jul 2022 16:34:32 +0200 Subject: [PATCH 06/14] Cleanup eventDispatcher --- .../slider/ReactSliderManager.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 1109f866..679f67cf 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -9,6 +9,8 @@ import android.view.View; import android.widget.SeekBar; +import androidx.annotation.NonNull; + import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; @@ -17,7 +19,6 @@ import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerHelper; -import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.ViewManagerDelegate; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; @@ -90,21 +91,19 @@ public long measure( @Override public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { ReactContext reactContext = (ReactContext) seekbar.getContext(); - EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag( - reactContext, seekbar.getId() - ); - eventDispatcher.dispatchEvent(new ReactSliderEvent(seekbar.getId(), ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); + int reactTag = seekbar.getId(); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) + .dispatchEvent(new ReactSliderEvent(reactTag, ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); } @Override public void onStartTrackingTouch(SeekBar seekbar) { ReactContext reactContext = (ReactContext) seekbar.getContext(); - EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag( - reactContext, seekbar.getId() - ); + int reactTag = seekbar.getId(); ((ReactSlider)seekbar).isSliding(true); - eventDispatcher.dispatchEvent(new ReactSlidingStartEvent( - seekbar.getId(), + UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) + .dispatchEvent(new ReactSlidingStartEvent( + reactTag, ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); } @@ -112,18 +111,18 @@ public void onStartTrackingTouch(SeekBar seekbar) { public void onStopTrackingTouch(SeekBar seekbar) { ReactContext reactContext = (ReactContext) seekbar.getContext(); ((ReactSlider)seekbar).isSliding(false); - EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag( - reactContext, seekbar.getId() - ); + int reactTag = seekbar.getId(); + + EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag); eventDispatcher.dispatchEvent( new ReactSlidingCompleteEvent( - seekbar.getId(), + reactTag, ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress())) ); eventDispatcher.dispatchEvent( new ReactSliderEvent( - seekbar.getId(), + reactTag, ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), !((ReactSlider)seekbar).isSliding())); } From 8c1b1f9790643cb1fbd5d7c8cc710fd25eaefc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 25 Jul 2022 16:43:47 +0200 Subject: [PATCH 07/14] Make oldarch implementation use shared code --- .../slider/ReactSliderManager.java | 186 ++++++------------ 1 file changed, 62 insertions(+), 124 deletions(-) diff --git a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 796c0dda..038d26c9 100644 --- a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -7,11 +7,6 @@ package com.reactnativecommunity.slider; -import android.graphics.PorterDuffColorFilter; -import android.os.Build; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; import android.view.View; import android.widget.SeekBar; import com.facebook.react.bridge.ReactContext; @@ -28,8 +23,6 @@ import com.facebook.yoga.YogaMeasureMode; import com.facebook.yoga.YogaMeasureOutput; import com.facebook.yoga.YogaNode; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import javax.annotation.Nullable; @@ -38,10 +31,8 @@ */ public class ReactSliderManager extends SimpleViewManager { - public static final String REACT_CLASS = "RNCSlider"; - static class ReactSliderShadowNode extends LayoutShadowNode implements - YogaMeasureFunction { + YogaMeasureFunction { private int mWidth; private int mHeight; @@ -57,11 +48,11 @@ private void initMeasureFunction() { @Override public long measure( - YogaNode node, - float width, - YogaMeasureMode widthMode, - float height, - YogaMeasureMode heightMode) { + YogaNode node, + float width, + YogaMeasureMode widthMode, + float height, + YogaMeasureMode heightMode) { if (!mMeasured) { SeekBar reactSlider = new ReactSlider(getThemedContext(), null); final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); @@ -76,41 +67,41 @@ public long measure( } private static final SeekBar.OnSeekBarChangeListener ON_CHANGE_LISTENER = - new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { - ReactContext reactContext = (ReactContext) seekbar.getContext(); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSliderEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); - } - - @Override - public void onStartTrackingTouch(SeekBar seekbar) { - ReactContext reactContext = (ReactContext) seekbar.getContext(); - ((ReactSlider)seekbar).isSliding(true); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSlidingStartEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); - } - - @Override - public void onStopTrackingTouch(SeekBar seekbar) { - ReactContext reactContext = (ReactContext) seekbar.getContext(); - ((ReactSlider)seekbar).isSliding(false); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSlidingCompleteEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( - new ReactSliderEvent( - seekbar.getId(), - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), - !((ReactSlider)seekbar).isSliding())); - } - }; + new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSliderEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekbar) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + ((ReactSlider)seekbar).isSliding(true); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSlidingStartEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); + } + + @Override + public void onStopTrackingTouch(SeekBar seekbar) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + ((ReactSlider)seekbar).isSliding(false); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSlidingCompleteEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent( + new ReactSliderEvent( + seekbar.getId(), + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), + !((ReactSlider)seekbar).isSliding())); + } + }; @Override public String getName() { @@ -129,17 +120,7 @@ public Class getShadowNodeClass() { @Override protected ReactSlider createViewInstance(ThemedReactContext context) { - ReactSlider slider = new ReactSlider(context, null); - - if (Build.VERSION.SDK_INT >= 21) { - /** - * The "splitTrack" parameter should have "false" value, - * otherwise the SeekBar progress line doesn't appear when it is rotated. - */ - slider.setSplitTrack(false); - } - - return slider; + return ReactSliderManagerImpl.createViewInstance(context); } @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) @@ -147,102 +128,59 @@ public void setEnabled(ReactSlider view, boolean enabled) { view.setEnabled(enabled); } - @ReactProp(name = "value", defaultDouble = 0d) - public void setValue(ReactSlider view, double value) { - if (view.isSliding() == false) { - view.setValue(value); - if (view.isAccessibilityFocused() && Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { - view.setupAccessibility((int)value); - } - } + @ReactProp(name = "value", defaultFloat = 0f) + public void setValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setValue(view, value); } - @ReactProp(name = "minimumValue", defaultDouble = 0d) - public void setMinimumValue(ReactSlider view, double value) { - view.setMinValue(value); + @ReactProp(name = "minimumValue", defaultFloat = 0f) + public void setMinimumValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setMinimumValue(view, value); } - @ReactProp(name = "maximumValue", defaultDouble = 1d) - public void setMaximumValue(ReactSlider view, double value) { - view.setMaxValue(value); + @ReactProp(name = "maximumValue", defaultFloat = 1f) + public void setMaximumValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setMaximumValue(view, value); } - @ReactProp(name = "step", defaultDouble = 0d) - public void setStep(ReactSlider view, double value) { - view.setStep(value); + @ReactProp(name = "step", defaultFloat = 0f) + public void setStep(ReactSlider view, float value) { + ReactSliderManagerImpl.setStep(view, value); } @ReactProp(name = "thumbTintColor", customType = "Color") public void setThumbTintColor(ReactSlider view, Integer color) { - if (view.getThumb() != null) { - if (color == null) { - view.getThumb().clearColorFilter(); - } else { - view.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN); - } - } + ReactSliderManagerImpl.setThumbTintColor(view, color); } @ReactProp(name = "minimumTrackTintColor", customType = "Color") public void setMinimumTrackTintColor(ReactSlider view, Integer color) { - LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); - Drawable progress = drawable.findDrawableByLayerId(android.R.id.progress); - if (color == null) { - progress.clearColorFilter(); - } else { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - progress.setColorFilter(new PorterDuffColorFilter((int)color, PorterDuff.Mode.SRC_IN)); - } - else { - progress.setColorFilter(color, PorterDuff.Mode.SRC_IN); - } - } + ReactSliderManagerImpl.setMinimumTrackTintColor(view, color); } @ReactProp(name = "thumbImage") public void setThumbImage(ReactSlider view, @Nullable ReadableMap source) { - String uri = null; - if (source != null) { - uri = source.getString("uri"); - } - view.setThumbImage(uri); + ReactSliderManagerImpl.setThumbImage(view, source); } @ReactProp(name = "maximumTrackTintColor", customType = "Color") public void setMaximumTrackTintColor(ReactSlider view, Integer color) { - LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); - Drawable background = drawable.findDrawableByLayerId(android.R.id.background); - if (color == null) { - background.clearColorFilter(); - } else { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - background.setColorFilter(new PorterDuffColorFilter((int)color, PorterDuff.Mode.SRC_IN)); - } - else { - background.setColorFilter(color, PorterDuff.Mode.SRC_IN); - } - } + ReactSliderManagerImpl.setMaximumTrackTintColor(view, color); } @ReactProp(name = "inverted", defaultBoolean = false) public void setInverted(ReactSlider view, boolean inverted) { - if (inverted) view.setScaleX(-1f); - else view.setScaleX(1f); + ReactSliderManagerImpl.setInverted(view, inverted); } @ReactProp(name = "accessibilityUnits") public void setAccessibilityUnits(ReactSlider view, String accessibilityUnits) { - view.setAccessibilityUnits(accessibilityUnits); + ReactSliderManagerImpl.setAccessibilityUnits(view, accessibilityUnits); } @ReactProp(name = "accessibilityIncrements") public void setAccessibilityIncrements(ReactSlider view, ReadableArray accessibilityIncrements) { - List objectList = accessibilityIncrements.toArrayList(); - List stringList = new ArrayList<>(); - for(Object item: objectList) { - stringList.add((String)item); - } - view.setAccessibilityIncrements(stringList); + ReactSliderManagerImpl.setAccessibilityIncrements(view, accessibilityIncrements); } @Override @@ -253,6 +191,6 @@ protected void addEventEmitters(final ThemedReactContext reactContext, final Rea @Override public Map getExportedCustomDirectEventTypeConstants() { return MapBuilder.of(ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingComplete"), - ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); + ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); } } From f90d3afd362e6f12de4f97f32f82b8f9371b5207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Wed, 27 Jul 2022 11:17:38 +0200 Subject: [PATCH 08/14] Add defaults to js spec --- package/src/RNCSliderNativeComponent.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package/src/RNCSliderNativeComponent.js b/package/src/RNCSliderNativeComponent.js index 09ad0cfd..2075818b 100644 --- a/package/src/RNCSliderNativeComponent.js +++ b/package/src/RNCSliderNativeComponent.js @@ -18,6 +18,7 @@ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNati import type { Float, BubblingEventHandler, + WithDefault, } from 'react-native/Libraries/Types/CodegenTypes'; type Event = $ReadOnly<{| @@ -29,11 +30,11 @@ type NativeProps = $ReadOnly<{| ...ViewProps, accessibilityUnits?: string, accessibilityIncrements?: $ReadOnlyArray, - disabled?: ?boolean, - enabled?: ?boolean, - inverted?: ?boolean, + disabled?: WithDefault, + enabled?: WithDefault, + inverted?: WithDefault, vertical?: ?boolean, - tapToSeek?: ?boolean, + tapToSeek?: WithDefault, maximumTrackImage?: ?ImageSource, maximumTrackTintColor?: ?ColorValue, maximumValue?: ?Float, From 7da2e286f2cc8d9d3ec161069c5ce7d06be10d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Wed, 27 Jul 2022 11:22:08 +0200 Subject: [PATCH 09/14] Clean up newarch ReactSliderManager --- .../slider/ReactSliderManager.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 679f67cf..2322df19 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -10,6 +10,7 @@ import android.view.View; import android.widget.SeekBar; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; @@ -28,7 +29,6 @@ import com.facebook.yoga.YogaMeasureOutput; import com.facebook.yoga.YogaNode; import java.util.Map; -import javax.annotation.Nullable; import com.facebook.react.viewmanagers.RNCSliderManagerInterface; import com.facebook.react.viewmanagers.RNCSliderManagerDelegate; import com.facebook.react.module.annotations.ReactModule; @@ -216,15 +216,13 @@ public void setAccessibilityIncrements(ReactSlider view, ReadableArray accessibi @Override @ReactProp(name = "thumbImage") - public void setThumbImage(ReactSlider reactSlider, @androidx.annotation.Nullable ReadableMap source) { - ReactSliderManagerImpl.setThumbImage(reactSlider, source); + public void setThumbImage(ReactSlider view, @androidx.annotation.Nullable ReadableMap source) { + ReactSliderManagerImpl.setThumbImage(view, source); } @Override @ReactProp(name = "disabled") - public void setDisabled(ReactSlider reactSlider, boolean b) { - reactSlider.setEnabled(!b); - } + public void setDisabled(ReactSlider view, boolean b) {} @Override protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) { @@ -239,16 +237,16 @@ public Map getExportedCustomDirectEventTypeConstants() { // these props are not available on Android, however we must override their setters @Override - public void setTestID(ReactSlider reactSlider, @androidx.annotation.Nullable String s) {} + public void setTestID(ReactSlider view, @Nullable String s) {} @Override - public void setMinimumTrackImage(ReactSlider reactSlider, @androidx.annotation.Nullable ReadableMap readableMap) {} + public void setMinimumTrackImage(ReactSlider view, @Nullable ReadableMap readableMap) {} @Override - public void setMaximumTrackImage(ReactSlider reactSlider, @androidx.annotation.Nullable ReadableMap readableMap) {} + public void setMaximumTrackImage(ReactSlider view, @Nullable ReadableMap readableMap) {} @Override - public void setTrackImage(ReactSlider view, @androidx.annotation.Nullable ReadableMap value) {} + public void setTrackImage(ReactSlider view, @Nullable ReadableMap value) {} @Override public void setTapToSeek(ReactSlider view, boolean value) {} From 88958e4237d33ec421fbd1b5f1cb87e6e4226cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Wed, 27 Jul 2022 11:52:04 +0200 Subject: [PATCH 10/14] Reorder props to fix disabled state --- package/src/Slider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/src/Slider.js b/package/src/Slider.js index fbd70f80..9d7a7211 100644 --- a/package/src/Slider.js +++ b/package/src/Slider.js @@ -292,6 +292,7 @@ const SliderComponent = ( return ( true} onResponderTerminationRequest={() => false} - accessibilityState={_accessibilityState} onRNCSliderAccessibilityAction={onAccessibilityActionEvent} /> ); From e1d479e43938753fd13a8b552e8e3ae2a5c84bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 1 Aug 2022 14:07:31 +0200 Subject: [PATCH 11/14] Handle TestID setter --- .../reactnativecommunity/slider/ReactSliderManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 2322df19..550590ff 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -221,8 +221,9 @@ public void setThumbImage(ReactSlider view, @androidx.annotation.Nullable Readab } @Override - @ReactProp(name = "disabled") - public void setDisabled(ReactSlider view, boolean b) {} + public void setTestID(ReactSlider view, @Nullable String value) { + super.setTestId(view, value); + } @Override protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) { @@ -237,7 +238,8 @@ public Map getExportedCustomDirectEventTypeConstants() { // these props are not available on Android, however we must override their setters @Override - public void setTestID(ReactSlider view, @Nullable String s) {} + @ReactProp(name = "disabled") + public void setDisabled(ReactSlider view, boolean disabled) {} @Override public void setMinimumTrackImage(ReactSlider view, @Nullable ReadableMap readableMap) {} From 23ddf4101a768f7d8d24e34b2df605f23cb6b9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 1 Aug 2022 15:02:19 +0200 Subject: [PATCH 12/14] Move ReactSliderShadowNode to shared implementation --- .../slider/ReactSliderManagerImpl.java | 42 ++++++ .../slider/ReactSliderManager.java | 127 ++++++------------ .../slider/ReactSliderManager.java | 46 +------ 3 files changed, 88 insertions(+), 127 deletions(-) diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java index f59e9bb2..421cc948 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java @@ -5,11 +5,18 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; +import android.view.View; +import android.widget.SeekBar; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; +import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.yoga.YogaMeasureFunction; +import com.facebook.yoga.YogaMeasureMode; +import com.facebook.yoga.YogaMeasureOutput; +import com.facebook.yoga.YogaNode; import java.util.ArrayList; import java.util.List; @@ -21,6 +28,41 @@ public class ReactSliderManagerImpl { public static final String REACT_CLASS = "RNCSlider"; + public static class ReactSliderShadowNode extends LayoutShadowNode implements + YogaMeasureFunction { + + private int mWidth; + private int mHeight; + private boolean mMeasured; + + public ReactSliderShadowNode() { + initMeasureFunction(); + } + + private void initMeasureFunction() { + setMeasureFunction(this); + } + + @Override + public long measure( + YogaNode node, + float width, + YogaMeasureMode widthMode, + float height, + YogaMeasureMode heightMode) { + if (!mMeasured) { + SeekBar reactSlider = new ReactSlider(getThemedContext(), null); + final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + reactSlider.measure(spec, spec); + mWidth = reactSlider.getMeasuredWidth(); + mHeight = reactSlider.getMeasuredHeight(); + mMeasured = true; + } + + return YogaMeasureOutput.make(mWidth, mHeight); + } + } + public static ReactSlider createViewInstance(ThemedReactContext context) { ReactSlider slider = new ReactSlider(context, null); diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 550590ff..326bec6d 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -7,9 +7,7 @@ package com.reactnativecommunity.slider; -import android.view.View; import android.widget.SeekBar; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.react.bridge.ReactContext; @@ -24,10 +22,6 @@ import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.events.EventDispatcher; -import com.facebook.yoga.YogaMeasureFunction; -import com.facebook.yoga.YogaMeasureMode; -import com.facebook.yoga.YogaMeasureOutput; -import com.facebook.yoga.YogaNode; import java.util.Map; import com.facebook.react.viewmanagers.RNCSliderManagerInterface; import com.facebook.react.viewmanagers.RNCSliderManagerDelegate; @@ -51,82 +45,47 @@ protected ViewManagerDelegate getDelegate() { return mDelegate; } - static class ReactSliderShadowNode extends LayoutShadowNode implements - YogaMeasureFunction { - - private int mWidth; - private int mHeight; - private boolean mMeasured; - - private ReactSliderShadowNode() { - initMeasureFunction(); - } - - private void initMeasureFunction() { - setMeasureFunction(this); - } - - @Override - public long measure( - YogaNode node, - float width, - YogaMeasureMode widthMode, - float height, - YogaMeasureMode heightMode) { - if (!mMeasured) { - SeekBar reactSlider = new ReactSlider(getThemedContext(), null); - final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - reactSlider.measure(spec, spec); - mWidth = reactSlider.getMeasuredWidth(); - mHeight = reactSlider.getMeasuredHeight(); - mMeasured = true; - } - - return YogaMeasureOutput.make(mWidth, mHeight); - } - } - private static final SeekBar.OnSeekBarChangeListener ON_CHANGE_LISTENER = - new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { - ReactContext reactContext = (ReactContext) seekbar.getContext(); - int reactTag = seekbar.getId(); - UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) - .dispatchEvent(new ReactSliderEvent(reactTag, ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); - } - - @Override - public void onStartTrackingTouch(SeekBar seekbar) { - ReactContext reactContext = (ReactContext) seekbar.getContext(); - int reactTag = seekbar.getId(); - ((ReactSlider)seekbar).isSliding(true); - UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) - .dispatchEvent(new ReactSlidingStartEvent( - reactTag, - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); - } - - @Override - public void onStopTrackingTouch(SeekBar seekbar) { - ReactContext reactContext = (ReactContext) seekbar.getContext(); - ((ReactSlider)seekbar).isSliding(false); - int reactTag = seekbar.getId(); - - EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag); - - eventDispatcher.dispatchEvent( - new ReactSlidingCompleteEvent( - reactTag, - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress())) - ); - eventDispatcher.dispatchEvent( - new ReactSliderEvent( - reactTag, - ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), - !((ReactSlider)seekbar).isSliding())); - } - }; + new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + int reactTag = seekbar.getId(); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) + .dispatchEvent(new ReactSliderEvent(reactTag, ((ReactSlider)seekbar).toRealProgress(progress), fromUser)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekbar) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + int reactTag = seekbar.getId(); + ((ReactSlider)seekbar).isSliding(true); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag) + .dispatchEvent(new ReactSlidingStartEvent( + reactTag, + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()))); + } + + @Override + public void onStopTrackingTouch(SeekBar seekbar) { + ReactContext reactContext = (ReactContext) seekbar.getContext(); + ((ReactSlider)seekbar).isSliding(false); + int reactTag = seekbar.getId(); + + EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag); + + eventDispatcher.dispatchEvent( + new ReactSlidingCompleteEvent( + reactTag, + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress())) + ); + eventDispatcher.dispatchEvent( + new ReactSliderEvent( + reactTag, + ((ReactSlider)seekbar).toRealProgress(seekbar.getProgress()), + !((ReactSlider)seekbar).isSliding())); + } + }; @Override public String getName() { @@ -135,12 +94,12 @@ public String getName() { @Override public LayoutShadowNode createShadowNodeInstance() { - return new ReactSliderShadowNode(); + return new ReactSliderManagerImpl.ReactSliderShadowNode(); } @Override public Class getShadowNodeClass() { - return ReactSliderShadowNode.class; + return ReactSliderManagerImpl.ReactSliderShadowNode.class; } @Override @@ -233,7 +192,7 @@ protected void addEventEmitters(final ThemedReactContext reactContext, final Rea @Override public Map getExportedCustomDirectEventTypeConstants() { return MapBuilder.of(ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingComplete"), - ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); + ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); } // these props are not available on Android, however we must override their setters diff --git a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 038d26c9..a65b6ea0 100644 --- a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -7,7 +7,6 @@ package com.reactnativecommunity.slider; -import android.view.View; import android.widget.SeekBar; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; @@ -19,10 +18,6 @@ import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.yoga.YogaMeasureFunction; -import com.facebook.yoga.YogaMeasureMode; -import com.facebook.yoga.YogaMeasureOutput; -import com.facebook.yoga.YogaNode; import java.util.Map; import javax.annotation.Nullable; @@ -31,41 +26,6 @@ */ public class ReactSliderManager extends SimpleViewManager { - static class ReactSliderShadowNode extends LayoutShadowNode implements - YogaMeasureFunction { - - private int mWidth; - private int mHeight; - private boolean mMeasured; - - private ReactSliderShadowNode() { - initMeasureFunction(); - } - - private void initMeasureFunction() { - setMeasureFunction(this); - } - - @Override - public long measure( - YogaNode node, - float width, - YogaMeasureMode widthMode, - float height, - YogaMeasureMode heightMode) { - if (!mMeasured) { - SeekBar reactSlider = new ReactSlider(getThemedContext(), null); - final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - reactSlider.measure(spec, spec); - mWidth = reactSlider.getMeasuredWidth(); - mHeight = reactSlider.getMeasuredHeight(); - mMeasured = true; - } - - return YogaMeasureOutput.make(mWidth, mHeight); - } - } - private static final SeekBar.OnSeekBarChangeListener ON_CHANGE_LISTENER = new SeekBar.OnSeekBarChangeListener() { @Override @@ -110,12 +70,12 @@ public String getName() { @Override public LayoutShadowNode createShadowNodeInstance() { - return new ReactSliderShadowNode(); + return new ReactSliderManagerImpl.ReactSliderShadowNode(); } @Override public Class getShadowNodeClass() { - return ReactSliderShadowNode.class; + return ReactSliderManagerImpl.ReactSliderShadowNode.class; } @Override @@ -125,7 +85,7 @@ protected ReactSlider createViewInstance(ThemedReactContext context) { @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) public void setEnabled(ReactSlider view, boolean enabled) { - view.setEnabled(enabled); + ReactSliderManagerImpl.setEnabled(view, enabled); } @ReactProp(name = "value", defaultFloat = 0f) From 3701d5763024a016e942279b741c31f861ebc150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Mon, 1 Aug 2022 15:21:56 +0200 Subject: [PATCH 13/14] Share getExportedCustomDirectEventTypeConstants --- .../com/reactnativecommunity/slider/ReactSliderManager.java | 3 +-- .../com/reactnativecommunity/slider/ReactSliderManager.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 326bec6d..a7ccebe1 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -191,8 +191,7 @@ protected void addEventEmitters(final ThemedReactContext reactContext, final Rea @Override public Map getExportedCustomDirectEventTypeConstants() { - return MapBuilder.of(ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingComplete"), - ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); + return ReactSliderManagerImpl.getExportedCustomDirectEventTypeConstants(); } // these props are not available on Android, however we must override their setters diff --git a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index a65b6ea0..5db1b7da 100644 --- a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -150,7 +150,6 @@ protected void addEventEmitters(final ThemedReactContext reactContext, final Rea @Override public Map getExportedCustomDirectEventTypeConstants() { - return MapBuilder.of(ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingComplete"), - ReactSlidingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRNCSliderSlidingStart")); + return ReactSliderManagerImpl.getExportedCustomDirectEventTypeConstants(); } } From e3ac5346c91c43e51b88d1a599395e0aea7f13c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwas=CC=81niewski?= Date: Thu, 4 Aug 2022 09:09:37 +0200 Subject: [PATCH 14/14] Remove comments, add empty line --- package/android/build.gradle | 2 +- .../reactnativecommunity/slider/ReactSliderManager.java | 7 ------- .../reactnativecommunity/slider/ReactSliderManager.java | 7 ------- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/package/android/build.gradle b/package/android/build.gradle index 60d6e960..f940a4bd 100644 --- a/package/android/build.gradle +++ b/package/android/build.gradle @@ -66,4 +66,4 @@ if (isNewArchitectureEnabled()) { libraryName = "ReactSlider" codegenJavaPackageName = "com.reactnativecommunity.slider" } -} \ No newline at end of file +} diff --git a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index a7ccebe1..e87e7b46 100644 --- a/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -1,10 +1,3 @@ -/** - * 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. - */ - package com.reactnativecommunity.slider; import android.widget.SeekBar; diff --git a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java index 5db1b7da..b76b4417 100644 --- a/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -1,10 +1,3 @@ -/** - * 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. - */ - package com.reactnativecommunity.slider; import android.widget.SeekBar;