I created the Text To Speech function in React Native using the react-native-tts library on Android, but it always shows an error/warn like this
new NativeEventEmitter() was called with a non-null argument without the required addListener method.
new NativeEventEmitter() was called with a non-null argument without the required removeListeners method.
Here's an example from my code.
import React from 'react';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import {View, Text, SafeAreaView, TouchableOpacity} from 'react-native';
import Tts from 'react-native-tts';
const TextToVoiceScreen = ({route, navigation}) => {
const handleTextToSpeech = val => {
let stringSpace = val.split('').join(' ');
// Set Engine Voice
Tts.setDefaultEngine('com.google.android.tts');
Tts.getInitStatus().then(
() => {
Tts.stop();
Tts.setDucking(true);
Tts.setDefaultRate(0.09);
Tts.speak(stringSpace, {
androidParams: {
KEY_PARAM_PAN: -1,
KEY_PARAM_VOLUME: 0.9,
KEY_PARAM_STREAM: 'STREAM_MUSIC',
},
});
},
err => {
if (err.code === 'no_engine') {
Tts.requestInstallEngine();
console.log('Install Engine');
}
},
);
};
return (
<SafeAreaView>
<View>
<Text>Test Voice</Text>
<TouchableOpacity onPress={() => handleTextToSpeech('Hello World')}>
<View>
<MaterialCommunityIcons
name="text-to-speech"
color={'#33691e'}
size={20}
/>
</View>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
export default TextToVoiceScreen;
this is so annoying.
how fix this issues guys..
Related
I have a context that contains an array, this context has a function that updates a certain value in that array:
import React, { createContext, useState } from 'react'
export const SliderValueContext = createContext()
export function SliderValueProvider({ children }) {
const [intensity, setIntensity] = useState([
{
EXAMPLE0: 0,
},
{
EXAMPLE1: 0,
},
{
EXAMPLE2: 0,
},
])
const updateCertainIntensity = (value, index) => {
console.log('Index: ' + index)
console.log('Value: ' + value)
let newIntensity = [...intensity]
newIntensity[index] = value
setIntensity(newIntensity)
}
return (
<SliderValueContext.Provider
value={{intensity, updateCertainIntensity}}>
{children}
</SliderValueContext.Provider>
)
}
I have a basic StackNavigator with both of my screens:
import React from 'react'
import { createStackNavigator } from '#react-navigation/stack'
import Index from './index'
import SliderScreen from './screen'
const Stack = createStackNavigator()
export default function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name='Index' component={Index}/>
<Stack.Screen name='SliderScreen' component={SliderScreen}/>
</Stack.Navigator>
)
}
This is how my index looks like:
import React from 'react'
import {
Button
} from 'react-native'
import { useNavigation } from '#react-navigation/native'
import { SliderValueProvider } from './context'
export default function Index() {
const navigation = useNavigation()
return (
<SliderValueProvider>
<Button title='YOU' onPress={() => navigation.navigate('SliderScreen')}></Button>
</SliderValueProvider>
)
}
App.js
export default function App() {
return (
<NavigationContainer>
<MyStack>
</MyStack>
</NavigationContainer>
)
}
Custom Slider component:
export default function SliderGroup({ id, text, borderColor }) {
const { updateCertainIntensity } = useContext(SliderValueContext)
return (
<View style={[styles.slider_container, { borderColor: borderColor }]}>
<View style={styles.slider_container_text}>
<Text style={styles.text_style}> {text} </Text>
{/* <Text style={styles.number_style}> </Text> */}
</View>
<View style={styles.slider_container_slider}>
<Slider
onValueChange={(value) => updateCertainIntensity(value, id)}
step={1}
minimumValue={0}
maximumValue={5}
maximumTrackTintColor='rgb(255, 255, 255)'
/>
</View>
</View>
)
}
Problem: Whenever I try to access the useContext in my custom Slider component, it says that the context is undefined undefined is not an object (evaluating useContext.updateCertainIntensity) .Other contexts however, work just fine, but they are not using objects, just simple strings. Does it have to do with using an object in useState()?
You aren't wrapping your app inside the context you just created.
In your App.jsx
<NavigationContainer>
<SliderValueProvider> {/* this one is going to feed its children with data */}
<MyStack /> {/* this will be fed by the parent component */}
</SliderValueProvider>
</NavigationContainer>
I am using a so simple GiftedChat component in react native on expo, the problem here is when i open the first time the keyboard this works fine, but the second time i press in the textInput but the keyboard doesn't appear, i'm using a emulator of android 5 and a device with android 7. Doesn't work in any
import { useState, useLayoutEffect, useCallback } from 'react'
import { TouchableOpacity } from 'react-native'
import { GiftedChat } from 'react-native-gifted-chat'
import {
collection,
addDoc,
orderBy,
query,
onSnapshot
} from 'firebase/firestore'
import { signOut } from 'firebase/auth'
import { auth, database } from '../config/firebase'
import { useNavigation } from '#react-navigation/native'
import { AntDesign } from '#expo/vector-icons'
import colors from '../colors'
export default function Chat() {
const [messages, setMessages] = useState([])
const navigation = useNavigation()
const onSignOut = () => {
signOut(auth)
.catch(err => console.log('Error logging out: ', err.message))
}
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
style={{
marginRight: 10
}}
onPress={onSignOut}
>
<AntDesign
name='logout'
size={24}
color={colors.gray}
style={{
marginRight: 10
}}
/>
</TouchableOpacity>
)
})
}, [navigation])
useLayoutEffect(() => {
const collectionRef = collection(database, 'chats')
const q = query(collectionRef, orderBy('createdAt', 'desc'));
const unsubscribe = onSnapshot(q, snapshot => {
setMessages(
snapshot.docs.map(doc => ({
_id: doc.data()._id,
createdAt: doc.data().createdAt.toDate(),
user: doc.data().user,
text: doc.data().text
}))
)
})
return unsubscribe
}, [])
const onSend = useCallback((messages = []) => {
setMessages(previewMessages => GiftedChat.append(previewMessages, messages))
const { _id, createdAt, text, user } = messages[0]
addDoc(collection(database, 'chats'), {
_id,
createdAt,
text,
user,
})
}, [])
return (
<>
<GiftedChat
messages={messages}
showAvatarForEveryMessage={false}
showUserAvatar={true}
onSend={message => onSend(message)}
messagesContainerStyle={{
backgroundColor: '#fff'
}}
user={{
_id: auth?.currentUser?.email,
avatar: 'https://placeimg.com/140/140/any'
}}
/>
</>
)
}
gif example of the error
If you can help me with the reason why this happens i will thank you so much...
The problem is that the TextInput of GiftedChat (of TextInput in general actually) never looses focus if you dismiss the keyboard using the virtual Android button. Thus, the keyboard is not opened again if you simply retouch into the TextInput. If you touch outside it and then inside again, you will notice that the keyboard opens again. This should be the normal behavior of any TextInput and might be even expected by the user (we can open the keyboard again by pressing the same button).
However, you could try to handle this programmatically as well. The GiftedChat component provides a function to allow you to refocus the TextInput again programmatically. It is called focusTextInput() and it
Open(s) the keyboard and focus the text input box
const ref = useRef(null)
<GiftedChat
…
ref={ref}
/>
Then, call ref.focusTextInput(). We could then wrap the GiftedChat component inside a Pressable and fire this in the onPress function.
const ref = useRef(null)
<Pressable onPress={() => ref.focusTextInput()}
<GiftedChat
…
ref={ref}
/>
</Pressable>
onValueChange={(itemValue) => {
setSelectedValue(itemValue);
if(itemValue == 'other'){
alert('You Choose: '+itemValue+' Nice')
return(
// The <View> Doesnt Work Why ????
<View style={{backgroundColor:'red',height:5000,width:5000,}}>
<Text>Anas</Text>
</View>
)
}
}}
The Doesnt Work Why ????
i cant put it in if statment or i can ?
i dont hava idea !!
I put together a small sandbox where you can see an example of how to achieve what you want: https://codesandbox.io/s/sad-bird-lzzbb
import React, { useState } from "react";
import { Button, Text, View } from "react-native";
export default function App() {
const [selectValue, setSelectedValue] = useState('');
const onValueChange = (itemValue) => {
setSelectedValue(itemValue);
};
return (
<div className="App">
<Button
onPress={() => onValueChange("other")}
title="Click to set value to 'other'"
/>
{selectValue === "other" ? (
<View style={{ backgroundColor: "red", height: 5000, width: 5000 }}>
<Text>Anas</Text>
</View>
) : null}
</div>
);
}
You can use the onValueChange function to pass it as callback in any event you want (like the onPress of that button I have created) but then you need to return all jsx in the return of your functional component (or the render function if you're using class components)
We have the following code within I have the method createDrawerNavigator in my App.js file
const RootDrawer = createDrawerNavigator({
Home: { screen: HomeScreen },
Detail: { screen: DetailScreen },
Result: { screen: ResultScreen },
Section : { screen: SectionScreen }
},{
contentComponent : ({ navigation }) => (<SideBar navigation={navigation} />),
initialRouteName: 'Home',
navigationOptions: {
headerStyle: {
backgroundColor: '#26272d',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
transitionConfig: () => ({
transitionSpec: {
duration: 500,
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
screenInterpolator: sceneProps => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
const height = layout.initHeight;
const translateY = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [height, 0, 0],
});
const opacity = position.interpolate({
inputRange: [index - 1, index - 0.99, index],
outputRange: [0, 1, 1],
});
return { opacity, transform: [{ translateY }] };
},
}),
});
And I have the screen SideBar that acts as Drawer:
import React, { Component, PureComponent } from 'react';
import { connect } from 'react-redux';
import { Image, StyleSheet, View, TouchableOpacity, Text, Linking } from 'react-native';
import { Icon } from 'native-base';
import {StackActions, NavigationActions, DrawerActions} from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
export default class SideBar extends React.Component {
goTo = (section) => {
const resetAction = StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Section' })
]
})
return () => this.props.navigation.dispatch(resetAction);
}
render() {
return(
<View style={styles.container}>
<View>
<View style={styles.logo}><Image source={require('./images/ln-header-bg.jpg')} style={styles.ln_logo} resizeMode="contain" /></View>
<TouchableOpacity style={styles.link_menu} onPress={() => { this.goTo('all'); }}><Text style={styles.link_menu_text}>Últimas noticias</Text></TouchableOpacity>
<TouchableOpacity style={styles.link_menu} onPress={() => { this.goTo(68); }}><Text style={styles.link_menu_text}>La Nación</Text></TouchableOpacity>
<TouchableOpacity style={styles.link_menu} onPress={() => { this.goTo(69); }}><Text style={styles.link_menu_text}>El Mundo</Text></TouchableOpacity>
<TouchableOpacity style={styles.link_menu} onPress={() => { this.goTo(70); }}><Text style={styles.link_menu_text}>Gente</Text></TouchableOpacity>
<TouchableOpacity style={styles.link_menu} onPress={() => { this.goTo(97); }}><Text style={styles.link_menu_text}>#YoParticipo</Text></TouchableOpacity>
</View>
<View>
<Text style={styles.follow_social}>Síguenos en las redes</Text>
<View style={styles.follow_social_links}>
</View>
</View>
</View>
)
}
}
In the SideBar I want to call an function located in Home Component, I tried with react navigation dispacth method but doesn't working.
What I have to call the function or navigate to another screen? Can some help me please?
Thanks!
I never used drawers from react-navigation, but I would assume that the way they work is similar to stackNavigators. So, assuming that, what you could do was to set a navigation parameter in the Home screen, for example, inside the componentDidMount() method, like so:
this.props.navigation.setParams({ 'paramName': paramValue });
and then, in the drawer, in the componentWillMount() method, you could do something like:
const var_x = this.props.navigation.getParam('paramName', null);
This way, you can either send the function itself as a parameter, or send a reference to the Home screen, and then access its methods from the drawer.
ps: on both calls, paramName needs to be a string.
ps2: in the getParam method call, the second argument, in the example, null, is the default value in case there is not a value for the requested parameter.
Again, I use this method for stackNavigators, so you might take a look at the react-navigation documentation to double check if there is any difference for drawer: https://reactnavigation.org/docs/en/drawer-navigator.html#docsNav
I am new in react-native and i want to open url in default browser like Chrome in Android and iPhone both.
We open url via intent in Android same like functionality i want to achieve.
I have search many times but it will give me the result of Deepklinking.
You should use Linking.
Example from the docs:
class OpenURLButton extends React.Component {
static propTypes = { url: React.PropTypes.string };
handleClick = () => {
Linking.canOpenURL(this.props.url).then(supported => {
if (supported) {
Linking.openURL(this.props.url);
} else {
console.log("Don't know how to open URI: " + this.props.url);
}
});
};
render() {
return (
<TouchableOpacity onPress={this.handleClick}>
{" "}
<View style={styles.button}>
{" "}<Text style={styles.text}>Open {this.props.url}</Text>{" "}
</View>
{" "}
</TouchableOpacity>
);
}
}
Here's an example you can try on Expo Snack:
import React, { Component } from 'react';
import { View, StyleSheet, Button, Linking } from 'react-native';
import { Constants } from 'expo';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Button title="Click me" onPress={ ()=>{ Linking.openURL('https://google.com')}} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
A simpler way which eliminates checking if the app can open the url.
loadInBrowser = () => {
Linking.openURL(this.state.url).catch(err => console.error("Couldn't load page", err));
};
Calling it with a button.
<Button title="Open in Browser" onPress={this.loadInBrowser} />
Try this:
import React, { useCallback } from "react";
import { Linking } from "react-native";
OpenWEB = () => {
Linking.openURL(url);
};
const App = () => {
return <View onPress={() => OpenWeb}>OPEN YOUR WEB</View>;
};
Hope this will solve your problem.
In React 16.8+, the following can be used to create an ExternalLinkBtn component for opening external links in the browser.
import React from 'react';
import { Button, Linking } from 'react-native';
const ExternalLinkBtn = (props) => {
return <Button
title={props.title}
onPress={() => {
Linking.openURL(props.url)
.catch(err => {
console.error("Failed opening page because: ", err)
alert('Failed to open page')
})}}
/>
}
Below is an example of using our ExternalLinkBtn component
export default function exampleUse() {
return (
<View>
<ExternalLinkBtn title="Example Link" url="https://example.com" />
</View>
)
}