Different UI Design behaviour in react-native (expo) - android

I'M creating ui in expo application using react-native-paper. The UI is getting different for android and iOS platform for Account Screen. However, i tried same code in Snack and it show correct ui in web.
This is ios UI
This is android UI
In Android, some part of ui is hidden.
Snack Code Link
I need look like ios device screenshot have in android.

Here is demo: https://snack.expo.io/#nomi9995/45f132
You should make parent view inside ScrollView and wrap ImageBackground and View
inside this parent view
import React, { useState, useContext } from "react";
import {
SafeAreaView,
View,
ScrollView,
Dimensions,
ImageBackground,
Alert,
} from "react-native";
import { FontAwesome, MaterialIcons } from "#expo/vector-icons";
import { TextInput, Button } from "react-native-paper";
import Constants from "expo-constants";
export default function App() {
const SCREEN_HEIGHT = Dimensions.get("window").height;
const SCREEN_WIDTH = Dimensions.get("window").width;
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView style={{ flex: 1, height: SCREEN_HEIGHT }}>
<View style={{ flex: 1, height: SCREEN_HEIGHT }}>
<ImageBackground
source={{
uri:
"https://firebasestorage.googleapis.com/v0/b/ielts-preps.appspot.com/o/1592920135765?alt=media&token=ec911583-06f9-4315-b66c-cf47de120e85",
}}
style={{ width: SCREEN_WIDTH, height: SCREEN_HEIGHT * 0.4 }}
>
<View
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "flex-start",
margin: 20,
}}
>
<FontAwesome name="close" size={30} color="#fff" />
<MaterialIcons name="edit" size={30} color="#fff" />
</View>
</ImageBackground>
<View
style={{
height: SCREEN_HEIGHT * 2,
width: SCREEN_WIDTH * 0.9,
backgroundColor: "red",
position: "absolute",
left: (SCREEN_WIDTH - SCREEN_WIDTH * 0.9) / 2,
top: SCREEN_HEIGHT * 0.3,
zIndex: 1,
elevation: 10,
}}
>
<TextInput
label="First Name"
value=""
mode="flat"
onChangeText={(text) => {}}
style={{ margin: 20, backgroundColor: "#fff" }}
/>
<TextInput
label="Last Name"
value=""
mode="flat"
onChangeText={(text) => {}}
style={{ margin: 20, backgroundColor: "#fff" }}
/>
<Button
style={{
marginHorizontal: 50,
marginVertical: 20,
backgroundColor: "#0af",
padding: 10,
}}
mode="contained"
onPress={() => {}}
>
Update
</Button>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}

Related

React-Native: Pressing on the keyboard (textInput) causes the header to slide off the screen. How can it be kept in the same position?

Currently, I'm getting the page this way after pressing on text input (notice there's no header, since it's popped out of the screen):
I want it to be like this (even if I press on text input, HEADER should remain in the same position):
I'm using this in the android manifest:
android:windowSoftInputMode="adjustPan"
Here's my code:
import React from 'react';
import {
View,
Dimensions,
TextInput,
ScrollView,
StatusBar,
Text,
KeyboardAvoidingView,
} from 'react-native';
const {width, height} = Dimensions.get('window');
const Conversation = ({}) => {
return (
<>
<StatusBar hidden />
<View
style={{
backgroundColor: 'gray',
height: 50,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text center style={{color: 'white'}}>
Header
</Text>
</View>
<KeyboardAvoidingView behavior="padding" style={{flex:1}}>
<TextInput
style={{
backgroundColor: 'white',
borderWidth: 1,
height: 50,
marginHorizontal: width * 0.1,
top: height * 0.9,
}}
/>
</KeyboardAvoidingView>
</>
);
};
export default Conversation;
You just need to remove top: height * 0.9 and place your content inside ScrollView.
import React from 'react';
import {
View,
Dimensions,
TextInput,
ScrollView,
StatusBar,
Text,
FlatList,
KeyboardAvoidingView,
} from 'react-native';
const { width, height } = Dimensions.get('window');
const Conversation = ({ }) => {
return (
<>
<StatusBar hidden />
<View
style={{
backgroundColor: 'gray',
height: 50,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text center style={{ color: 'white' }}>
Header
</Text>
</View>
<KeyboardAvoidingView behavior="padding" style={{ flex: 1 }}>
<ScrollView>
</ScrollView>
<TextInput
style={{
backgroundColor: 'white',
borderWidth: 1,
height: 50,
marginHorizontal: width * 0.1
}}
/>
</KeyboardAvoidingView>
</>
);
};
export default Conversation

ScrollView horizontal pagination only works on Android doesn't work on IOS react native expo cli

Everyone.
I need your help.
I made one app with react native expo cli.
But one issue occurred.
I used the ScrollView for horizontal pagination.
*<SafeAreaView>
<ScrollView
snapToInterval={wp("100%")}
horizontal
pagingEnabled
nestedScrollEnabled
decelerationRate="fast"
>
{[...Array(this.state.pageCount)].map((num, index) => {
return (
<View
key={"view" + index}
style={{
width: wp("100%"),
height: "100%",
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
alignContent: "center",
justifyContent: "center",
}}
>
{this.state.categories
.slice(index * 6, index * 6 + 6)
.map((item, key) => (
<TouchableOpacity
key={"touch" + key}
style={styles.itemStyle}
onPress={() => this.openModal(item)}
onLongPress={() => this.selectItem(item)}
>
<Image
source={{ uri: item.Foto }}
style={{ height: 120, width: "90%" }}
resizeMode="cover"
/>
<Text style={{ fontSize: 18 }}>{item.Precio}</Text>
<Text style={{ fontSize: 12 }}>{item.Gemas}</Text>
</TouchableOpacity>
))}
</View>
);
})}
</ScrollView>
</SafeAreaView>*
But the pagination only works on Android Phone and doesn't work on iPhone.
Please help me.
Your <ScrollView> should have style flex: 1, to allow the view fit the screen size.
The width of the Views inside the Scroll should have a numerical value. A width of 100% inside a scrollview is undefined. Your approach should be related to the dimension of the screen.
// import dimensions lib
import Dimensions from 'react-native';
...
...
...
// capture the width of the screen
const screenWidth = Dimensions.get('screen').width;
...
...
...
{[...Array(this.state.pageCount)].map((num, index) => {
return (
<View
key={"view" + index}
style={{
width: screenWidth,
height: "100%",
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
alignContent: "center",
justifyContent: "center",
}}
>
{this.state.categories
.slice(index * 6, index * 6 + 6)
.map((item, key) => (
<TouchableOpacity
key={"touch" + key}
style={styles.itemStyle}
onPress={() => this.openModal(item)}
onLongPress={() => this.selectItem(item)}
>
<Image
source={{ uri: item.Foto }}
style={{ height: 120, width: "90%" }}
resizeMode="cover"
/>
<Text style={{ fontSize: 18 }}>{item.Precio}</Text>
<Text style={{ fontSize: 12 }}>{item.Gemas}</Text>
</TouchableOpacity>
))}
</View>
);
})}

Add "radius" to bottom side of image

This is design that I want to implement for my mobile application:
And this is what is currently accomplished to implement:
Implemented design
As you can see folowing some online examples i manage to curve the picture but its curved on both ends instead of just on the bottom.
This is my style code:
const mainStyle = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
backgroundColor: "#d3c586",
alignItems: "center",
justifyContent: "space-between",
},
cardContainer: {
flex: 1,
alignSelf: "center",
backgroundColor: "#d3c586",
alignItems: "center",
justifyContent: "space-between",
overflow: "hidden",
},
cardImageContainer: {
flex: 0.6,
borderRadius: width,
width: width,
height: width,
bottom: 0,
overflow: 'hidden',
},
cardImage: {
height: height / 2,
width: width,
bottom: 0,
marginLeft: 0,
}};
This is a list of items that can be swiped and i render it from this function:
renderItem ({item, index}) {
return (
<View style={mainStyle.cardContainer}>
<View style={mainStyle.cardImageContainer}>
<TouchableOpacity onPress={(event) => this.handleDoubleTap(item)} onLongPress={(event) => this.handlePictureShare(item)}>
<LoadImage style={mainStyle.cardImage} source={{uri: item.url}} thumbnailSource={{uri: item.url}}/>
</TouchableOpacity>
</View>
<View style={mainStyle.cardTextContainer}>
<Text numberOfLines={25} style={{fontSize: 19}}>{item.fact}</Text>
</View>
</View>
)
}
I do not have a lot of experience with CSS since most of my work is on the backend.
Check these links BorderBottomLeftRadius BorderBottomRightRadius
This way you can only give radius bottom of your image.
You can try like this:
import React, { Component } from 'react';
import { View } from 'react-native';
export default class FlexDirectionBasics extends Component {
render() {
return (
// Try setting `flexDirection` to `column`.
<View style={{flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center'}}>
<View style={{width: 100, height: 100, backgroundColor: 'steelblue', borderBottomColor: 'black', borderBottomEndRadius: 10, borderBottomStartRadius: 10 }} />
</View>
);
}
}

React Native showing text twice in Apple, Once in Android

I have a react native code, using expo, with a graph with text. In Apple, this application is showing it twice. In Android, once.
Here is the code:
import { ScrollView, StyleSheet, Text, View, Alert, Dimensions } from 'react-native';
...
// Charts
import * as scale from 'd3-scale'
import { ProgressCircle, LineChart, XAxis, Grid } from 'react-native-svg-charts';
.... <Other Code> ...
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={{ padding: 10 }}>
<ProgressCircle
style={{ height: 150, width: 150 }}
startAngle={-Math.PI * 0.5}
endAngle={Math.PI * 0.5}
progress={this.state.perFirstTier}
progressColor={constants.BGC_GREEN}
strokeWidth={10}>
{* THIS IS WHAT IS DOUBLED*}
<Text key ='percentage' style={{
position: "absolute",
marginLeft: 65, marginTop: 50
}}>{(this.state.perFirstTier * 100).toFixed(0)}%</Text>
</ProgressCircle>
<View style={{ marginTop: -40, flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.description}>{i18n.t('activityDashboard.firstGoalDesc')}</Text>
{/* Show colored badge if 100%*/}
{this.state.perSecondTier == 1
? <Image style={styles.medalImage} source={require('../../utils/images/silver_medal.png')}></Image>
: <Image style={styles.medalImage} source={require('../../utils/images/grey_medal.png')}></Image>
}
</View>
</View>
Here is an image comparison of Apple versus Android:
Why is this happening, and how can I make it only show once?
Because progress is already declared in the ProgressCircle component, and it's rendered inside it. Just remove the Text component from the ProgressCircle. I guess it has overflow hidden on Android so it's not displayed there.
if all else fails, try adding a rendering condition for iOS platform.
<ProgressCircle
style={{ height: 150, width: 150 }}
startAngle={-Math.PI * 0.5}
endAngle={Math.PI * 0.5}
progress={this.state.perFirstTier}
progressColor={constants.BGC_GREEN}
strokeWidth={10}
>
{/* THIS IS WHAT IS DOUBLED */}
{Platform.OS === 'ios'
? <View />
: (
<View>
<Text
key ='percentage'
style={{
position: "absolute",
marginLeft: 65,
marginTop: 50
}}
>
{(this.state.perFirstTier * 100).toFixed(0)}%
</Text>
</View>
)
}
</ProgressCircle>
I had a similar issue trying to render YAxis as < Text > on iOS14. I used < Text > because had a hard time using YAxis for putting the label at the top of the chart bar.
My specs:
{
"expo": "~39.0.2",
"react-native-svg-charts": "^5.4.0",
"react-native-svg": "12.1.0"
}
Code:
const Values = ({ x, y, data }) => {
return (
data.map((value, index) => {
return (
<Text
key={index}
style={{
color: '#6e6969',
fontSize: 10,
position: 'absolute',
left: x(index) + 1,
top: y(value) - 15
}}
>
{value}
</Text>
)
})
)}
<BarChart
style={styles.chart}
data={data.plot}
spacing={0.2}
svg={{ fill: 'rgba(134, 65, 244, 0.8)' }}
contentInset={{ top: 20, bottom: 20, left: 0, right: 0 }}
>
<Values />
</BarChart>
<XAxis
style={{ marginHorizontal: -10 }}
data={data.plot}
formatLabel={(value, index) => data.labels[index]}
contentInset={{ left: 30, right: 30 }}
svg={{ fontSize: 10, fill: colors.medium }}
/>
Result
What I needed to do was wrapper the < Text > into a < View > and the issue was solved:
Changed code:
const Values = ({ x, y, data }) => {
return (
data.map((value, index) => {
return (
<View key={index}>
<Text
style={{
color: '#6e6969',
fontSize: 10,
position: 'absolute',
left: x(index) + 1,
top: y(value) - 15
}}
>
{value}
</Text>
</View>
)
})
)}
Result
Both codes worked fine on Android, though.

React Native: Undefined is not a function(evaluating this.props...)

I'm trying to a implement a logic to display some data fetched from a simple REST API. So i'm grabbing the JSON object in the RanjoorExplore class and the data is sent into the data to the ExploreCard in the other class. So the this.props.data must be referencing the passed variable. By mapping that variable, I'm displaying the title attribute of the response object in a simple Text Component.
I'm facing this error:
undefined is not a function(evaluating this.props.data.map).
RanjoorExplore:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
ScrollView,
Alert
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import ExploreCard from '../../elements/cards/ExploreCard';
import ExploreHeader from '../../elements/headers/ExploreHeader';
class RanjoorExplore extends Component {
constructor(){
super();
this.state = {
rawData: []
}
}
static navigationOptions = {
header: null,
title: 'Explore',
tabBarIcon: ({ tintColor, focused }) => (
<Icon
name="bandcamp"
size={24}
color={focused ? '#4ab367' : 'white'}
/>
),
headerStyle: { backgroundColor: '#202026' },
headerTitleStyle: {
color: 'white'
}
};
fetchGanjoorData() {
return fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((responseJson) => {
this.setState({rawData: responseJson})
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
this.fetchGanjoorData();
}
render() {
return (
<View style={styles.ExploreContainer}>
<ExploreHeader />
<ScrollView>
<ExploreCard data={this.state.rawData} />
</ScrollView>
</View>
);
}
}
var styles = StyleSheet.create({
ExploreContainer: {
backgroundColor: '#303036',
height: '100%',
width: '100%'
},
})
export default RanjoorExplore
ExploreCard:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
Alert
} from 'react-native';
import { Card, ListItem, Button, Icon, Avatar } from 'react-native-elements';
export default class ExploreCard extends Component {
render() {
/* Mapped data will be processed right here */
let mappedData = this.props.data.map(function (data1) {
return (
<View>
{data1.title}
</View>
)
})
return (
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1 }}></View>
<Card
containerStyle={{
width: '85%', height: 250, backgroundColor: '#202026', shadowOpacity: 0.7,
shadowOffset: { height: 5 }, shadowColor: 'black', borderWidth: 0, borderRadius: 8, flexDirection: 'row'
}}
wrapperStyle={{ alignSelf: 'flex-end' }} >
<View style={{ flex: 2, alignSelf: 'flex-end' }}>
<View style={{ flexDirection: 'row', alignSelf: 'flex-end' }}>
<Text style={{ fontFamily: 'IRANSans', marginRight: 5, marginTop: 12, color: '#505056' }}>حافظ</Text>
<Avatar
medium
rounded
source={require('../../img/avatars/ferdowsi.jpg')}
containerStyle={{
alignSelf: 'flex-end', marginRight: 15,
shadowOpacity: 0.7,
shadowOffset: { height: 5 }, shadowColor: 'black'
}}
/>
</View>
<View>
<Text style={{ alignSelf: 'flex-end', fontFamily: 'IRANSans', color: 'white', marginTop: '10%', marginRight: '5%' }}>
{mappedData}
</Text>
<Text style={{ alignSelf: 'flex-start', fontFamily: 'IRANSans', color: 'white' }}>
تا دمی برآساییم زین حجاب ظلمانی
</Text>
</View>
</View>
<View style={{ alignSelf: 'flex-end', backgroundColor: 'transparent', flexDirection: 'row' }}>
<Icon
name='favorite' size={24} color="#34343a" style={{ marginLeft: 5 }}
/>
<Icon
name='grade' size={24} color="#34343a" style={{ marginLeft: 5 }}
/>
<View>
<Button
textStyle={{ fontSize: 15 }}
iconRight
backgroundColor='#4ab367'
fontFamily='IRANSans_UltraLight'
buttonStyle={{
height: 15, width: 110,
borderRadius: 8
}}
title='ادامه مطلب'
/>
</View>
</View>
</Card>
<View style={{ flex: 1 }}></View>
</View>
);
}
}
Can someone please help me solve this issue?
Thanks in advance.
https://jsonplaceholder.typicode.com/posts/1 returns an object, not an array. Therefore, map is not a valid operation
Perhaps you meant to use https://jsonplaceholder.typicode.com/posts/? That returns an array

Categories

Resources