How to manually set the app window dimensions in React Native - react-native

I was wondering if it would be possible to manually set the entire app window dimension manually.
I'm aware of the useDimensions hook but I'm not interested in listening to window's dimensions changes, I'm interested in setting them.
For example I would like to set an entire app to be 50% in height of the available screen size.
I could't find any doc on this specific request.
Is this possible? How?

why dont you try this in the root level file, like app.js or somewhere ,
const App = () => {
return(
<View>
<View style={{height:0.5*Dimensions.get('window').height}}>
<StackNavigatrScreen />
</View>
<View style={{height:0.5*Dimensions.get('window').height,width:'100%'}}/>
</View>
)
}
and inside the stack navigator you have your enitre screens, so that it just occupies 50 percent of screen ,rather than whole
hope it helps, feel free for doubts

Related

React navigation header resizes on navigating to a screen with react-navigation/native-stack

I'm getting a strange behavior when navigating into a screen containing the code below.
I believe it has something to do with how the flex containers are rendered when navigating into a new screen, but I'm not sure.
This seems to happen when creating navigation stacks with '#react-navigation/native-stack', and once for the entire navigation regardless. See EDIT 2 below for more details.
export const AccountScreen = ({ route, navigation }: any) => {
return (
<View style={{ flex: 1, flexDirection: 'column'}}>
<View style={{ flex: 1 }}>
<Text>Top</Text>
</View>
<View style={{}}>
<Text>Bottom</Text>
</View>
</View>
);
};
I created a snack to demonstrate: https://snack.expo.dev/#kickbk/navigation
The issue is that when I navigate to Account, you may notice that Bottom sort of jumps up the first time it renders the screen. It's very brief, but it happens.
This glitch becomes more visible when adding content such as images instead of Text.
On a very bad Android phone it sometimes gets stuck where the Bottom part gets hidden below and behind the navigation bar.
If you look at this snack and go to Carousel.tsx, you will see the content I load into Screens > AccountScreen.
How do I do this correctly? How do I load this screen so the content will not jitter like that?
MORE INFO
I screen recorded what I was seeing and you can clearly see it jmuping around, frame by frame:
Frame 1
Frame 2
Frame 3
Frame 4
EDIT 2
It looks like this header adjusting height behavior happens with #react-navigation/native-stack. When switching to importing stack from #react-navigation/stack, and then navigating to Account, the glitch doesn't happen.
However, when launching the app, despite all the stack getting imported from #react-navigation/stack, the header gets adjusted once. I am guessing it's because the entire JS implementation of stacks sits inside a native component which cuases this behavior when loaded once. Maybe caused by NavigationContainer from '#react-navigation/native';?
I have updated the snack (https://snack.expo.dev/#kickbk/navigation) with a minimal implementation so there's no doubt on possible third party dependency influencing this.

How to add a screen switcher component in react native

Being a newbie to the field of app development, I actually don't know the name of this UI component .
This component basically act as a switcher between two screen, which shows up Explore screen when Explore is clicked and My Community screen when My Community is clicked
Someone please help me to know what to call this component and which npm package need to be used to deploy it.
THANKS IN ADVANCE!!!
You can use the switch component and its boolean value to conditionally display different screens/components.
Basic example using setState:
const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
return (
<View>
<Switch
onValueChange={toggleSwitch}
value={isEnabled}
/>
{isEnabled ? <Text>Placerholder Screen 1</Text> : <Text>Placerholder Screen 2</Text>}
</View>
);
But in this situation I would advise you to use Tabs instead of a Switch. React Navigation is a great library to help you with this. You may want to look at the bottom tabs, material bottom tabs or material top tabs.

Controlling how far to scroll in flat list. React native

Good day guys , is there anyway I can control how far the flatlist can scroll ? I'm trying to make an image viewer. When there is multiple image , the user can scroll to the 2nd image without reaching the 3rd image. Thank you. Expected outcome :
Either you can use a library like react native snap carousel
or use the function of scrollToIndex inside any function ,so that you can control which index the user goes ==
scrollToNext(){
this.flatListRef.scrollToIndex({animated: true, index: newIndex});
}
<Flatlist
ref={ref => {
this.flatListRef = ref;
}}
/>
hope it helps. feel free for updates

react-native - TouchableHighlight: Remove highlighting after onPress?

I am developing a simple react-native app and am encountering an issue on TouchableHighlight:
When pressing the TouchableHighlight, a new screen is displayed (using StackNavigator from react-navigation). After pressing the back-button and returning to the original screen, the TouchableHighlight still has a black background-color - meaning, that it is still highlighted.
My questions are:
Is there a way to manually deactivate the highlighting of a TouchableHighlight-component? That way I could disable the highlighting after onPress has run.
What could be possible reasons to why the TouchableHighlight stays highlighted? I am using it on other parts of my app without navigation, and I could imagine that it has to do with that.
The TouchableHighlight exists within a FlatList. The renderItems-method looks like the following:
let handlePress = () => {
this.props.navigation.navigate('DetailsScreen');
};
return <TouchableHighlight
onPress={handlePress}>
<Text>Some Text</Text>
</TouchableHighlight>;
If you need/want any further information, please let me know. I've tested the code on android, using the Genymotion-emulator with Marshmallow.
Versions are:
node -v: 8.9.4
npm -v: 5.6.0
react-native-cli: 2.0.1
react-native: 0.54.2
react-navigation: 1.5.2
Build environment: Windows 10 64-bit
At this point, I'm quite certain that the error is somewhere in my code, as TouchableHighlight works correctly on other parts of my app, and it propably has to do with the navigation-call, but I was unable to pinpoint, why exactly. I've made sure that there are no exceptions or anything like that in my app, and that the onPress-method therefore finishes successfully.
You can replace Touchable Highlight with Touchable opacity and simply set activeOpactity prop with value 1. It will not highlight the press.
<TouchableOpacity activeOpacity={1}>....</TouchableOpacity>
After using the tip from #Kartiikeya and exchanging TouchableHighlight with TouchableOpacity and back to TouchableHighlight, it now works as expected:
Now, after onPress has been executed, the button (be it a TouchableOpacity or a TouchableHighlight) looses its effect.
I am not sure, why it works now. The obvious reason would be, that a recompilation of the source code fixed errors - but I recompiled it for writing the original question multiple times before, so that that cannot be an option. Other users I would suggest to clear any cache possible, and especially do the following steps:
Close and reopen the android emulator / restart your testing device
Restart the build PC
Recompile all source code
Check in your console for errors and/or exceptions (obviously)
Replace TouchableHighlight with TouchableOpacity, recompile, check if the error still exists - and if not, reexchange TouchableOpacity to TouchableHighlight
You can replace Touchable Highlight with Touchable opacity. It won't highlight the press.
return <TouchableOpacity
onPress={handlePress}>
<Text>Some Text</Text>
</TouchableOpacity >;
For me, i needed to disable the highlight effect after onLongPress has been fired. You can simply change the key of the touchable using a re-render when you want to remove it.
Here's an example:
<TouchableHighLight
onPress={this.pressRow}
style={styles.outerContainer}
onLongPress={() => this.setState({ onLongPressed: true })}
onPressOut={() => this.setState({ onLongPressed: false })}
key={`long-pressed-${this.state.onLongPressed ? 'yes' : 'no'}`}>
<View style={styles.innerContainer}>
{rowText}
{rowIcon}
</View>
</TouchableHighLight>
Following Leonardo Lusoli's answer, there one thing you should also add is
useEffect(() => {
if(isLongPressed){
setIsLongPressed(false)
}
}, [isLongPressed])
This step is necessary because
when the first onLongPress event is fired it will set isLongPressed to true and thus changing the key the component is re-rendered and is identifies as a new component and previour event listners are discareded so the onPressOut will not be fired. So
when isLongPressed is set to true the component re-renders and then immediatietly we set it's value to false and thus we get the expected behaviour. Otherwise we will get the unexpected behaviour followed by one expected behaviour.

How do I detect if a language has been changed when using the goBack() in React Native?

I have 3 pages that will be interacting with each other. a Login page, a Settings page, and a HomeScreen page. The login page contains a toolbar which has a clickable back arrow image(uses goBack()) and a clickable settings image which redirects to a settings page where a language can be picked.
There is no problem detecting a language change on the settings page because state is updated upon a change in language. However, if the user taps the backarrow image, the login page does NOT detect a change in state. How do I make sure that the login page can detect if the language has been changed(on the Settings page)?
I found on question that is similar to my problem here however, the answer provided uses navigate, whereas I'm using goBack. I know they're similar, but I'm unsure as to how/where I could pass a callback function on my settings page, and where to use refresh() on my Login page.
I use this method on my Login page
componentWillMount() {
AsyncStorage.getItem('language', (err, result) => {
langCode = result;
this.setState({
currLang: result,
})
});
}
On my Settings page:
onLangChange(value, index){
Config.langCode = value;
this.setState({ currLang: Config.langCode });
AsyncStorage.setItem('language', value)
console.log( 'here is your new lang ' + Config.langCode);
}
and then
render(){
const {navigate} = this.props.navigation;
const {goBack} = this.props.navigation
const langText = Config.langText[this.state.currLang]; // Object that has text in current language.
return(
<ScrollView style={styles.mainContainer}>
<View style={styles.headerContainer}>
<View style={styles.iconContainer}>
<TouchableOpacity onPress={ () => goBack('') } >
<Image source={Config.images.leftArrowIcon} style={styles.leftArrowIcon} />
</TouchableOpacity>
Use redux for global states like language in your example. It's just much simpler. If you have like 30 screens in your app, and every screen must display texts in correct language, this means that you have to send language back and forth between 30 screens, that's just horrible. redux is a state container, it's strongly recommended that you put those global states (states that many screens share) in redux and send them to each screen. If you don't know how to use redux yet, don't worry, it's not hard to understand, there're plenty good tutorials online. Here is the LanguagePickerExample I wrote for this question using redux, simply
npm install
or
yarn
then
react-native link
The result looks like this: