I am working on a settings screen design for this startup and am very new to react native. I am an intern, but I am trying to add lines between each button. I'll attach a screenshot of what it should kind of look like, but I just am lost with no matter how much I look up, I can't find something that will work for me.
So far what I did was:
<View className="w-full mt-2 mb-7 flex-row">
<TouchableOpacity onPress={() => navigation.navigate(RouteName.home)} className="flex flex-row items-center space-x-3 w-24">
<Ionicons name='person-sharp' size={24} color="grey"></Ionicons>
<Text>Profile</Text>
<AntDesign name='right' size={24} color='#7A7A7A' style={{position: 'absolute', right: 0}}></AntDesign>
</TouchableOpacity>
</View>
I dont have a specific stylesheet connected to it other than the inline one.
I attached a picture of what it should look like, but I am mainly struggling on the line between each button.
Related
Here is my code, it works for the code that was already entered well. But I want to be able to just input some additional data on the go while it's working. We have a web version that does this. But how to do this with react native? I am not really sure that sectionedmultiselect is capable of this anyway.
<View style={styles.input}>
<Text style={styles.header}>Rakip Firma :</Text>
<SectionedMultiSelect
onToggleSelector={() => enemyList()}
items={itemsEnemy}
IconRenderer={Icon}
uniqueKey="id"
subKey="children"
selectText="Rakip seçin"
showDropDowns={true}
readOnlyHeadings={true}
onSelectedItemsChange={onSelectedEnemyChange}
selectedItems={selectedEnemy}
searchPlaceholderText="Ara.."
confirmText="Onayla"
selectedText="ürün seçildi"
colors={{ chipColor: 'blue', disabled: 'blue' }}
expandDropDowns={true}
/>
</View>
I am using Expo for my app. I have a horizontal Flatlist where I render my data react native paper's Card. I saw Card have onPress function. I used that to navigate the another page. But onPress function does not trigger on Android device. I know React native's touchable-opacity have positioning issue on Android. I tried hitSlop and inline styling zIndex but still does not work. I also wrap my card with react-native's touchable-opacity and play with positioning still did not help me, only it works when i used react-native-gesture-handler's touchable-opacity but then it does not work on IOS. Hope anyone can help me...
import React from 'react';
import { Card } from 'react-native-paper';
import { useNavigation } from '#react-navigation/native';
interface Iprops {
item: string;
}
export default function RenderCard({ item }: Iprops) {
const navigation = useNavigation();
return (
<Card
hitSlop={{ "bottom": 30, "top": 30, "right": 30, "left": 30 }}
onPress={() => {
navigation.navigate(`detail`, { // THIS DOES NOT TRIGGER ON ANDROID
"id": `${item.pk}`
});
}}
style={{ "marginBottom": 20 }}>
<Card.Cover
source={{ "uri": `${item.img_url}` }} />
<Card.Actions>
<Card.Title title={item.name} subtitle="Card Subtitle" />
</Card.Actions>
</Card>
);
}
I've noticed that using onPressIn or onPressOut does work on Android within an absolute positioned flatlist, but onPress does not work. I hope this might be of help to someone out there looking for an answer.
You'll need to use the TouchableOpacity element from react-native-gesture-handler.
Like you told, you should add touchable opacity to the element you are rendering on the card. TouchableOpacity can be tricky. So, first give it a styling of borderWidth:1 and borderColor to see the actual touchable area on the screen. Then you start to bring them together with the icon or the image or whatever you are rendering. TouchableOpacity works but the positioning can be tricky. You have to understand it to use it better. Think touchableOpacity as a view with borders then it'll be easier to grasp. Also, if you dont give touchableOpacity an absolute position in the styling it will be out of the screen somewhere, I was never be able to bring it to somewhere that I can see to position it. So you can add 'position' as well.
I gave up on positioning and render my component's based on Platform.
Platform.OS === `ios` ?
<Card
onPress={() => {
navigation.navigate(`detail`, {
"id": `${item.pk}`
});
}}
style={{ "marginBottom": 20 }}>
<Card.Cover source={{ "uri": `${item.img_url}` }} />
<Card.Actions>
<Card.Title title={item.name} subtitle="Card Subtitle" right={Beer} />
</Card.Actions>
</Card> :
<TouchableOpacity
onPress={() => {
navigation.navigate(`detail`, {
"id": `${item.pk}`
});
}}
>
<Card style={{ "marginBottom": 20 }}>
<Card.Cover source={{ "uri": `${item.img_url}` }} />
<Card.Actions>
<Card.Title title={item.name} subtitle="Card Subtitle" right={Beer} />
</Card.Actions>
</Card>
</TouchableOpacity>;
I have a component that renders a WebView along with a Text component at the top and bottom of the screen:
return (
<Container>
<Text>TEXT TOP</Text>
<WebView source={{uri: url}} />
<Text>TEXT BOTTOM</Text>
</Container>
);
The issue that I am facing is that the "TEXT TOP" does not appear the first time I navigate to the specific component, while the "TEXT BOTTOM" appears just fine. In order to make the top text appear, I need to do one of the following:
Navigate to another component and come back
Change the phone's orientation
Interact with the WebView (scroll or press on an input field)
I have tried with both the WebView component from 'react-native' and also from 'react-native-webview' without managing to change the behaviour.
I have this example it renders both text on top and bottom along with webview in
middle.Hope it helps.Run this code on expo snack and view it on your device.
import * as React from 'react';
import { Text, View, StyleSheet, WebView } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
Change code in the editor and watch it change on your phone! Save to
get a shareable url.
</Text>
<WebView source={{ uri: 'https://github.com/facebook/react-native' }} />
<Text style={styles.paragraph}>
Change code in the editor and watch it change on your phone! Save to
get a shareable url.
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
I had a similar issue. Any components above the WebView would not render and couldn't be forced to render until the WebView had finished loading.
I was able to work around this by having the WebView load a local html resource (source = require('xxx')). Then implement the WebView's onLoadEnd to flip a component state variable to load the real URI you want to show.
It seems that the layout of the screen is delayed or otherwise impeded by the first load of the WebView. I don't know if the first page being local causes the engine to compute the layout inline since it doesn't need to wait on an asynchronous fetch result.
Why the layout of the screen would need to change based on the contents of the WebView is unclear to me. Perhaps it just looks like that's what's happening.
Place all other content below the WebView and position using absolute.
I have been trying to resolve this issue for a while and found that this solution works like a charm!
<WebView source={{uri: url}} style={{ marginTop: 60 }} />
<Text style={{ position: 'absolute', top: 0, height: 60 }}>TEXT TOP</Text>
<Text>TEXT BOTTOM</Text>
The problem is pretty simple, still I can't figure out why it happens. I'd need some good Android and/or React Native developers.
I have a settings page in my application which renders 4 boxes (depending content of the settings, like user password, email modification...) and one of them has a bit much more content than the others.
The problem seems to only occur on Android 7.0 (testing with a real device, Honor 8) and it works well on One Plus 6 (8.1) and a Xiaomi (I don't know which one, running 7.1)
As long as I want to display all the content of the box, it will just not render to the screen, but still takes the height needed in the ScrollView to be displayed (see the screens)
At first, I didn't understand why, because no error was triggered, I decided to check the logCats and I got this error :
View: ReactViewGroup not displayed because it is too large to fit into a software layer (or drawing cache), needs 8636760 bytes, only 8294400 available
Imgur
So I tried multiple things:
set android:hardwareAccelerated="false" in the AndroidManifest, this solution works BUT the app is quite laggy when you scroll, and all is a bit slowed down (I would love to avoid this)
Delete some components from the render, which also works, but... obviously, I want all my content in this box
I tried to understand which component takes a lot of space (in bytes) by adding/deleting the components in the view and referring to the logCat, seems like ZestInput takes quite a lot, as custom components for Toggles, and Checkboxes (I also tried with native TextInput to compare with our custom input, the result was not that far... they bot take a lot of space)
render() {
const {
textStyle,
titleTextStyle,
subtleText,
boxStyle,
marginLarge,
marginSmall,
marginLeft,
buttonStyle,
} = styles;
const { isUpdating, newMail } = this.state;
const { user, emailEdition } = this.props;
const emailTranslation =
newMail === ''
? translations.t('ADD_EMAIL')
: translations.t('CHANGE_EMAIL');
return (
<MCollapsableBox
style={boxStyle}
headerText={translations.t('APPLICATION_SETTINGS')}
>
<View>
<Text style={[titleTextStyle, marginLarge]}>
{translations.t('PARAMETERS_CHOOSE_LANGUAGE')}
</Text>
{(newMail === '' || emailEdition) && (
<View>
<Separation />
<Text style={[titleTextStyle, marginLarge]}>
{translations.t('EMAIL')}
</Text>
<ZestInput
//ref={ref => (this.inputRef = ref)}
placeholder={emailTranslation}
onChangeText={this.changeMailAddress}
value={newMail}
/>
{user.tmpEmail !== '' && (
<View>
<Text style={[textStyle, marginSmall]}>
{translations.t('CURRENT_TMP_MAIL')}
</Text>
<Text style={[textStyle, marginLeft]}>{user.tmpEmail}</Text>
<Text style={[subtleText, marginLeft]}>
{translations.t('EMAIL_NEEDS_VALIDATION')}
</Text>
</View>
)}
<PrimaryButton
onPress={this.onChangeEmail}
style={buttonStyle}
isLoading={isUpdating}
disabled={!this.checkIsEmail(newMail)}
>
{emailTranslation}
</PrimaryButton>
</View>
)}
<Separation />
<Text style={[titleTextStyle]}>
{translations.t('PARAMETERS_VISIBILITY')}
</Text>
{_.map(this.state.privacyOptions, (value, key) => {
return (
<TitledTextToggle
title={value.text}
options={value.options}
onPress={this.toggleChanged}
key={key}
id={key}
/>
);
})}
<Separation />
<Text style={[titleTextStyle, marginSmall]}>
{translations.t('MOOD_NOTIFICATIONS_SETTINGS')}
</Text>
<Text style={[textStyle, marginLarge]}>
{translations.t('MOOD_NOTIFICATIONS_SETTINGS_TEXT')}
</Text>
<CheckboxList
onPress={this.onPressCheckbox}
options={this.state.moodNotification}
/>
<PrimaryButton
onPress={this.onSave}
style={buttonStyle}
isLoading={isUpdating}
>
{translations.t('SAVE')}
</PrimaryButton>
</View>
</MCollapsableBox>
);
}
This is what I expect
Imgur
Imgur
Imgur
I am working on a react native app which involves a video player (react-native-video), and some simple controls I set up myself. on iOS this works fine, but on Android the TouchableOpacity elements, which I use for controls and navigation, don't seem to detect touches. (Navigation is handles by react-native-fluid-transitions in my app). When I turn on the inspector, a screen-covering View seems to be on top of my controls. However, this is not the case on iOS and I have also not configured such a view.
I installed Atom to use it's inspector feature to see the actual order of my views. It looks as follows:
VideoView is the name of my component, Video is the actual video player and the TouchableOpacity I highlighted is the button I'm trying to get to work. In this view hierarchy, no views seem to be on top of anything. I have also compared this breakdown to other components where my buttons actually work and it looks the same.
My code looks as follows:
return (
<View style={internalStyles.container}>
<Video style={internalStyles.videoContainer}
ref={(ref) => {
this.props.player = ref
}}
source={{uri: url}}
controls={false}
onEnd={() => this.videoEnded()}
paused={this.state.paused}
muted={false}
repeat={false}
resizeMode={"contain"}
volume={1.0}
rate={1.0}
ignoreSilentSwitch={"obey"}
/>
{this.renderControls()}
{Renderer.getInstance().renderNavigationButton()}
</View>
);
where renderControls is a function that renders the pause button, and Renderer is a singleton component containing render function for items I use in more components of my app. This all works fine on iOS, but not on Android. react-native-video seems to be incompatible with react-native-fluid-transitions as everything works when I remove one of either.
Does anyone know what might cause this behavior? Any help would be highly appreciated.
Try removing the activeOpacity prop from TouchableOpacity component.
Or you can use platform specific code to set values for activeOpacity prop
import { Platform, TouchableOpacity } from 'react-native'
<TouchableOpacity
activeOpacity={Platform.OS==='android' ? 0 : 0.2}
>
<Text>submit</Text>
</TouchableOpacity>
Wrap the component in a view and disable pointer events.
<View pointerEvents="none">
<Video source={{ uri: source }} />
</View>
import {TouchableOpacity} from 'react-native';
<TouchableOpacity>some text</TouchableOpacity>
For me it was solved by putting zIndex:1000
<TouchableOpacity
onPress={this.handlePause}
style={{
position: "absolute",
alignItems: "center",
justifyContent: "center",
alignSelf: "center",
elevation: 2,
backgroundColor: "#FFF",
width: 60,
height: 60,
borderRadius: 30,
flex: 1,
zIndex: 1000,
}}
>