How to style react native picker - android

I'm using Beefe's react-native-picker and I want to add custom styles.
I have an method that renders the picker as follows:
renderModal() {
if (!this.state.itemPickerVisible) return;
return (
<View>
{
Picker.init({
pickerData: map(categories, cat => cat.code + "." + cat.name),
pickerTitleText: gettext("Please select"),
pickerConfirmBtnText: gettext("Done"),
pickerCancelBtnText: gettext("Cancel"),
selectedValue: [this.state.selectedValue.code],
pickerBg: [255, 255, 255, 1],
onPickerConfirm: data => {
let code = data[0].substring(0, data[0].indexOf('.'));
this.setState({selectedValue: get_category(code), itemPickerVisible: false}, () => this.selectedItem());
},
onPickerCancel: data => {
Picker.hide();
},
onPickerSelect: data => {
console.log(data);
}
})
}
{
Picker.show()
}
</View>
)
}
And the render method is as follows:
render() {
let value = this.props.value ? this.props.value.name : "";
return (
<View style={{
borderLeftWidth: 4,
borderLeftColor: this.props.mandatory ? this.props.value == null ? s.paletteMandatory : s.success : '#fff'
}}>
{this.renderModal()}
<ItemDetail locked={this.props.locked} selectItem={this.selectItem.bind(this)}
resetItem={this.resetItem.bind(this)} title={this.props.title} value={value}
icon={this.props.icon}/>
</View>
)
}
Is there any way to add custom style (fontFamily, color) to the picker items?

If you check the component docs there are several parameters you can pass to init function.
Picker.init({
pickerTitleColor: [90, 90, 90, 1], // RGBA values
pickerData: data,
selectedValue: [59],
onPickerConfirm: data => {
console.log(data);
},
onPickerCancel: data => {
console.log(data);
},
onPickerSelect: data => {
console.log(data);
}
});
Picker.show();

Related

Refresh Control not working on Android -React Native

Here is My Code
<FlatList
refreshControl={
<RefreshControl
enabled={true}
refreshing={loader}
onRefresh={() => getLockerHistory(1)}
tintColor={ThemeColors.primary}
/>
}
ListEmptyComponent={noDataMessage()}
onScroll={(e) => {
if (Platform.OS == 'ios') {
return;
}
let paddingToBottom = 20;
paddingToBottom += e.nativeEvent.layoutMeasurement.height;
if (e.nativeEvent.contentOffset.y >= e.nativeEvent.contentSize.height - paddingToBottom) {
getNextRecordsPage();
}
}}
ListFooterComponent={() => {
return (
<ActivityIndicator color={ThemeColors.black} animating={footerLoader} />
);
}}
ListFooterComponentStyle={footerLoader ? { marginVertical: 20 } : {}}
ListFooterComponentStyle={{ paddingVertical: 20 }}
onEndReached={() => {
if (Platform.OS == 'ios') {
getNextRecordsPage()
}
}}
onEndReachedThreshold={Platform.OS == 'ios' ? 0 : null}
keyExtractor={(item, index) => item.lockerCode + '' + index}
data={lockers}
renderItem={(itemData) => {
return renderItem(itemData.item, props.navigation);
}}
/>
When I have more then 5 records which means there is not empty space left on screen then the refresh control won't work. It only works the seperator space between cells.
And my cell is made up of plain views nothing fancy or touchable.
Note: I tried to debug it with empty view but seems like pull/drag to refresh is not being listen by Flat List.
Any help?
Below code is working for me to achieve Refresh Control
import { View, Text, RefreshControl, FlatList } from 'react-native'
<FlatList
testID="DiscussionView"
initialNumToRender={5}
maxToRenderPerBatch={5}
windowSize={11}
data={posts}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh} />}
keyExtractor={this.keyExtractor}
refreshing={refreshing}
renderItem={this.renderPostItem}
onEndReached={this.onEndReached}
scrollEnabled={scrollEnabled}
onEndReachedThreshold={0.3}
contentContainerStyle
listKey="DiscussionViewList"
onMomentumScrollBegin={() => {
this.onEndReachedCalledDuringMomentum = false
}}
/>
onRefresh = () => {
this.setState(
{ refreshing: true },
// Do what you want,
)
}
keyExtractor = (item) => String(item.id)
renderPostItem = ({ item }) => {
// Render Item here
}
onEndReached = () => {
if (!this.onEndReachedCalledDuringMomentum) {
// Call API again if needed by use case
this.onEndReachedCalledDuringMomentum = true
}
}

How can I send images/video and voice messages in React-native-Gifted-chat using render actions?

I want to send images/video in chat application, developed using React-native-gifted-chat and Firebase, How can I create action for them and call that actions to upload in firebase and send images/video?
Here is my code.
handleSendImage = () => {
console.log("handleSendImage");
};
renderActions(props) {
return (
<Actions
{...props}
// containerStyle={{
// width: 70,
// }}
icon={() => (
<Icon
name={"camera"}
size={30}
color={colors.btnBg}
font={"FontAwesome"}
onPress={this.handleSendImage}
/>
)}
onSend={(args) => console.log(args)}
/>
);
}
<GiftedChat
placeholder={"Hey!"}
alwaysShowSend
messages={messages}
onSend={(newMessage) => this.onSend(this.chatID(), newMessage)}
renderInputToolbar={this.renderInputToolbar}
renderActions={this.renderActions}
user={{
_id: senderId,
name: senderName,
}}
/>
How can I click on particular actions and send voice and images/video respectively?
Gifted chat has renderActions property itself so just need to create custom action to upload image/video and voice.
Here, I am attaching code for upload documents like PDF/Doc file.
To upload image/video you just need to change that package instead of I've used document-picker
const renderActions = (props) => {
return (
<Actions
{...props}
options={{
['Document']: async (props) => {
try {
const result = await DocumentPicker.pick({
type: [DocumentPicker.types.pdf],
});
console.log("image file",result)
} catch (e) {
if (DocumentPicker.isCancel(e)) {
console.log("User cancelled!")
} else {
throw e;
}
}
},
Cancel: (props) => { console.log("Cancel") }
}}
onSend={args => console.log(args)}
/>
)
};
Gifted-chat component
<GiftedChat
messages={messages}
showAvatarForEveryMessage={true}
onSend={messages => onSend(messages)}
renderActions={() => renderActions()}
user={{
_id: 2,
name: 'React Native',
avatar: 'https://placeimg.com/140/140/any',
}}
renderCustomView={renderCustomView}
/>

React Native Firebase - Push data to Array allowing to display in a FlatList

I am new to React Native and struggling a little to get this working. I have realtime database in Firebase which contains 'mechanic' names. I would like to retrieve these names and display them in a list.
I would like to display this data in a list and then execute some function when the user clicks on either name. I thought adding the database data to an array then looping through the array to add it to my FlatList.
The problem now is that when I execute the code, the this.setState({ mechanicsList: mechanicsTemp }); returns an error.
Error
[Unhandled promise rejection: TypeError: this.setState is not a function.
(In 'this.setState({]
* src\screens\FindMechanics.js:28:30 in <unknown>
- node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
- node_modules\promise\setimmediate\core.js:123:25 in <unknown>
- ... 8 more stack frames from framework internals
Full Code
import React, { Component } from 'react';
import { View, Text, SafeAreaView, TouchableOpacity, ScrollView, StyleSheet } from "react-native";
import { Card } from 'react-native-elements'
import firebase from "firebase/app";
export default class FindMechanics extends Component {
constructor(props) {
super(props);
this.state = {
mechanicsList: [],
isDataLoaded: false
}
}
componentDidMount() {
var query = firebase.database().ref("MechanicList").orderByKey();
query.once("value")
.then(function (snapshot) {
let mechanicsTemp = [];
snapshot.forEach(function (childSnapshot) {
// key will be the auth ID for each user
var key = childSnapshot.key;
var mechanicName = snapshot.child(key + '/name').val();
mechanicsTemp.push({ _name: mechanicName, _key: key });
});
mechanicsList = mechanicsTemp;
() => this.setState({ mechanicsList: mechanicsTemp }); // This does not execute it seems - main problem I believe
//this.setState({ mechanicsList: mechanicsTemp }); - This return a warning 'this.setState is not a function'
console.log(mechanicsList); //Prints data as expected
mechanicsTemp.forEach((mechanic) => {
console.log( mechanic._name); //Prints data as expected
});
});
}
render() {
//The Card element is empty - nothing shows.
console.log(this.state.mechanicsList) //This return Array [] which indicates it is empty
return (
<SafeAreaView style={styles.container}>
<ScrollView horizontal={true}>
<TouchableOpacity>
<Card style={styles.card}>
{
this.state.mechanicsList.map((u, i) => {
return (
<View key={i}>
<Text>{u._key}</Text>
<Text>{u._name}</Text>
</View>
);
})
}
</Card>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#FFF'
},
paragraph: {
margin: 24,
fontSize: 18,
textAlign: 'center',
},
card: {
flex: 1,
width: '80%',
},
});
Console
Finished building JavaScript bundle in 384ms.
Running application on Android SDK built for x86.
Array []
1st thing, you have mechanics object in state so you need to access it like
console.log(this.state.mechanics)
2nd thing is that you are not updating state variable when you are having data, it should be like following
let mechanicsTemp = [];
snapshot.forEach(function (childSnapshot) {
// key will be the auth ID for each user
var key = childSnapshot.key;
var mechanicName = snapshot.child(key + '/name').val();
mechanicsTemp.push({_name: mechanicName, _key: key});
});
this.setState({ mechanics:mechanicsTemp })
I dunno if you still need help with this or not but I just used your code and I solved this.setState problem with binding. You can either use arrow function or bind your function:
.then(function (snapshot) {
// ..
}.bind(this));

React Native Send sms within the app

I want to send sms to multiple numbers without opening to default messaging app.
I try to use react-native-sms-x but its not maintained and my project just stuck at compiling.
Also I used react-native-sms but it open default Messaging App filled with one user number and message body and had to click send button of it too.
import { Linking,Platform } from "react-native";
const url = (Platform.OS === 'android')
? 'sms:919999999999?body=your message'
: 'sms:919999999999'
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log('Unsupported url: ' + url)
} else {
return Linking.openURL(url)
}
}).catch(err => console.error('An error occurred', err))
After a lot of research and trials in the react app...
I have found this library working fine and reached the goals to send a message without going into the default message environment.
var phoneNumbers = {
"addressList": ["+911212121212", "+911212121212"]
};
var message = "This is automated test message"
SmsAndroid.autoSend(
phoneNumbers,
message,
(fail) => {
console.log('Failed with this error: ' + fail);
},
(success) => {
console.log('SMS sent successfully');
},
);
I hope it helps you. Do not forget to upvote
From Now Just For Android I use react-native-sms-android
Here is my Code for Sending sms to multiple users:
import Asms from "react-native-sms-android";
type Props = {};
export default class App extends Component<Props> {
constructor(Props) {
super(Props);
this.state = { FileNumbers: ['687867867867','8575774433'], Message:
"gjjgjgj" };
}
sendingSms = (Receivers, Messagex) => {
try {
Receivers.map(
async Numbers =>
await Asms.sms(Numbers, Messagex, "sendDirect", (err,message)
=> {
if (err) {
console.log(err);
} else {
console.log(message);
}
})
);
} catch (e) {
alert("" + e);
}
};
render() {
return (
<View style={styles.container}>
<TextInput
style={{
height: 40,
borderColor: "gray",
borderWidth: 1,
width: "90%"
}}
onChangeText={Message => this.setState({ Message })}
value={this.state.Message}
/>
<Button
title="SEND"
onPress={() =>
this.sendingSms(this.state.FileNumbers, this.state.Message)
}
/>
</View>
);
}
}

React native android animation

I'm trying to animate the height of a View in react native. The animation is working as expected in iOS but is not working in Android. The animated View seems to always be full height regardless of the animation value. Relevant code is below:
var Facets = React.createClass({
getInitialState: function() {
return {
h: new Animated.Value(0),
};
},
_animate: function(newHeight) {
Animated.timing(this.state.h, {
duration: 300,
toValue: newHeight
}).start();
},
render: function() {
var facetComponents = [];
if (this.props.shown) {
this._animate(MAX_HEIGHT);
}
else {
this._animate(0);
}
facets.map( (facet, idx) => {
facetComponents.push(
<Facet
key={idx}
facet={facet}
filterBy={this.props.filterBy} />);
});
return (
<Animated.View style={{ maxHeight: this.state.h }}>
{facetComponents}
</Animated.View>
);
}
});
Try moving your Animated Value out of state:
componentDidMount() {
this.h = new Animated.Value(0)
}
Then, refer to it as this.h as opposed to this.state.h

Categories

Resources