TextInput in absolute positioned LinearGradient doesnot focus - react-native

I have a component with 2 LinearGradient views, both of them with absolute position and one with TextInput. For this setting, TextInput never gains focus in Android.
Code:
class SearchScreen extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<LinearGradient
colors={['blue', 'red']}
style={{
height: 80,
width: '100%',
position: 'absolute',
zIndex: 10,
elevation: 10,
top: 0,
left: 0,
}}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
>
<TextInput
style={{
backgroundColor: 'white',
height: 50,
paddingLeft: 15,
marginTop: 10,
marginBottom: 10,
marginRight: 20,
marginLeft: 20,
borderWidth: 0,
}}
placeholder={'search placeholder'}
onFocus={() => { console.log('onFocus: '); }}
onChangeText={(text) => { console.log('enter text: ', text); }}
onEndEditing={() => { console.log('endEditing: '); }}
/>
</LinearGradient>
<LinearGradient
colors={['red', 'blue']}
style={{
height: 150,
width: '100%',
position: 'absolute',
zIndex: 5,
elevation: 5,
}}
>
</LinearGradient>
</View >
);
}
}
export default SearchScreen;
React Native: 0.55.2
react-native-linear-gradient: 2.4.0
I found the problem is with the 2 absolute positioned LinearGradient View with Text Input. If I remove the one of the LinearGradient, the TextInput works fine as it should.
I've tried providing zIndex to the TextInput too, it doesn't work.
Thanks.

Seems like a bug in the zIndex for android, as it works fine for IOS.
You can use it the following way as a workaround by nesting of linear gradients so that there is no conflict for the overlay element that renders.
<LinearGradient
colors={['red', 'blue']}
style={{
height: 150,
width: '100%',
position: 'absolute',
zIndex: 5,
elevation: 5,
}}
>
<LinearGradient
colors={['blue', 'red']}
style={{
height: 80,
width: '100%',
position: 'absolute',
zIndex: 10,
elevation: 10,
top: 0,
left: 0,
}}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
>
<TextInput
style={{
backgroundColor: 'white',
height: 50,
paddingLeft: 15,
marginTop: 10,
marginBottom: 10,
marginRight: 20,
marginLeft: 20,
borderWidth: 0,
}}
placeholder={'search placeholder'}
onFocus={() => { console.log('onFocus: '); }}
onChangeText={(text) => { console.log('enter text: ', text); }}
onEndEditing={() => { console.log('endEditing: '); }}
/>
</LinearGradient>
</LinearGradient>

Related

What should I pass as a value to a prop expecting Animated.Value while using react-native-reanimated?

I created a hook to capture the react-native-pager-view carousel scroll position:
import { useEvent, useHandler } from 'react-native-reanimated';
import { AnimatedPagerScrollHookParams } from './animated-pager-scroll.type';
const useAnimatedPagerScroll = (
handlers: AnimatedPagerScrollHookParams['handlers'],
dependencies?: AnimatedPagerScrollHookParams['dependencies'],
) => {
const { context, doDependenciesDiffer } = useHandler(handlers, dependencies);
return useEvent(
event => {
'worklet';
const { onPageScroll } = handlers;
if (
onPageScroll &&
(
event as {
eventName: string;
}
).eventName.endsWith('onPageScroll')
) {
onPageScroll(event, context);
}
},
['onPageScroll'],
doDependenciesDiffer,
);
};
export default useAnimatedPagerScroll;
And then, I used it in my PagerView component like so:
<AnimatedPagerView
onPageScroll={handler}
style={{ flex: 1 }}
initialPage={0}
>
{slides.map((slide, index) => (
<View
key={index}
style={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<ImageBackground
testID="TestID__image-Onboarding"
source={slide.imageUrl}
style={{
width: '100%',
height: '100%',
justifyContent: 'flex-end',
}}
>
<LinearGradient
colors={['rgba(255,255,255,1)', 'rgba(255,255,255,0)']}
style={{
position: 'absolute',
left: 0,
right: 0,
top: 0,
height: '50%',
}}
/>
<Typography
testID="TestID__subtitle-Onboarding"
variant="h1"
color="alternateBasic"
style={{
marginBottom: 146,
marginLeft: 43,
width: index === slides.length - 1 ? '45%' : '35%',
}}
>
{slide.subtitle}
</Typography>
</ImageBackground>
</View>
))}
</AnimatedPagerView>
I am using a library called react-native-animated-pagination-dots. It animates based on the scroll position. It accepts a prop called scrollX which has to be of type Animated.Value. I am using react-native-reanimated
<ExpandingDot
data={slides}
expandingDotWidth={30}
scrollX={translationY.value}
inActiveDotOpacity={0.6}
dotStyle={{
width: 10,
height: 10,
backgroundColor: '#347af0',
borderRadius: 5,
marginHorizontal: 5,
}}
containerStyle={{
top: 30,
}}
/>
It throws an error if I pass a shared value which I can understand as it expects Animated.Value. What transformation can I perform to continue using react-native-reanimated and satisfy the condition of the library by passing the right prop?
Library List:
https://github.com/weahforsage/react-native-animated-pagination-dots
https://github.com/callstack/react-native-pager-view
https://docs.swmansion.com/react-native-reanimated/
Do as following and let me know it works or not:
scrollX={new Animated.value(translationY.value)}
I believe you need to pass the translationY directly (without .value):
<ExpandingDot
data={slides}
expandingDotWidth={30}
scrollX={translationY}
inActiveDotOpacity={0.6}
dotStyle={{
width: 10,
height: 10,
backgroundColor: '#347af0',
borderRadius: 5,
marginHorizontal: 5,
}}
containerStyle={{
top: 30,
}}
/>
Hope it helps.

Expo BlurView reacts too slowly(React Native)

If you look at other examples, you can see them reacting immediately.
But my code reacts slowly.
If you watch the video, you can see what I mean.(https://youtu.be/jo_iDDh2WBw)
Please tell me a solution to this.
Below is my code.
<SafeAreaView style={{...structure.safeViewContainer, backgroundColor: "#ffffff"}}>
<View style={{...structure.container}}>
<BlurView intensity={100} style={{...structure.headerBox}}>
<Header arrow={false} navigation={navigation} />
</BlurView>
<ScrollView style={{...structure.contentContainer, overflow: 'visible', backgroundColor: colors.lightGray}}>
<View style={structure.contentBox}>
<View style={{ right: 0, left: 0, backgroundColor: "#000000", height: 300, borderRadius: 20 }}></View>
<View style={{ right: 0, left: 0, backgroundColor: "#ffffff", height: 300, marginTop: 30, borderRadius: 20 }}></View>
<View style={{ right: 0, left: 0, backgroundColor: "#ffffff", height: 300, marginTop: 30, borderRadius: 20 }}></View>
<View style={{ right: 0, left: 0, backgroundColor: "#ffffff", height: 300, marginTop: 30, marginBottom: 55, borderRadius: 20 }}></View>
</View>
</ScrollView>
<View style={{ backgroundColor: colors.lightGray, right: 0, left: 0, height: 20, bottom: -20, position: "absolute" }}></View>
</View>
<TabBar navigation={navigation} />
</SafeAreaView>

OnScroll animation was not smooth on Android device

I want to freeze the customer profile component when user scrolling the page, so I set the scrollY value to translateY property to avoid the component from moving up. However, on android device, when the user scroll slightly faster, the component will become a little bit shaky even I have already added useNativeDriver: true.
Really APPRECIATE if anyone could help, was struggling for quite a number of days.
Below is the code for the entire screen:
const scrollY = React.useRef(new Animated.Value(0)).current;
<Animated.ScrollView
scrollEventThrottle={16}
automaticallyAdjustContentInsets={false}
contentContainerStyle={{ flexGrow: 1 }}
contentInsetAdjustmentBehavior="automatic"
bounces={false}
showsVerticalScrollIndicator={false}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{ useNativeDriver: true }
)}
>
<Animated.View
style={{
width: deviceWidth,
height: 250,
backgroundColor: 'lightgrey',
paddingHorizontal: 30,
justifyContent: 'center',
alignItems: 'center',
transform: [
{
translateY: scrollY
}
]
}}
>
<View
style={{
borderRadius: 100 / 2,
width: 100,
height: 100,
backgroundColor: 'white',
marginBottom: 20
}}
></View>
<Text style={{ marginBottom: 5, fontSize: 22 }}>Chris Groves</Text>
<Text style={{ fontSize: 30, fontWeight: 'bold' }}>$ 190.83</Text>
</Animated.View>
<View
style={{
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center'
}}
>
<View
style={{
height: 200,
width: 350,
backgroundColor: 'red',
marginVertical: 30
}}
/>
<View
style={{
height: 200,
width: 350,
backgroundColor: 'red',
marginBottom: 30
}}
/>
<View
style={{
height: 200,
width: 350,
backgroundColor: 'red',
marginBottom: 30
}}
/>
<View style={{ height: 200, width: 350, backgroundColor: 'red' }} />
</View>
</Animated.ScrollView>
Demo video for better understanding:
Demo Video

Component won't stay wrapped within bounds (React Native)

I am trying to make my own tab navigation like Instagram has instagram example. I noticed that the items within the footer view I made does not stay within the bounds and moves to the top left of the screen. Images shown - What I am trying to achieve What happens frequently
Here is the most important part of my code. I have done inline styles temporarily to try and figure out the issue. Here is the part where the issue lays <View style = {{ width: Dimensions.get('window').width, backgroundColor: '#fff', height: 80}} <TouchableOpacity onPress = {() => this.props.navigation.navigate('Profile')} style = {{justifyContent: 'flex-end'}}>
<Text style = {{justifyContent: 'flex-end'}}> Profile </Text>
</TouchableOpacity> </View>-
render() {
return (
<MapView style = {[style.container, style.map]}
region = {this.state.initialPosition}>
<MapView.Marker coordinate = {this.state.markerPosition}>
<View style = {style.radius}>
<View style = {style.marker}/>
</View>
</MapView.Marker>
<View style = {{ width: Dimensions.get('window').width, backgroundColor: '#fff', height: 80}} >
<TouchableOpacity onPress = {() => this.props.navigation.navigate('Profile')} style = {{justifyContent: 'flex-end'}}>
<Text style = {{justifyContent: 'flex-end'}}> Profile </Text>
</TouchableOpacity>
</View>
</MapView>
);
}
}
const style = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-end',
//alignItems: 'center',
},
text: {
color: '#fff'
},
map: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute'
},
radius:{
height: 50,
width: 50,
borderRadius: 50 / 2,
overflow: 'hidden',
backgroundColor: 'rgba(1,213,106,0.3)',
borderWidth: 1,
borderColor: 'rgba(1,213,106,0.3)',
alignItems:'center',
justifyContent: 'center'
},
marker: {
height: 20,
width: 20,
borderWidth: 3,
borderColor: '#fff',
borderRadius: 20 / 2,
borderWidth: 3,
overflow: 'hidden',
backgroundColor: '#01D56A'
},
menuSection: {
backgroundColor: 'rgba(255, 255, 255, 0.7)',
width: Dimensions.get('window').width,
height: Dimensions.get('window').height/3,
justifyContent: 'flex-end',
alignItems: 'center'
},
icon:{
width: 50,
height: 50,
backgroundColor: 'black'
}
})

text Align :'right' doesn't work for placeholder when multiline is true

In my code i have 2 textInputs, one has one line and the other has multiple lines, the input is arabic so i have to enable textAlign: 'right',
my problem is when i set multilines to true, the placeholder text remains on the left side of the text input,
any idea how to solve this?
my code is the following:
View:
<View style={{ position: 'relative' }}>
<TextInput
style={forms.textInput}
value={this.state.telephone}
placeholder={'رقم هاتفك'}
placeholderTextColor={'rgba(0,0,0,0.6)'}
onChangeText={(val) => this.setState({telephone: val}) } />
<Icon name="android-phone-portrait" size={27} color="rgba(0,0,0,0.6)" style={{ position: 'absolute', top: 10, right: 24 }}/>
</View>
<View style={{ position: 'relative' }}>
<TextInput
style={[forms.textInput,{height: 120}]}
multiline={true}
value={this.state.desc}
numberOfLines={4}
placeholder={'اقتراحك'}
placeholderTextColor={'rgba(0,0,0,0.6)'}
onChangeText={(val) => this.setState({desc: val}) }/>
<Icon name="ios-help-outline" size={27} color="rgba(0,0,0,0.6)" style={{ position: 'absolute', top: 10, right: 24 }}/>
</View>
Style:
textInput: {
height: 40,
borderColor: 'rgba(0, 0, 0, 0.4)',
borderWidth: 2,
margin: 15,
marginTop: 5,
backgroundColor: '#fff',
color: 'rgba(0, 0, 0, 0.9)',
paddingRight: 40,
textAlign :'right'
},
______________________*******________________________
______________________*******________________________
I have actually made a pull request for this which has been accepted and will be in the 0.29.0 release of react-native.
My fix was to add this line
_placeholderView.textAlignment = _textView.textAlignment;
to react-native/Libraries/Text/RCTTextView.m
Inside the updatePlaceholder function (right before [self insertSubview:_placeholderView belowSubview:_textView];)
GitHub Commit