java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String when I use a RN switch Android only - react-native

I keep getting this error in the Android version of my React Native app. The iOS version of the app has zero problems with the React Native switch that I've used. This app is currently running on RN 0.54
Just in case, here's the code that uses the switch:
<View style={styles.feedbackSwitchWrapper}>
<Switch
value={this.props.feedbackCancellation}
onValueChange={() => {
this.feedbackCancellationToggle()
}}
onTintColor="#xxxx"
/>
</View>
And here is the error I get when I hit the switch.
Here's the updated code that ended up fixing the issue:
this.feedbackCancellation = SomeBluetoothEventEmitter.addListener('feedbackMode', event => {
// console.log('show me feedback mode object: ', event);
if (!event) {
return;
}
let feedbackCancellation = event.feedbackMode;
if (this.cancellationFeedbackDeferred) {
this.cancellationFeedbackDeferred.resolve(event.feedbackMode);
let trueOrFalseValue = this.convertIntToBool(feedbackCancellation);
/*
NOTE: for both feedbackCancellation and noiseReduction, we are getting the value
of each FROM THE DEVICE. We will use setFeedbackCancellationFunc to set the value in PROPS,
then we will use toggleFeedbackCancellationFunc to TOGGLE the values during
normal use.
*/
this.props.setFeedbackCancellationFunc(trueOrFalseValue);
} else {
if (this.mounted === true) { this.setState({ feedbackCancellation }) }
}
})

Related

How to use LayoutAnimation on Android using react native

LayoutAnimation not working on android
I didn't find any issues like this, and these errors are not found in google)
"react-native": "0.67.4"
I try to use LayoutAnimation, my code looks like this:
constructor(props) {
super(props)
this.state = {
height: Dimensions.get('window').height,
sliderTopPosition: Dimensions.get('window').height/2-50
}
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
kbShow = (event) => {
LayoutAnimation.configureNext(LayoutAnimation.create(
event.duration,
LayoutAnimation.Types[event.easing] //'keyboard'
// LayoutAnimation.Types.easeInEaseOut
), () => {
// console.log(finish, 'finish')
}, () => {
console.log('KEYBOARD SHOW ANIMATION DID FAIL')
})
this.setState({
height: event.endCoordinates.screenY,
sliderTopPosition: this.state.sliderTopPosition-event.endCoordinates.height+150,
})
}
And it works fine on iOS, but if I try to run this code on android I get an error:
Unsupported interpolation type : keyboard
Ok, I replace this strings like this just for test:
//LayoutAnimation.Types[event.easing] //'keyboard'
LayoutAnimation.Types.easeInEaseOut
It still works on ios but not on android
And now error is like this:
Invalid layout animation : {NativeMap: {"type": easeInEaseOut}}
And no matter what type of easing I use it always throw this error
To make it work on Android, you need to supply a property:
LayoutAnimation.configureNext(LayoutAnimation.create(
event.duration,
LayoutAnimation.Types[event.easing],
'opacity'
)
The property can be either 'opacity', 'scaleX', 'scaleY' or 'scaleXY'.
It's a very misleading error message and the type checking should show that the property is required...

React-Native FusionCharts event won't fire on IOS

I've implemented a 2d dragable area chart from react-native-fusioncharts. I am trying to fire an event when the data is changed which works as expected on android but no event will fire on IOS.
I've tried dataplotDragEnd and dataPlotClick but neither fire.
state = {
...,
events: {
dataplotDragEnd: (e, a) => {
Alert.alert("called")
console.log(e.data.endValue)
},
}
}
}
render() {
return (
<FusionCharts
type={this.state.type}
width={this.state.width}
height={this.state.height}
dataFormat={this.state.dataFormat}
dataSource={this.state.dataSource}
events={this.state.events}
libraryPath={this.libraryPath}
/>
)
}
I am expecting an alert message and a console.log from the event firing but am currently getting nothing only on IOS

Code push not updating app on IOS device

My code-push is working on simulator but when i ran same app on device it shows me update dialog but when i press install nothing happens.
class MyApp extends React.Component {
constructor () {
super();
this.state = {
logs: []
}
}
codePushStatusDidChange(status) {
let msg = '';
switch(status) {
case codePushComponent.SyncStatus.CHECKING_FOR_UPDATE:
msg = ("Checking for updates.");
break;
case codePushComponent.SyncStatus.DOWNLOADING_PACKAGE:
msg = ("Downloading package.");
break;
case codePushComponent.SyncStatus.INSTALLING_UPDATE:
msg = ("Installing update.");
break;
case codePushComponent.SyncStatus.UP_TO_DATE:
msg = ("Up-to-date.");
break;
case codePushComponent.SyncStatus.UPDATE_INSTALLED:
msg = ("Update installed.");
break;
}
}
codePushDownloadDidProgress(progress) {
console.log(progress.receivedBytes + " of " + progress.totalBytes + " received.");
}
update () {
codePushComponent.sync({
updateDialog: true,
installMode: codePushComponent.InstallMode.IMMEDIATE
},() => this.codePushStatusDidChange,() => this.codePushDownloadDidProgress);
}
render(){
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome
</Text>
<Text style={styles.instructions}>
Update version 1.0
</Text>
<Button title="Update" onPress={() => this.update()} />
</View>
)
}
}
export default (MyApp)
Additional Information
react-native-code-push version:
4.1.0-beta
react-native version:
16.0.0-alpha.12
iOS/Android/Windows version:
IOS 10.3
Does this reproduce on a debug build or release build?
Release
Release Does this reproduce on a simulator, or only on a physical device? physical device only
I solved it after so many hours, and then wrote an article so that others won't spend that much time on this simple thing.
[Tutorial] Integrate Code push with React Native (IOS & Android)
Code push integration
[Tutorial] Release Build (Running on physical device)
Running React Native on Ios/Android device

How to programmatically switch a switch in React Native?

I make us several Switch Components in one view. When I switch on one switch, I want all others to switch off. Currently, I set the boolean value property via the state. This results in changes happen abruptly because the switch is just re-rendered and not transitioned.
So how would you switch them programmatically?
EDIT 2: I just discovered that it runs smoothly on Android so it looks like an iOS-specific problem.
EDIT: part of the code
_onSwitch = (id, switched) => {
let newFilter = { status: null };
if (!switched) {
newFilter = { status: id };
}
this.props.changeFilter(newFilter); // calls the action creator
};
_renderItem = ({ item }) => {
const switched = this.props.currentFilter === item.id; // the state mapped to a prop
return (
<ListItem
switchButton
switched={switched}
onSwitch={() => this._onSwitch(item.id, switched)}
/>
);
};

How detect tablet landscape on React Native

I want to border margin of of screen S on phone and tablet to be different. There are variants for tablet landscape and portrait mode.
How to create different margin dimension for the variants on phone, tablet portrait, tablet landscape ?
For those curious how to do on Android , we just create some resource files at the right folder :
values for default
values-sw600dp for tablet default
values-sw600dp-land for tablet landscape
The other answers have already addressed the screen detection task. However, there is still the issue of detecting if the code is running on a Tablet device. You can detect that using the react-native-device-info package, in particular its isTablet method. So, as an example, in your component:
constructor(){
super();
this.state = {orientation: 'UNKNOWN'}
this._onOrientationChanged = this._onOrientationChanged.bind(this);
}
_onOrientationChanged(orientation){
this._setState({orientation})
}
componentDidMount(){
Orientation.addOrientationListener(this._onOrientationChanged);
}
componentWillUnmount(){
Orientation.removeOrientationListener(this._orientationDidChange);
}
render(){
let layoutStyles;
if(DeviceInfo.isTablet()){
layoutStyles = this.state.orientation == 'LANDSCAPE' ? landscapeTabletStyle : portraitTabletLandscape; // Basic example, this might get more complex if you account for UNKNOWN or PORTRAITUPSIDEDOWN
}else{
layoutStyles = this.state.orientation == 'LANDSCAPE' ? landscapeStyle : portraitLandscape;
}
render(){
<View style={[styles.container, layoutStyles]} // And so on...
}
}
Note that the state holds the UNKNOWN value on the beginning. Have a look at the getInitialOrientation() of the package function. I am intentionally leaving that bit out because it simply reads a property that is set when the JS code loads, and I am not sure if that satisfies your usecase (i.e. this is not your first screen). What I usually like to do is store the rotation value in a redux store (where I initialize the orientation value to that of getInitialOrientation() and then subscribe only once to the orientation listener).
I think this library will be helpful for you: https://github.com/yamill/react-native-orientation
You can do something like that with it:
Orientation.getOrientation((err,orientation)=> {
console.log("Current Device Orientation: ", orientation);
if(orientation === 'LANDSCAPE') {
//do stuff
} else {
//do other stuff
}
});
// Extract from the root element in our app's index.js
class App extends Component {
_onLayout = event => this.props.appLayout(event.nativeEvent.layout);
render() {
return (
<View onLayout={this._onLayout}>
{/* Subviews... */}
</View>
);
}
}
export const SET_ORIENTATION = 'deviceStatus/SET_ORIENTATION';
export function appLayout(event: {width:number, height:number}):StoreAction {
const { width, height } = event;
const orientation = (width > height) ? 'LANDSCAPE' : 'PORTRAIT';
return { type: SET_ORIENTATION, payload: orientation };
}
Code Copied from Here