How to get current focused FlatList Item - react-native

I am creating an androidTV application and trying to get the current FlatList focused item using TouchableNativeFeedback.
I have tried using "onFocus" to change a state when the FlatList item has focus but when the application rendered it seemed to focus on every item as it was loaded into the FlatList resulting in an error for to many SetState updates. I tried using "()=>" in the onfocus to stop it running at render but this seemed to stop it working completly
<View style={styles.containerItemNow}>
<TouchableNativeFeedback background={TouchableNativeFeedback.Ripple('#f14621', true)} onFocus={this.UpdateStatus(item.status)} onPress={() => this.downloadfile(item.url)}>
<View style={styles.containerItemNowSelected}>
<Text style={{color: 'white'}}>{item.title}</Text>
</View>
</TouchableNativeFeedback>
</View>
I was hoping when the users move using there d-pad the item highlights with the ripple effect and runs the onfocus and updates the needed state but this does not happen even when the items ripple effect shows the onfocus does not run

Related

How do I make an absolut positioned touchable element on top of a FlatList catch only press events and let other events propagate to the FlatList?

I have a FlatList in React Native with fullscreen image and video items (with pagingEnabled). I want to have a short descriptive touchable text floating on top of the FlatList, to open up a view with some information about the image/video when pressed.
To make the user experience nice, I'd like to be able to scroll the FlatList through the touchable text as well. I.e. if the user happen to start their scrolling motion on top of the text, the FlatList would scroll but if it is a simple press event I'd like to open the view with details about the image/video.
No mater what I try I end up with either the text being able to react to the press OR the FlatList being able to scroll. I have tried different configurations with a custom PanResponder and pointerEvents but seem to always end up with a state were one thing does not work. Do you guys have any smart ideas? I am probably just stuck in the wrong train of thought.
This is a simplified view of my component structure:
<View>
<View style={{ position: 'absolute', bottom: 100, zIndex: 10 }}>
<TouchableOpacity onPress={() => console.log('press')}>
<Text>Some Descriptive Text</Text>
</TouchableOpacity>
</View>
<FlatList pagingEnabled horizontal {...otherFlatListProps} />
</View>

TouchableOpacity wont work as supposed in android

I got an app with flatlist ,I added to the app TouchableOpacity that covers the whole screen,
works great when I click on item area but doesn't work when I click the area that got no items
this is the code of the TouchableOpacity:
<View style={{position: "absolute",width:'100%',height:HEIGHT,backgroundColor: 'rgba(0,0,0,0.8)',zIndex:6}}>
<TouchableOpacity onPress={()=>setEditing(false)} style={{flex:1,zIndex:6}}>
</TouchableOpacity>
Its looks like the flatlist block any clicks below it also in ios its works without any problems
Try change it to:
<View style={{position: "absolute",width:'100%',height:HEIGHT,backgroundColor: 'rgba(0,0,0,0.8)',zIndex:6}}>
<TouchableOpacity onPress={()=>setEditing(false)} style={{flex:1,zIndex:7}}>
</TouchableOpacity>
</View>
and run it

React Native button on press doesn't work properly

I got a weird problem on my react native app, I've a counter buttons, like increment and decrement the quantity of product using redux, but the problem is when i press on button the store value change but the Text component (View) doesn't change automatically until i click outside the button (That's the weird issue).
I tried Button component with onPress, TouchableOpacity onPress but still the same issue.
<TouchableOpacity onPress={()=>{this.handleDecQuantity(item)}}>
<Icon
family="AntDesign"
size={16}
name="minus"
color="#2B4D8E"
style={styles.btn}
/>
</TouchableOpacity>
...
<Text size={16}>{item.quantity}</Text>
...
<Button onlyIcon icon="plus" radius={3} shadowless iconFamily="AntDesign" iconSize={20} color="tarnsparent" iconColor="#2B4D8E" style={styles.btn} onPress={()=>{this.handleIncQuantity(item)}}>+</Button>
I hope the issue is clear, The counter change only when i click outside of button or TouchableOpacity

Inconsistent focus by TextInput in React Native

I have a TextInput that looks like this.
<TextInput
autoFocus
style={styles.inputText}
placeholder="Type username here here"
ref={input => { this.textUser = input }}
value={this.state.user}
onChangeText={(user) => this.setState({user})}
/>
Now, this is inside a component that is called by a TabNavigator which happens also to be buried inside a StackNavigator. You can see the raw visual representation below:
[Label of Tabs below]
Home Tab (has list of users to choose from)
|
---Show Summary of User
|
---Show more detail about the User
AddUser Tab
Every time I click the Tab named AddUser that has the above TextInput I could see the cursor blinking on my TextInput and obviously the focus is working. However, if I press on one of the list (it has a list of users with summary of information) on my Home Tab and it shows a component, once I go back and press the Tab AddUser again, the focus is gone and there is no blinking cursor. Additionally, if I click also the List of users that I mentioned earlier that shows summary information of the user and then I click further down that shows the more Detail information about the user (See illustration above). Then go back (twice) to Home then click again the Add User it works without problem meaning focus is there and the cursor is blinking.
Below is a snippet code inside the Summary View of Users component:
<View style={{flex:10, flexDirection:'column', justifyContent:'center'}}>
<View style={{flex:8, marginTop:40, marginBottom:40, alignItems:'center', justifyContent:'center', backgroundColor:lightBlue}}>
<Text style={{fontSize:36, color:black, fontWeight:'bold'}}>{user.title}</Text>
<Text style={{fontSize:24, color:gray, fontStyle:'italic'}}>{user.totalAchievements} </Text>
</View>
<View style={{flex:1, justifyContent:'flex-start'}}>
<Button
raised
backgroundColor={white}
color={black}
icon={{name: 'add-circle-outline', color:black}}
onPress={()=>this.gotoAddDetail(user)}
title='Add Detail' />
</View>
</View>
I've been debugging this for almost a whole day and can't figure out what could be the problem. I am new to React and React Native by the way.

React Native Touchable is disabling ScrollView

I'm new to React Native, so am probably asking something very obvious, but please help.
I have a view wrapped in a touchable, so that the whole area responds to tapping. Then have a ScrollView nested inside the view. The overall structure is something like this:
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<Text>Hello, here is a very long text that needs scrolling.</Text>
<ScrollView>
</View>
</TouchableWithoutFeedback>
When this compiles and runs, the tapping is detected, but the scroll view doesn't scroll at all. I made the above code short and simple, but each component has the proper styling and I can see everything rendering fine and the long text is cutoff at the bottom of the ScrollView. Please help.
Thank you!
This is what worked for me:
<TouchableWithoutFeedback onPress={...}>
<View>
<ScrollView>
<View onStartShouldSetResponder={() => true}>
// Scrollable content
</View>
</ScrollView>
</View>
</TouchableWithoutFeedback>
The onStartShouldSetResponder prop stops the touch event propagation towards the TouchableWithoutFeedback element.
I'm using this structure it's working for me:
<TouchableWithoutFeedback onPress={() => {}}>
{other content}
<View onStartShouldSetResponder={() => true}>
<ScrollView>
{scrollable content}
</ScrollView>
</View>
</TouchableWithoutFeedback>
You can have a scrollView or FlatList inside a TouchableWithoutFeedback. Tho you shouldn't but some times you have no other choice to go. Taking a good look at this questions and answer validates that.
close react native modal by clicking on overlay,
how to dismiss modal by tapping screen in react native.
For the Question, The only way you can make it work (atleast that i know of), or the simplest way is to add a TouchableOpacity around Text in your code like this,
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<TouchableOpacity>
<Text>Hello, here is a very long text that needs scrolling.</Text>
</TouchableOpacity>
<ScrollView>
</View>
</TouchableWithoutFeedback>
Note: TouchableOpacity is a wrapper for making Views respond properly to touches so automatically you can style it the way you would have styled your View Component then set some of its special props to whatever you want e.g activeOpacity etc. Moreso you can use TouchableHighlight it works, but it receives one child element i.e you enclose all your component inside a parent one.
I'm using this structure it's working for me:
<TouchableOpacity>
{other content}
<ScrollView>
<TouchableOpacity activeOpacity={1}>
{scrollable content}
</TouchableOpacity>
</ScrollView>
I found that for my situation the other examples did not work as they disabled the ability to click or disabled the ability to scroll. I instead used:
<FlatList
data={[{key: text1 }, { key: text2 } ...]}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={this.onPressContent}>
<Text style={styles.text}>{item.key}</Text>
</TouchableWithoutFeedback>
)}
/>
I happend to need to multiple chunks but you could use single element in the data array for one piece of text.
This let the press event to fire as well as let the text scroll.
Trying to use a ScrollView component inside a TouchableWithoutFeedback component can cause some unexpected behavior because the TouchableWithoutFeedback component is designed to capture user gestures and trigger an action, but the ScrollView component is designed to allow users to scroll through content.Here is what the official docs say
Do not use unless you have a very good reason. All elements that
respond to press should have a visual feedback when touched.
TouchableWithoutFeedback supports only one child. If you wish to have
several child components, wrap them in a View. Importantly,
TouchableWithoutFeedback works by cloning its child and applying
responder props to it. It is therefore required that any intermediary
components pass through those props to the underlying React Native
component.
Thats write , you cannot have a scroll view inside the TouchableWithoutFeedback, it the property of react native that it will disable it, you can instead have your scroll view outside the TouchableWithoutFeedback tab and add the other contents that you want upon the click inside a view tag.
You can also use the Touchable Highlights instead, if the TouchableWithoutFeedback does not works.