diff --git a/package/android/build.gradle b/package/android/build.gradle index 5d78bc84..f940a4bd 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" + } +} diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java deleted file mode 100644 index 65f7849f..00000000 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ /dev/null @@ -1,258 +0,0 @@ -/** - * 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.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; -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.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.ArrayList; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; - -/** - * Manages instances of {@code ReactSlider}. - */ -public class ReactSliderManager extends SimpleViewManager { - - public static final String REACT_CLASS = "RNCSlider"; - - 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 REACT_CLASS; - } - - @Override - public LayoutShadowNode createShadowNodeInstance() { - return new ReactSliderShadowNode(); - } - - @Override - public Class getShadowNodeClass() { - return ReactSliderShadowNode.class; - } - - @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; - } - - @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) - 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 = "minimumValue", defaultDouble = 0d) - public void setMinimumValue(ReactSlider view, double value) { - view.setMinValue(value); - } - - @ReactProp(name = "maximumValue", defaultDouble = 1d) - public void setMaximumValue(ReactSlider view, double value) { - view.setMaxValue(value); - } - - @ReactProp(name = "step", defaultDouble = 0d) - public void setStep(ReactSlider view, double value) { - view.setStep(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); - } - } - } - - @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); - } - } - } - - @ReactProp(name = "thumbImage") - public void setThumbImage(ReactSlider view, @Nullable ReadableMap source) { - String uri = null; - if (source != null) { - uri = source.getString("uri"); - } - view.setThumbImage(uri); - } - - @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); - } - } - } - - @ReactProp(name = "inverted", defaultBoolean = false) - public void setInverted(ReactSlider view, boolean inverted) { - if (inverted) view.setScaleX(-1f); - else view.setScaleX(1f); - } - - @ReactProp(name = "accessibilityUnits") - public void setAccessibilityUnits(ReactSlider view, String accessibilityUnits) { - view.setAccessibilityUnits(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); - } - - @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")); - } -} 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..421cc948 --- /dev/null +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java @@ -0,0 +1,175 @@ +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 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; +import java.util.Map; + +import javax.annotation.Nullable; + +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); + + 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")); + } +} 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..e87e7b46 --- /dev/null +++ b/package/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -0,0 +1,209 @@ +package com.reactnativecommunity.slider; + +import android.widget.SeekBar; +import androidx.annotation.Nullable; + +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.UIManagerHelper; +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 java.util.Map; +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; + } + + 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())); + } + }; + + @Override + public String getName() { + return ReactSliderManagerImpl.REACT_CLASS; + } + + @Override + public LayoutShadowNode createShadowNodeInstance() { + return new ReactSliderManagerImpl.ReactSliderShadowNode(); + } + + @Override + public Class getShadowNodeClass() { + return ReactSliderManagerImpl.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 view, @androidx.annotation.Nullable ReadableMap source) { + ReactSliderManagerImpl.setThumbImage(view, source); + } + + @Override + public void setTestID(ReactSlider view, @Nullable String value) { + super.setTestId(view, value); + } + + @Override + protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) { + view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER); + } + + @Override + public Map getExportedCustomDirectEventTypeConstants() { + return ReactSliderManagerImpl.getExportedCustomDirectEventTypeConstants(); + } + + // these props are not available on Android, however we must override their setters + @Override + @ReactProp(name = "disabled") + public void setDisabled(ReactSlider view, boolean disabled) {} + + @Override + public void setMinimumTrackImage(ReactSlider view, @Nullable ReadableMap readableMap) {} + + @Override + public void setMaximumTrackImage(ReactSlider view, @Nullable ReadableMap readableMap) {} + + @Override + public void setTrackImage(ReactSlider view, @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/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java new file mode 100644 index 00000000..b76b4417 --- /dev/null +++ b/package/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -0,0 +1,148 @@ +package com.reactnativecommunity.slider; + +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.ViewProps; +import com.facebook.react.uimanager.annotations.ReactProp; +import java.util.Map; +import javax.annotation.Nullable; + +/** + * Manages instances of {@code ReactSlider}. + */ +public class ReactSliderManager extends SimpleViewManager { + + 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 ReactSliderManagerImpl.ReactSliderShadowNode(); + } + + @Override + public Class getShadowNodeClass() { + return ReactSliderManagerImpl.ReactSliderShadowNode.class; + } + + @Override + protected ReactSlider createViewInstance(ThemedReactContext context) { + return ReactSliderManagerImpl.createViewInstance(context); + } + + @ReactProp(name = ViewProps.ENABLED, defaultBoolean = true) + public void setEnabled(ReactSlider view, boolean enabled) { + ReactSliderManagerImpl.setEnabled(view, enabled); + } + + @ReactProp(name = "value", defaultFloat = 0f) + public void setValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setValue(view, value); + } + + @ReactProp(name = "minimumValue", defaultFloat = 0f) + public void setMinimumValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setMinimumValue(view, value); + } + + @ReactProp(name = "maximumValue", defaultFloat = 1f) + public void setMaximumValue(ReactSlider view, float value) { + ReactSliderManagerImpl.setMaximumValue(view, 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) { + ReactSliderManagerImpl.setThumbTintColor(view, color); + } + + @ReactProp(name = "minimumTrackTintColor", customType = "Color") + public void setMinimumTrackTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setMinimumTrackTintColor(view, color); + } + + @ReactProp(name = "thumbImage") + public void setThumbImage(ReactSlider view, @Nullable ReadableMap source) { + ReactSliderManagerImpl.setThumbImage(view, source); + } + + @ReactProp(name = "maximumTrackTintColor", customType = "Color") + public void setMaximumTrackTintColor(ReactSlider view, Integer color) { + ReactSliderManagerImpl.setMaximumTrackTintColor(view, color); + } + + @ReactProp(name = "inverted", defaultBoolean = false) + public void setInverted(ReactSlider view, boolean inverted) { + ReactSliderManagerImpl.setInverted(view, inverted); + } + + @ReactProp(name = "accessibilityUnits") + public void setAccessibilityUnits(ReactSlider view, String accessibilityUnits) { + ReactSliderManagerImpl.setAccessibilityUnits(view, accessibilityUnits); + } + + @ReactProp(name = "accessibilityIncrements") + public void setAccessibilityIncrements(ReactSlider view, ReadableArray accessibilityIncrements) { + ReactSliderManagerImpl.setAccessibilityIncrements(view, accessibilityIncrements); + } + + @Override + protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) { + view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER); + } + + @Override + public Map getExportedCustomDirectEventTypeConstants() { + return ReactSliderManagerImpl.getExportedCustomDirectEventTypeConstants(); + } +} 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, 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} /> );