I have a component called MDropDowlList which render the following view :
MDropDownList.js
render() {
return (
<View>
<View
style={{
backgroundColor: '#fff',
position: 'absolute',
left: 0,
right: 0,
top: 0,
maxHeight: 200,
}}
>
{
this.props.searchable && (
<TextInput
style={{ zIndex: 198 }}
onChangeText={(text) => this.search(text)}
/>
)
}
<FlatList
data={this.state.data}
keyboardShouldPersistTaps="always"
nestedScrollEnabled={true}
contentContainerStyle={{ zIndex: 199 }}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<TouchableHighlight
key={index.toString()}
style={{
padding: 10,
backgroundColor: '#fff',
}}
underlayColor="#5897fb"
onPress={() => this.props.handleOnPress(item)}
>
<MText size={18}>{item}</MText>
</TouchableHighlight>
)}
/>
</View>
</View>
);
}
Then I have called this component to another component called MDropDown which render method is as below :
MDropDown.js
render() {
return (
<View style={{ marginVertical: 5, zIndex: 3}}>
...
{/* Another components */}
...
{
this.state.displayDropDown && (
<MDropDownList data={this.props.data} searchable={this.props.searchable} handleOnPress={(item) => this.handleOnPress(item)} />
)
}
</View>
);
}
Now finally I called my MDropDown component in my main screen as follow :
render() {
return (
<KeyboardAvoidingView style={{ flex: 1, backgroundColor: Colors.bgGray }} behavior="padding">
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.container} keyboardShouldPersistTaps="always" nestedScrollEnabled={true}>
<View style={{ backgroundColor: '#fff', padding: 10 }}>
<MDropDown
label="Category"
placeholder="Select Category"
data={["test1", "test2", "test3", "test4", "test5"]}
onSelectItem={(selectedItem) => alert(selectedItem)}
searchable={true}
/>
</View>
</ScrollView>
</KeyboardAvoidingView>
)
}
But I am not able to access Flatlist item or TextInput of MDropDownList component. Even I am not able to focus TextInput available in MDropDownList.
Please help me what's going wrong here ???
Note : This issue is only on android, on ios it is working properly. On ios I am able to click flatlist item and focus TextInput as well as.
Tried using zIndex to the absolute view?
Add property of zIndex : 500 to the style.
Related
I have this <ScrollView />
<ScrollView
style={styles.scrollview}>
{route.params && route.params....map((cat, index) => {
return <Kitten
cat={cat}
key={index} />
})}
</ScrollView >
const styles = StyleSheet.create({
scrollview: {
paddingLeft: 15,
paddingRight: 15,
backgroundColor: 'white',
flex: 1,
},
});
into which I want to put this <BackgroundImage />.
import { ImageBackground } from 'react-native';
const image = require('...')
const Kittens = ({ children }) => {
return <ImageBackground
source={image}
resizeMode='repeat'
style={{ width: '100%', height: '100%' }}>
{children}
</ImageBackground>
}
I want the background image to be fixed, so that the content scrolls over the image. I further shall fill the whole screen. How would I do that?
use the scrollview as the child of ImageBackground
<ImageBackground
source={{uri://image url here}}
style={{
}}
>
<ScrollView
style={styles.scrollview}
contentContainerStyle={}
>
{route.params && route.params....map((cat, index) => {
return <Kitten cat={cat} key={index} />
})}
</ScrollView >
</ImageBackground>
If the parent of the Kittens fills the screen, removing white backgroundColor should work. You can play with resizeMode to get the best result from your image.
<Kittens>
<ScrollView
style={styles.scrollview}>
{route.params && route.params....map((cat, index) => {
return <Kitten cat={cat} key={index} />
})}
</ScrollView >
</Kittens>
const styles = StyleSheet.create({
scrollview: {
paddingLeft: 15,
paddingRight: 15,
//backgroundColor: 'white',
flex: 1,
},
});
<ImageBackground
source={{uri:image url}}
style={{height:"100%", width:"100%"}}
>
<ScrollView
contentContainerStyle={flexGrow:1}
>
<View style={{flex:1}} >
</View>
</ScrollView >
</ImageBackground>
I am making filter modal for e-commerce application where I divided it into two component view one for left and one for right view. Where I am using flatlist for left view and scrollview for right.
I am trying achieve scroll on both side. I don't know why isn't working.Same code is working for different project without any problem.
I am unable to scroll on either side.
Attaching code snippet for same.
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {
this.setState({ modalVisible: !this.state.modalVisible });
}}
>
<View style={Style.general.centeredView}>
<View style={Style.general.modalView}>
<View style={Style.general.filterModal}>
<Text style={Style.general.filterModalHeading}>FILTERS</Text>
{this.state.filtersApplied.length > 0 ? (
<TouchableOpacity
style={{
alignSelf: "flex-end",
marginRight: 10,
paddingHorizontal: 10,
paddingVertical: 5,
borderWidth: 1,
borderColor: "#000",
borderRadius: 5,
}}
onPress={() => this.clearFiltersHandler()}
>
<Text>Clear Filters</Text>
</TouchableOpacity>
) : null}
</View>
<View style={Style.general.filterModalData}>
<View style={Style.general.filterModalDataLeftScroll}>
{/* {isFetching && modalVisible ? <Loader /> : null} */}
{this.state.filters && (
<FlatList
// contentContainerStyle={styles.listContainer}
data={this.state.filters}
// numColumns={2}
// onEndReached={() => fetchProducts(false, sortApplied)}
// onEndReachedThreshold={0.1}
keyExtractor={() =>
"_" + Math.random().toString(36).substr(2, 9)
}
renderItem={this.renderFilters}
// removeClippedSubviews
/>
)}
</View>
<ScrollView
style={{
flexGrow: 1,
width: "70%",
flexDirection: "column",
paddingHorizontal: 10,
}}
>
{this.state.activeFilterLabel !== "pf_p_price" &&
this.state.fliterLabel.map((values, i) => {
// console.log("values", values);
return (
<TouchableOpacity
key={i}
onPress={() => this.addFilterHandler(values)}
>
<View
style={Style.general.filterModalDataRightFilter}
>
<View
style={[
Style.general.filterBoxWrap,
{
backgroundColor:
this.state.filtersApplied.some(
(filter) => filter == values.key
)
? "#000"
: "#fff",
},
]}
>
<Icon name="check" size={11} color="#fff" />
</View>
<Text
style={{
fontFamily: "Futura",
fontSize: 12,
}}
>
{values.key}
</Text>
</View>
</TouchableOpacity>
);
})}
{this.state.activeFilterLabel === "pf_p_price" ? (
<View>
<Text>Hello</Text>
</View>
) : null}
</ScrollView>
</View>
{this.state.filterModalLoader ? (
<TouchableOpacity style={{ flex: 1 }} />
) : null}
<View style={Style.general.filterBtnFix}>
<TouchableWithoutFeedback
onPress={() => {
this.setState({ modalVisible: false });
}}
>
<View style={Style.general.filterBtnFixWrap}>
<Text style={Style.general.filterBtnFixWrapText}>
Close
</Text>
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => {
this.setState({ modalVisible: false });
}}
>
<View style={Style.general.filterBtnFixWrap}>
<Text style={Style.general.filterBtnFixWrapText}>
Apply
</Text>
</View>
</TouchableWithoutFeedback>
</View>
</View>
</View>
</Modal>
I have encountered a weird issue in the newest react native where the value in the text input in a component remains when a tab is switched.
I can't figure what is going on and I thought it should re-render when tab is changed but it doesn't.
Here's my code
app.js
export default function App() {
const [tab, setTab] = useState("TAB1")
return (
<View style={styles.container}>
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity
style={{ borderRadius: 5, borderWidth: 1, marginRight: 5, padding: 20 }}
onPress={() => setTab("TAB1")}
>
<Text>Tab 1</Text>
</TouchableOpacity>
<TouchableOpacity
style={{ borderRadius: 5, borderWidth: 1, padding: 20}}
onPress={() => setTab("TAB2")}
>
<Text>Tab 2</Text>
</TouchableOpacity>
</View>
<View style={{ marginTop: 20}}>
{
tab === "TAB1" ? (
<View>
<InputComponent tab={tab} />
</View>
) : (
<View>
<InputComponent tab={tab} />
</View>
)
}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
marginTop: 100,
padding: 10
},
});
inputcomponent.js
export function InputComponent({ tab }) {
const [value, setValue] = useState("");
return (
<View>
<Text>{tab}</Text>
<TextInput placeholder="INPUT HERE" value={value} onChangeText={setValue}/>
</View>
)
}
It seems like the input component re-renders but the text input within it doesn't change.
Demo Issue
This is such a good question. This is because we are importing it once and passing it to two different components. It changes the tab but uses the same textinput state because they are using the same key.
To fix this pass in the key prop so React knows that tab changed:
{
tab === "TAB1" ? (
<View>
<InputComponent key={1} tab={tab} />
</View>
) : (
<View>
<InputComponent key={2} tab={tab} />
</View>
)
}
Snack: https://snack.expo.io/mVVLb9uId
Read about keys: https://reactjs.org/docs/lists-and-keys.html#keys
I have 2 columns in flatList and I'm trying to align the header component besides the items itself,
Like this
But I got the "add image" above then the items below it,
I'm trying to solve it by using flexWrap in content container style but since I was using numColumns i got a warning that tells flexWrap not supported and use numColumns instead.
so i don't know how can i solve it, so if anybody can help in this case!
here's a snack
Code snippet
const renderItems = ({ item, index }) => {
return (
<View style={{ flex: 0.5, margin: 4 }}>
<View style={[styles.imgContainer, { borderWidth: 0 }]}>
<Image
style={styles.imgStyle}
source={{
uri:
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcR1K8ypPsfNVQU8lVxl1i2_ajismMS_w6FA4Q&usqp=CAU',
}}
/>
</View>
</View>
);
};
const renderHeader = () => (
<TouchableOpacity
// onPress={appeandImgs}
style={styles.imgContainer}>
<Image
style={styles.imgStyle}
source={{
uri: 'https://static.thenounproject.com/png/3322766-200.png',
}}
/>
</TouchableOpacity>
);
const keyExtractor = (item, index) => String(index);
<FlatList
data={[1,2,3]}
style={styles.flatList}
numColumns={2}
renderItem={renderItems}
ListHeaderComponentStyle={{
backgroundColor: '#ff0',
width: ScreenWidht / 2 - 20,
}}
keyExtractor={keyExtractor}
ListHeaderComponent={renderHeader}
columnWrapperStyle={{
backgroundColor: '#f07',
}}
contentContainerStyle={{
flexGrow: 1,
paddingBottom: 12,
paddingTop: 15,
}}
/>
I am fetching data from http://retailsolution.pk/api/allhome I want to display the title of the product and then all the child products below it, I am getting this output: Here's my code:
class App extends Component {
constructor(props) {
super(props);
this.state = {
Deals: []
};
}
componentWillMount() {
axios
.get("https://retailsolution.pk/api/allhome")
.then(response => this.setState({ Deals: response.data.Deals }));
}
_renderItem(item) {
return (
<View style={{ width: 100, height: 130 }}>
<Image
style={{ width: 100, height: 100 }}
source={{ uri: item.image }}
/>
<Text numberOfLines={1} style={{ flex: 1 }}>
{" "}
{item.name}
</Text>
</View>
);
}
renderTitle() {
return this.state.Deals.map(deal => (
<Text key={deal.parent.id} style={styles.text}>
{deal.parent.name}
</Text>
));
}
renderImage() {
return this.state.Deals.map(deal => (
<FlatList
key={deal.child.product_id}
style={{ marginTop: 5 }}
horizontal
ItemSeparatorComponent={() => <View style={{ width: 5 }} />}
renderItem={({ item }) => this._renderItem(item)}
data={[deal.child]}
/>
));
}
render() {
console.log(this.state.Deals);
return (
<View style={{ flex: 1, marginLeft: 8, marginRight: 8, marginTop: 10 }}>
{this.renderTitle()}
{this.renderImage()}
</View>
);
}
}
In my case {this.renderTitle()} gets execute first and maps every value from the api to the app and then {this.renderImage()} maps all flatlists to the app.
Is there any way I can run this.renderImage() after every iteration of rhis.renderTitle()?
You will have to do it using nested loop.
Try something like this -
{this.state.Deals.map(deal => {
return (
<div>
<Text key={deal.parent.id} style={styles.text}>
{deal.parent.name}
</Text>
{deal.child.map(item => {
return (
<FlatList
key={item.product_id}
style={{ marginTop: 5 }}
horizontal
ItemSeparatorComponent={() => <View style={{ width: 5 }} />}
renderItem={({ item }) => this._renderItem(item)}
data={[item]}
/>
);
})}}
</div>
);
})}
A way to do it is to call a function after the fetch that will create the section data for the Flatlist with the correct format:
sections = [{title: 'Latest', data:["The products data array"]}, {title: 'second section', data : ["Other products"]}, and so on...]`