react native custom picker set style not working - reactjs

I developing a react native project.
I use react-native-custom-picker but when I try gives a Custom Picker style it's not working. my code like this below
//.. in CustomPicker.js
<CustomPicker
placeholder={labelDefault}
options={options}
getLabel={item => item.label}
optionTemplate={this.renderOption}
selectedValue={this.props.selectedValue}
onValueChange={this.onValueChangeCustomPicker}
textStyle={{color:colors.dark_black,fontSize:25}}--> Here is not work
/>
renderOption() function like this
renderOption(settings) {
const { item, getLabel } = settings
return (
<View style={styles.optionContainer}>
<View style={styles.innerContainer}>
<Text style={{ color: colors.dark_black, alignSelf: 'flex-start', fontSize: 24 }} key={item.key}>{item.label}</Text>
</View>
</View>
)
}
I know Picker style only support IOS.
What's my fault? Any idea!

can you try this code?
I don't know how you organized "options," but you can't work because you don't have any place to take the factors for "colors."
renderOptions:
const options = [
...
color: "black",
]
...
renderOption(settings) {
const { item, getLabel } = settings
return (
<View style={styles.optionContainer}>
<View style={styles.innerContainer}>
<Text style={{ color: item.color, alignSelf: 'flex-start', fontSize: 25 }} key={item.key}>{item.label}</Text>
</View>
</View>
)
}
<CustomPicker
placeholder={labelDefault}
options={options}
getLabel={item => item.label}
optionTemplate={this.renderOption}
selectedValue={this.props.selectedValue}
onValueChange={this.onValueChangeCustomPicker}
/>

I checked source code and documentation if I wanna give style placeholder I should use props for field template like this.
<CustomPicker
fieldTemplateProps={{textStyle:{color:"red",fontSize:22}}}
placeholder={'Please select your favorite item...'}
options={options}
getLabel={item => item.label}
optionTemplate={this.renderOption}
headerTemplate={this.renderHeader}
onValueChange={value => {
Alert.alert('Selected Item', value ? JSON.stringify(value) : 'No item were selected!')
}}
/>
it's worked in my project
more detail

Related

the style does not work on images (Image) how can I fix it?

the style does not work on images (Image); how can I fix it?
For example, style 2-card is applied without an image
but when I add images, the style changes, I don't understand why.
Icons are visible on Card-2, but after adding an image on card-1, the photo closes the icons
export default class Cards extends Component{
render(){
return(
<View style={{...styles.container, backgroundColor:this.props.bg }}>
<View style={styles.col}>
<Image
style={styles.col}
source={this.props.imageUri}
/>
<Icon
name={this.props.icon}
size={30}
color={this.props.bg == "red" ? "red":"red"}
/>
<TouchableOpacity onPress={this.props.onPress}>
<Icon2
style={{marginLeft:50}}
name="dots-vertical"
size={30}
color="red"
/>
</TouchableOpacity>
</View>
<Text style={styles.title}>{this.props.title}</Text>
<Text style={{
...styles.number,
color: this.props.bg == "red" ? "#FFF":"#000",
}}>
{this.props.number}
</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container:{
height:200,
width:130,
borderRadius:30,
padding:15,
marginLeft:20
},
col: {
flexDirection:"row"
},
title:{
marginTop:90,
color:"#b8b8aa",
fontWeight:"bold",
fontSize:12
},
number:{
fontWeight:'bold',
fontSize:22
}
})
example
I have created a sample based on your code.
Basically overflow: 'hidden' of the container did the trick

Why is my Text Input getting activated only at the width of PlaceHolder?

I am building an Android specific app using React-Native.
In this app I am trying to build a custom TextInputField which can be re-used. This is my Custom Function Component
function AppTextInput({ icon, ...otherProps }) {
return (
<View style={styles.container}>
{icon && (
<MaterialCommunityIcons
name={icon}
size={20}
color={colors.medium}
style={styles.icon}
/>
)}
<TextInput style={customStyles.text} {...otherProps} />
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: colors.light,
borderRadius: 25,
flexDirection: "row",
width: "100%",
padding: 15,
marginVertical: 10,
},
icon: {
margin: 3,
marginRight: 7,
},
});
export default AppTextInput;
I call this component from my App.js like so
<AppTextInput
autoCapitalize="none"
autoCorrect={false}
icon="email"
keyboardType="email-address"
placeholder="Email"
/>
The issue here is, this field is set-to focus only when I touch on the width occupied by placeholder text and not the entire text field. What am I doing wrong?
The focus effect will only happen when you press on the text input itself, and if you give it a background color you will find out that your text input is small and the pressable area that will trigger the focus effect is small (Only the text input area)
The solution is to make the whole View that contain the input and the icon trigger the focus via useRef like this:
export default function AppTextInput({ icon, ...otherProps }) {
const textInput = React.useRef(null);
function handleClick() {
textInput.current.focus();
}
return (
<Pressable style={styles.container} onPress={handleClick}>
{icon &&
<MaterialCommunityIcons
name={icon}
size={20}
color={colors.medium}
style={styles.icon}
/>}
<TextInput ref={textInput} {...otherProps} />
</Pressable>
);
}
Also replace the View with Pressable to be able to use onPress.
Try this simple solution,
<TextInput style={[customStyles.text, { flex: 1 }]} {...otherProps} />

React Native: Keyboard keeps closing on key press when typing in TextInput

I have a functional component Login Screen and have 4 Input Fields in them, along with a login button.
Here is the Full Code for my component Screen:
export default function Login() {
//Configs
const navigation = useNavigation();
const orientation = useDeviceOrientation();
const { colors, dark } = useTheme();
const InputTheme = {
colors: {
placeholder: colors.accent,
primary: colors.accent,
error: "red",
},
};
/** State Codes */
//States
const [login, setLogin] = useState({
email: "",
password: "",
licenseKey: "",
deviceName: "",
});
const [loading, setLoading] = useState(false);
const [secureEntry, setSecureEntry] = useState(true);
//Errors
const [errorEmail, setEmailError] = useState(false);
const [errorPWD, setPWDError] = useState(false);
const [errorLicense, setLicenseError] = useState(false);
const [errorDevice, setDeviceError] = useState(false);
//Error Messages
const [messageEmail, setEmailMessage] = useState("Looks Good");
const [messagePWD, setPWDMessage] = useState("All Good");
async function VerifyInputs() {
var pattern = /^[a-zA-Z0-9\-_]+(\.[a-zA-Z0-9\-_]+)*#[a-z0-9]+(\-[a-z0-9]+)*(\.[a-z0-9]+(\-[a-z0-9]+)*)*\.[a-z]{2,4}$/;
if (login.email == "") {
//Email cannot be empty
setEmailMessage("Email cannot be Blank!");
setEmailError(true);
return;
} else if (login.email != "" && !pattern.test(login.email)) {
//Email is not valid
setEmailMessage("This is not a valid email address!");
setEmailError(true);
return;
} else {
console.log("resolved email");
setEmailMessage("");
setEmailError(false);
}
if (login.password == "") {
//Password cannot be empty
setPWDMessage("Password cannot be Empty!");
setPWDError(true);
return;
} else if (login.password.length < 5) {
//Password must be minimum 5 characters.
setPWDMessage("Password must be of minimum 5 characters!");
setPWDError(true);
return;
} else {
console.log("resolved password");
setPWDMessage("");
setPWDError(false);
}
if (login.licenseKey == "") {
//License Key can't be Empty
setLicenseError(true);
return;
} else {
console.log("License resolved");
setLicenseError(false);
}
if (login.deviceName == "") {
//Device Name can't be empty as well
setDeviceError(true);
return;
} else {
console.log("Device name resolved");
setDeviceError(false);
}
Toast.show("Validation Successful");
}
function MobileContent() {
console.log("mobile_content rerendered");
return (
<View style={{ flex: 1, backgroundColor: colors.accent }}>
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}></View>
<View style={{ flex: 3, justifyContent: "center" }}>
{/**Main Content */}
<View style={[styles.content, { backgroundColor: colors.primary }]}>
<View style={{ flex: 1 }}>
{/**For Header */}
<Header />
</View>
<View style={{ flex: 5 }}>
{/**For Content */}
<ScrollView style={{ flex: 1 }}>
<LoginContent />
</ScrollView>
</View>
<View style={{ flex: 1 }}>
{/**For Footer */}
<Footer />
</View>
</View>
</View>
</View>
);
}
function TabContent() {
console.log("tab_content rerendered");
return (
<View
style={{
flex: 1,
backgroundColor: colors.accent,
flexDirection: orientation.landscape ? "row" : "column",
}}>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}></View>
<View style={{ flex: 1.5, justifyContent: "center" }}>
{/**Main Content */}
<View style={[styles.content, { backgroundColor: colors.primary }]}>
{/**Header Wrapper */}
<View style={{ justifyContent: "center" }}>
{/**Header Title */}
<Header />
</View>
{/**Content Wrapper */}
<LoginContent />
{/**Footer Wrapper */}
<View style={{ justifyContent: "center" }}>
{/** Login Button */}
<Footer />
</View>
</View>
</View>
</View>
);
}
function Header() {
console.log("header_component rerendered");
return (
<View style={{ margin: "5%" }}>
<Title>Welcome User</Title>
<Subheading>Please Sign In to Continue..</Subheading>
</View>
);
}
function Footer() {
console.log("footer_component rerendered");
return (
<View style={{ margin: isTablet ? "5%" : "3.5%" }}>
<Button
title="Login"
loading={false}
ViewComponent={LinearGradient}
containerStyle={{ maxWidth: isTablet ? "45%" : "100%" }}
buttonStyle={{ height: 50, borderRadius: 10 }}
linearGradientProps={{
colors: [colors.accent, colors.accentLight],
start: { x: 1, y: 1 },
end: { x: 1, y: 0 },
}}
onPress={() => {
VerifyInputs();
//navigation.navigate("verify");
}}
/>
</View>
);
}
function LoginContent() {
console.log("login_component rerendered");
return (
<View style={{ margin: "3%" }}>
{/**Login & Email Wrapper */}
<View style={{ flexDirection: isTablet ? "row" : "column" }}>
<View style={styles.input}>
<TextInput
mode="outlined"
label="Email"
value={login.email}
error={errorEmail}
theme={InputTheme}
onChangeText={(text) => setLogin({ ...login, email: text })}
/>
{errorEmail ? (
<HelperText visible={true} type="error" theme={{ colors: { error: "red" } }}>
{messageEmail}
</HelperText>
) : null}
</View>
<View style={styles.input}>
<View style={{ flexDirection: "row", alignItems: "center" }}>
<TextInput
mode="outlined"
label="Password"
value={login.password}
error={errorPWD}
theme={InputTheme}
secureTextEntry={secureEntry}
style={{ flex: 1, marginBottom: 5, marginEnd: isTablet ? 15 : 5 }}
onChangeText={(text) => setLogin({ ...login, password: text })}
/>
<Button
icon={
<Icon
name={secureEntry ? "eye-off-outline" : "eye-outline"}
size={30}
color={colors.primary}
/>
}
buttonStyle={{
width: 55,
aspectRatio: 1,
backgroundColor: colors.accent,
borderRadius: 10,
}}
containerStyle={{ marginStart: 5 }}
onPress={async () => setSecureEntry(!secureEntry)}
/>
</View>
{errorPWD ? (
<HelperText visible={true} type="error" theme={{ colors: { error: "red" } }}>
{messagePWD}
</HelperText>
) : null}
</View>
</View>
{/**License & Device Wrapper */}
<View style={{ flexDirection: isTablet ? "row" : "column" }}>
<View style={styles.input}>
<TextInput
mode="outlined"
label="License Key"
value={login.licenseKey}
error={errorLicense}
theme={InputTheme}
onChangeText={(text) => setLogin({ ...login, licenseKey: text })}
/>
{errorLicense ? (
<HelperText visible={true} type="error" theme={{ colors: { error: "red" } }}>
License Key cannot be Empty!
</HelperText>
) : null}
</View>
<View style={styles.input}>
<TextInput
mode="outlined"
label="Device Name"
value={login.deviceName}
error={errorDevice}
theme={InputTheme}
onChangeText={(text) => setLogin({ ...login, deviceName: text })}
/>
{errorDevice ? (
<HelperText visible={true} type="error" theme={{ colors: { error: "red" } }}>
Device Name cannot be empty
</HelperText>
) : null}
</View>
</View>
</View>
);
}
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle={"dark-content"} backgroundColor={colors.accent} />
{isTablet ? <TabContent /> : <MobileContent />}
</SafeAreaView>
);
}
As you can see by looking at the code.. my Login component's rendering responsive component layouts based on device type being phone or tablet, the following components MobileContent or TabContent.
MobileContent functional component wraps my main content in a ScrollView & TabContent functional component doesn't need a scrollview but has responsive scaling views.
Both of these parent components display my common components, Header,LoginContent & Footer.
My Header component just displays a standard title & subheading. My LoginContent component has all the TextInput fields in them with validation logic setup as well. My Footer component has the Submit/Login button. That's All.
So we can summarize the components tree for screen as:
Login Screen/Parent Component => Mobile Content/Tab Content => Header, LoginContent & Footer (Common Components)
Alright, so now what is the issue? the major issue for me lies for TextInputs in LoginContent component, but I assume the underlying issue is applicable for entire Login Screen component.
The ISSUE: When I click on TextInput fields, the input gets focus and Keyboard appears. Everything is fine till this point. As soon as I type even a single letter, single key press on keyboard.. The Keyboard closes immediately and the text input is lost focus.
Why it could be happening? I believe this might be the classic 'React Component Re-render' problem, which causes by TextInput to be re-rendered when state is updated by the onChangeText for the TextInput and hence it loses focus & that's why the Keyboard closes.
So, I hope to resolve atleast first issue from these two issues.
Issue 1: How do I prevent the Keyboard from constantly closing when I try to type something in any of the TextInput fields.
Issue 2: How can I better optimize my Parent & Children components rendering on every state update using the any of these two React Hooks useCallback() and useMemo()?
I've read the documentation for these two hooks useCallback & useMemo multiple times and still haven't grasped the concept of these hooks. All posted examples deal with a Counter Exmaple optimized using useCallback or useMemo but I'm not working with Counters here in my Screen.
I need a more practical exmaple of useCallback() & useMemo() in screen components. Perhaps an implementation of these two hooks in my current Login Screen component will help me understand & grasp the concept better.
Like I mentioned, solving Issue 1 is my highest priority atm, but I know a solution for Issue 2 will help me in the long run as well. It will be very helpful if you can resolve both of my issues here. Thanks for helping.

ScrollView not allowing me to select from Component dropdown

First of all let me share my code along with the current result of what I have going.
return(
<DismissKeyBoard>
<View>
<Formik
initialValues ={{user: 'User ', place: '', description: '', comments: '',datePosted: new Date(), location: '', eventDate: ''}}
onSubmit ={logInfo}>
{props =>(
<SafeAreaView style={styles.container}>
<ScrollView>
<View style={styles.form}>
<Text style={styles.text}>Pick a place for the event</Text>
<GooglePlacesAutocomplete
placeholder='Insert place to find'
minLength={2}
keyboardAppearance={'light'}
fetchDetails={false}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
{props.values.location= data.description}
console.log("hello",props.values.location);
}}
styles={{
textInputContainer: {
backgroundColor: 'rgba(0,0,0,0)',
borderTopWidth: 0,
borderBottomWidth:0,
width: '100%',
},
textInput: {
fontSize: 16
},
predefinedPlacesDescription: {
color: '#1faadb',
height:'100%',
},
}}
query={{
key: '',
language: 'en', // language of the results
}}
/>
<View style={styles.container}>
<Text
placeholder= {props.values.user}
onChangeText = {props.handleChange('user')}
values = {props.values.user}
style={styles.text}>{props.values.user}</Text>
<TextInput
placeholder= 'Place (e.g Honolulu)'
onChangeText = {props.handleChange('place')}
values = {props.values.place}
style={styles.text}/>
<TextInput
placeholder= 'Description (e.g This is located...)'
onChangeText = {props.handleChange('description')}
values = {props.values.description}
style={styles.text}/>
<TextInput
placeholder= 'Comment (e.g This is fun because...)'
onChangeText = {props.handleChange('comments')}
values = {props.values.comments}
style={styles.text}/>
<Text style={styles.text} >Pick a date for the event</Text>
<DatePicker
date={props.values.eventDate}
onDateChange={(date) => {props.values.eventDate= date}}
values = {props.values.eventDate} />
{/* <Text style={styles.text}>Location</Text> */}
<View style={styles.viewbtn}>
<TouchableOpacity onPress={props.handleSubmit} style={styles.btn} ><Text style={styles.txtbtn} >Submit</Text></TouchableOpacity>
{/* <Button title="Submit" onPress={props.handleSubmit} /> */}
</View>
</View>
</View>
</ScrollView>
</SafeAreaView>
)}
</Formik>
</View>
</DismissKeyBoard>
)
}
const styles = StyleSheet.create({
container:{
// flex:1,
paddingTop:20,
// margin: 10,
alignItems: 'center'
},
// form:{
// alignItems: 'flex-start',
// paddingTop:40,
// },
text:{
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: 'black',
paddingTop:15,
},
viewbtn:{
paddingTop:15,
},
btn:{
backgroundColor: 'purple',
padding:20,
margin:20,
width: 100,
justifyContent: 'center',
alignItems: 'center',
borderRadius : 5,
},
txtbtn:{
fontWeight: 'bold',
fontSize: 14,
color: 'orange'
},
})
The issue
When I click on the GooglePlacesAutoComplete I am able to see the list of places, but then when I click on any of the found places it will not take the input.
Observations
When the <GooglePlacesAutocomplete /> is NOT inside a ScrollView I cannot see the suggestion.
When the <GooglePlacesAutocomplete /> is NOT within any other <View></View> it works perfectly fine.
Warning
With the above code I also get this warning message "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead."
Desired Result
I would like to have the <GooglePlacesAutocomplete /> component displayed on top of the form, without any weird errors and its functionalities working properly. (Preferably as shown in the picture)
Edit
I am importing import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete'; from https://github.com/FaridSafi/react-native-google-places-autocomplete
I am not an expert in GUI, an explanation would be very appreciated and welcomed. If additional information is required I would be more than happy to provide it.
Thank you in advance.
So I faced the same problem and the one thing that helped me solve the problem was adding
keyboardShouldPersistTaps={true} inside the <ScrollView> as a prop.
This is my code snippet.
<ScrollView keyboardShouldPersistTaps={true}>
<SelectionDD studentstatus={studentStatus}/>
<SearchableDD collegeNames={collegeNames} placeholder='University'/>
</ScrollView>

Set background color dynamically in React native

I´m creating a weather application where I want the background color to change dynamically based on weather conditions fetched from OpenWeatherMaps API. However, I´m not really sure how to do this since I get an error message that says: "Undefined is not an object (near '...}]color...')
Right now I´ve pre-defined the conditions in a separate file called WeatherConditions, and I want the props in my Weather file to determine the background color. How can I do this?
This is my render method in the Weather file. The problem lies in the first view tag after return:
render() {
const {
weatherCondition,
city,
country,
temperature,
placeholder,
weatherDescription,
getWeather,
handleTextChange,
searchedCity
} = this.props;
const {
weatherContainer,
headerContainer,
tempText,
tempContainer,
bodyContainer,
inputContainer,
textInputStyle,
subtitle,
title
} = styles;
return (
<View
style={[
weatherContainer,
{
backgroundColor:
weatherConditions[{ weatherCondition }].color
}
]}
>
{" "}
// Does not work right now.
<View style={headerContainer}>
<Text style={tempText}>
{" "}
{city} {country}
</Text>
<Text style={tempContainer}>
{" "}
{Math.round(temperature)}
˚C
</Text>
</View>
<View style={bodyContainer}>
<View style={inputContainer}>
<TextInput
style={textInputStyle}
onChangeText={searchedCity =>
handleTextChange(searchedCity)
}
onSubmitEditing={() => getWeather()}
placeholder={placeholder}
clearTextOnFocus={true}
enablesReturnKeyAutomatically={true}
/>
</View>
<Text style={title}>{weatherCondition}</Text>
<Text style={subtitle}>{weatherDescription}</Text>
</View>
{this.renderLoading()}
</View>
);
}
My WeatherCondition file:
export const weatherConditions = {
Thunderstorm: {
color: '#303952'
},
Drizzle: {
color: '#8aacb8'
},
Rain: {
color: '#786fa6'
},
Snow: {
color: '#00d8d6'
},
Atmosphere: {
color: '#ff5252'
},
Clear: {
color: '#f5cd79'
},
Clouds: {
color: '#0be881'
},
}
It should be
<View style={[weatherContainer, {
backgroundColor: weatherConditions[weatherCondition].color
}]}>
Note the syntax weatherConditions[weatherCondition].color, you don't need any curly brackets.
weatherConditions is an object, weatherCondition is variable. To access property by variable name, you use bracket notation.

Resources