show / Hide text in React Native , time out, gradient - javascript

I am working on a page that basically is supposed to process some back end work and then push on another screen.
This Page should have some text appearing as soon as the page renders that says "submitting your info" then do the backend call, and then the text disappears, and then the whole page performs a push for another screen.
I am confused how to do that !!
This is the render part of the page
render(){
return(
<View style={styles.container}>
<Image style={styles.container} resizeMode="cover" source=
{require('/workingonit.png')}>
<View style={styles.backdropView}>
<Text style={styles.headline}>Submitting your info</Text>
</View>
</Image>
</View>
)
}
I know its something to do with settimeout? or interval?
Sorry I am new to JS and react native .

This example will toggle (hide/show) the text every time you click on the TouchableOpacity by updating the state. You can then, add whatever logic you want as a callback when the state gets updated.
import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native'
export default class DummyPage extends React.Component {
state = {
isTextVisible: false
}
toggleText() {
this.setState({isTextVisible: !this.state.isTextVisible}, () => {
// do some logic here
})
}
renderText() {
if (this.state.isTextVisible) {
return(
<Text>this is a random text</Text>
)
}
}
render() {
return(
<View style={{flex: 1}}>
<TouchableOpacity onPress={this.toggleText}>
<Text>Show Text</Text>
</TouchableOpacity>
{this.renderText()}
</View>
)
}
}
This should work for your API call too. Instead of updating the state with onPress, you can do it when the communication with the backend starts and hide it again when you want to push the user to another screen.

Related

Show texts during a loading

I have a question. I have a loader and during the loading I would show three different texts. Like text1, then this disappear and it's show text2 and then text3.
<View style={style.container}>
<View style={style.page}>
<ActivityIndicator size="large" color="#56cbbe" />
<Text>Text1.. </Text>
<Text>Text2.. </Text>
<Text>Text3.. </Text>
</View>
</View>
In this case I only show the three texts together. How can I do?
Thank you :)
One way to solve this is to use setInterval and call update function to loop through the texts assuming if they are present in form of array.
Simply saying for example.
Let's maintain loadingText in state as loadingText: ['text1', 'text2', 'text3'],A variable to track the present item as currentLoadingTextIndex: 0 and call setInterval in componentDidUpdate.
Be careful when calling update function in here,as one wrong mistake will make your app crash.
componentDidUpdate(prevProps, prevState) {
if (!prevState.isLoading && this.state.isLoading) {
this.timerId = setInterval(this.changeLoadText, 2000);
} else if (prevState.isLoading && !this.state.isLoading) {
clearInterval(this.timerId);
}
}
and finally our update function
changeLoadText = () => {
this.setState(prevState => {
return {
currentLoadingTextIndex:
(prevState.currentLoadingTextIndex + 1) %
prevState.loadingText.length,
};
});
};
I am attaching a working expo Demo for clarity purpose.
What you want is to show indicator and text1 during loading time and then text2 and text3. Is that right?
So I made an example for you. This should solve the problem by changing the status value. You can display the indicator for the duration of loading and show the text by changing the status value when loading is complete.
Example Code
//This is an example code to understand ActivityIndicator//
import React from 'react';
//import react in our code.
import { ActivityIndicator, Button, View, StyleSheet,Text } from 'react-native';
//import all the components we are going to use.
export default class App extends React.Component {
state = { showIndicator: true };
componentDidMount() {
setTimeout(() => {this.setState({showIndicator: false})}, 2000)
}
onButtonPress = () => {
//function to change the state to true to view activity indicator
//changing state will re-render the view and indicator will appear
};
render() {
//Check if showIndicator state is true the show indicator if not show button
if (this.state.showIndicator) {
return (
<View style={styles.container}>
{/*Code to show Activity Indicator*/}
<ActivityIndicator size="large" color="#0000ff" />
<Text>Text1.. </Text>
{/*Size can be large/ small*/}
</View>
);
} else {
return (
<View style={styles.container}>
<Text>Text2.. </Text>
<Text>Text3.. </Text>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
flexDirection: 'column',
alignItems: "center"
},
});

How to reload page after navigating from another screen

// I am using below code for navigating one screen to another i.e Home page .
But when am navigating home page , I have to refresh the page ..reload . In current , when i am coming to home screen non of the life cycle method is getting call . Specially UserAvatar component I have to refresh ,or recall .
Please suggest
<View style={{textTransform: 'lowercase'}}><YellowBtn label="Go to
Dashboard"
OnClick={this._redirectCustomerView}/></View>
_redirectCustomerView = () => {
this.props.navigation.navigate('UserHome');
};
// Below is home page
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { title: 'Hello!', hasFooterPermission: false };
console.log("Valuueeeeeee");
}
async componentDidMount() {
const homeFooter = await hasPermission('clm.360D.fe.restrictedView.allowed');
this.setState({
hasFooterPermission: homeFooter
})
}
onSearchClick = () => {
this.props.navigation.navigate('SubscriberSearch');
};
componentWillMount(){
console.log(" Home page dataaaa");
}
render() {
return (
<View>
<ImageBackground source={BG} style={{ width: '100%', height: '100%' }} resizeMode="cover">
<View style={{ paddingTop: 5 , alignContent:'space-between',flexDirection:'row'}}>
<View style={{alignSelf: 'flex-start', flex:1}}>
<UserAvatar navigationProps={this.props.navigation} avatarSize={40} isTouchable={true}/>
</View>
{/* <View style={{alignSelf: 'flex-end'}}>
<Icon
name="bell-outline"
type="MaterialCommunityIcons"
style={{ color: '#FFFFFF' }}
onPress={() => Toastr.showToast('No new notifications!', 3000)}
/>
</View> */}
</View>
use push instead of navigate
this.props.navigation.push('UserHome');
It is not homepage duty to know if you have to refresh the page. The suggested approach is that when the condition to reload is met (avatar update, user properties changes, etc) then the calling entity should go to the homepage and if needed ask for a reload (i.e., window.location.reload(true))
If you add a listener on the home page through the navigation prop, you can call a function when a transition to or from the home page is about to happen ('willFocus'/'willBlur') or if it has completed ('didFocus'/'didBlur').
This worked for me:
componentDidMount(){
this.props.navigation.addListener('willFocus',this.load)
}
load = () => {
//whatever you want to do when the page loads
}
Documentation here: https://reactnavigation.org/docs/en/navigation-prop.html

FlatList is not re-rendering on the state change

On pressing the button(ButtonComponent), the state of the button gets changed. Now I'm passing that state to the <FlatListItem> (a child component ) inside <FlatList>. Depending on that status, the each item in the <FlatList> should be re-arranged.
I just got to know about this extraData prop but not sure how to make use of it in the code.
It's not something new but it is like simple checkbox implementation.
Everything is working fine but when I press the select all button all the remaining select buttons are not getting toggled to selected.
class FlatListItem extends Component{
constructor(props){
super(props)
const{ isSelected }=this.props
this.state={
selectedStatus:isSelected,
}
}
changeSelectStatus=(key)=>{
this.setState({selectedStatus:!this.state.selectedStatus});
return key;
}
render(){
return(
<View style={{flex:1,
flexDirection:'row',
backgroundColor:'white'}}>
<View>
<Image
source={{uri:this.props.item.imageUri}}
style={{width:50, height:50, margin:5}}>
</Image>
</View>
<View>
<Text style={{color:'black', padding:10, fontSize:16}}>{this.props.item.name}</Text>
</View>
<View style={{flex:1, alignItems:'flex-end', paddingRight:-10}}>
{this.state.selectedStatus?
**<ButtonComponent buttonColor={"black"} buttonTextColor={"white"} fullRounded={true}
borderHighlight={true} buttonWidth={70} buttonHeight={30}
onPress={()=>this.props.showSelected(this.changeSelectStatus(this.props.item.key)) }>
Selected
</ButtonComponent>
:
<ButtonComponent buttonColor={"white"} buttonTextColor={"black"} fullRounded={true}
borderHighlight={true} buttonWidth={70} buttonHeight={30}
onPress={()=>this.props.showSelected(this.changeSelectStatus(this.props.item.key)) }>
Select
</ButtonComponent>
}
</View>
</View>
)
}
}
export default class SelectMembersBody extends Component {
constructor(props){
super(props)
this.state={
selectedButtons:[],
selectAllBtnStatus:false,
}
}
selectAllMembers=()=>{
let allMembers=[];
if(!this.state.selectAllBtnStatus){
membersData.forEach(element => {
if(!this.state.selectedButtons.includes(element.key))
allMembers.push(element.key)
});
this.setState({
selectAllBtnStatus:!this.state.selectAllBtnStatus,
selectedButtons:[...this.state.selectedButtons, allMembers]
})
}
else{
this.setState({
selectAllBtnStatus:!this.state.selectAllBtnStatus,
selectedButtons:[...allMembers]
})
}
}
showSelected=(callback)=>{
let val = callback;
if(!this.state.selectedButtons.includes(val))
this.setState({selectedButtons:[...this.state.selectedButtons, val]});
else{
let newMarkers=[...this.state.selectedButtons]
let index = newMarkers.indexOf(val);
if (index >= 0) {
newMarkers.splice( index, 1 );
}
this.setState({selectedButtons:newMarkers});
}
}
render(){
return(
<View style={{flex:1, }}>
<Text>{this.state.selectedButtons}</Text>
<View>
{this.state.selectAllBtnStatus?
<ButtonComponent buttonColor={"black"} buttonTextColor={"white"} fullRounded={true}
borderHighlight={true} buttonWidth={85} buttonHeight={30} onPress={this.selectAllMembers}>
Selected All
</ButtonComponent>
:
<ButtonComponent buttonColor={"white"} buttonTextColor={"black"} fullRounded={true}
borderHighlight={true} buttonWidth={85} buttonHeight={30} onPress={this.selectAllMembers}>
Select All
</ButtonComponent> }
</View>
<FlatList data={membersData} extraData={this.state}
renderItem={({item, index})=>{
return(
<View>
<FlatListItem item={item} index={index} isSelected={this.state.selectAllBtnStatus} showSelected={this.showSelected} ></FlatListItem>
</View>
)
}
}></FlatList>
</View>
)
}
}
I know that it's quite harder to step into someone's shoes. The code I provided in my question might not be that effective since I'm a learner. That's why it is uncomfortable to get on to the code flow. So, I decided to answer my own question after reading some articles, docs and similar questions on StackOverFlow.
So, my question is why the flatlist was not getting re-rendered on setState. To be more precise, if you've gone through the pictures above, on selecting the Select All button all the buttons in the items should be toggled to selected state.
To make the flatlist re-render, we need to add an additional prop "extraData"
By passing extraData={this.state} to FlatList we make sure FlatList itself will re-render when the state.selected changes. Without setting this prop, FlatList would not know it needs to re-render any items because it is also a PureComponent and the prop comparison will not show any changes.
You can get it's full documentation here.
In my case, I set extraData = {this.state} since the status of buttons in each of the flatlist item depends on the array which is present in the parent component.
So, I've sent it to child component via props.
Now the flatlist is working fine and re-rendering on every state update.

React native infinite scrollview with next previous buttons

I want to create a Infinite ScrollView like react-native-infinte-scrollview in which views are created and deleted on scroll but this plugin doesn't provide next/previous buttons. I just want to add next and previous buttons because I have 10 gif files in my project and each gif is 7 to 10 MB in size and if I load all these gif files at the same time in scrollview, my app crashed.
i dont know about this but i have logic here
constructor(){
this.state = {
pageNUmber:0,
data:['url1','url2',url3]
}
}
renderGif(){
var data = this.state.data;
return(
<Image source={{uri:data[this.state.pageNUmber]}} ?>
)
}
changePage(val){
if(val=='next'){
this.setState({
pageNumber:this.state.pageNumber+1
})
}else{
if(this.state.pageNumber!=0)
this.setState({
pageNumber:this.state.pageNumber-1
})
}
}
render(){
return(
<View>
<ScrollView>
{this.renderGif()}
</ScrollView>
<TouchableOpacity onPress={()=>{this.changePage('next')}}>
<Text>next</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>{this.changePage('previous')}}>
<Text>previous</Text>
</TouchableOpacity>
</View>
)
}
Im pretty sure that the difference between React Native's ScrollView and FlatList is that flatlist deletes content off the page.
According to the Docs, you'll want to use Flatlist with horizontal enabled

How do I enable touch on multiple buttons simultaneously in react native?

I need that when I am touching and holding one button then I should also be able to touch on the button 1.
<View>
<View
onStartShouldSetResponder={()=>this.console("Button 2 Clicked")}>
<Text>BUTTON 2</Text>
</View>
<TouchableOpacity
onPressIn={()=>this.console('Button 1 pressed')}
onPressOut={()=>this.console('Button 1 released')}>
<View>
<Text>BUTTON 1</Text>
</View>
</TouchableOpacity>
</View>
Basically, I have a screen where I can record a video by tapping and holding the record button(Button 1). On the same screen, I have a flip camera button (Button 2). I want that I should be able to click on the flip camera button while I am recording the video.
This problem can easily be resolved using onTouchStart, onTouchEnd props of View component without using gesture responder methods.
So the modified code will look like
<View>
<View onTouchStart={()=>this.console("Button 2 Clicked")}>
<Text>BUTTON 2</Text>
</View>
<View
onTouchStart={()=>this.console('Button 1 pressed')}
onTouchEnd={()=>this.console('Button 1 released')}>
<Text>BUTTON 1</Text>
</View>
</View>
This is my solution for multiple buttons
import React, { Component } from 'react';
import {
View,
PanResponder,
} from 'react-native';
import ReactNativeComponentTree from'react-native/Libraries/Renderer/shims/ReactNativeComponentTree';
export default class MultiTouch extends Component{
constructor(props) {
super(props);
this.onTouchStart = this.onTouchStart.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
this.onTouchCancel = this.onTouchCancel.bind(this);
this.triggerEvent = this.triggerEvent.bind(this);
}
onTouchStart(event){
const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
this.triggerEvent(element._owner, 'onPressIn');
}
onTouchEnd(event){
const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
this.triggerEvent(element._owner, 'onPressOut');
}
onTouchCancel(event){
const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
this.triggerEvent(element._owner, 'onPressOut');
}
onTouchMove(event){
// console.log(event);
}
triggerEvent(owner, event){ // Searching down the
if(!owner || !owner.hasOwnProperty('_instance')){
return;
}
if(owner._instance.hasOwnProperty(event)){
owner._instance[event]();
}else{
this.triggerEvent(owner._currentElement._owner, event);
}
}
render(){
return (
<View
onTouchStart={this.onTouchStart}
onTouchEnd={this.onTouchEnd}
onTouchCancel={this.onTouchCancel}
onTouchMove={this.onTouchMove}>
{this.props.children}
</View>
);
}
}
Then I simply wrap the buttons that needs to be pressed at the same time withe the component
<MultiTouch style={this.style.view}>
<UpDownButton />
<UpDownButton />
</MultiTouch>
Cheers!
UPDATE
Because of breaking changes in native react v.0.51, my previous solution does not work any more. But I manage to create a new one. Instead of using TouchableWithoutFeedback and onPress I use View and onTouch on each button that should have multitouch.
import React, { Component } from 'react';
import {
View,
} from 'react-native';
export default class RoundButtonPart extends Component{
constructor(props) {
super(props);
this.state = { active: false };
this.onTouchStart = this.onTouchStart.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
this.onTouchCancel = this.onTouchCancel.bind(this);
}
onTouchStart(event){
this.setState({ active: true });
this.props.onPressIn && this.props.onPressIn();
}
onTouchEnd(event){
this.setState({ active: false });
this.props.onPressOut && this.props.onPressOut();
}
onTouchCancel(event){
this.setState({ active: false });
this.props.onPressOut && this.props.onPressOut();
}
onTouchMove(event){
}
render(){
return (
<View
onTouchStart={this.onTouchStart}
onTouchEnd={this.onTouchEnd}
onTouchCancel={this.onTouchCancel}
onTouchMove={this.onTouchMove}>
{this.props.children}
</View>
);
}
}
I used react-native-gesture-handler. Install it and just replace
import { TouchableOpacity } from 'react-native';
with
import { TouchableOpacity } from 'react-native-gesture-handler';
Example
<View>
<TouchableOpacity
onPressIn={()=>this.console('Button 2 pressed')}
onPressOut={()=>this.console('Button 2 released')}>
<View>
<Text>BUTTON 2</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPressIn={()=>this.console('Button 1 pressed')}
onPressOut={()=>this.console('Button 1 released')}>
<View>
<Text>BUTTON 1</Text>
</View>
</TouchableOpacity>
</View>
Link: https://software-mansion.github.io/react-native-gesture-handler/docs/component-touchables.html
This library also offers button components which can be directly used instead of wrapping Text with TouchableOpacity
Try:
import { TouchableOpacity } from 'react-native';
Instead of:
import { TouchableOpacity } from 'react-native-gesture-handler';
Will help you to multiple buttons.
For example, if you have a TouchableOpacity inside a TouchableWithoutFeedback, when TouchableOpacity is touched, it will only call TouchableOpacity's onPress, and will not be called onPress of TouchableWithoutFeedback.

Categories

Resources