Closed salisuabubakar closed 8 months ago
On Android, wrap the scene in a View
component with collapsable set to 'false'. On iOS, wrap the scene in a ScrollView
component with contentInsetAdjustmentBehavior
set to 'automatic'. The following code will give you a native search on both Android and iOS.
const Container = (props) => (
Platform.OS === 'ios' ? <ScrollView contentInsetAdjustmentBehavior="automatic" {...props}/> : <View collapsable={false} {...props} />
);
const ServiceScreen = () => {
const [text, setText] = useState('');
return (
<Container>
<NavigationBar>
<SearchBar
toolbar
text={text}
onChangeText={text => setText(text)}>
<SearchServices text={text} />
</SearchBar>
</NavigationBar>
</Container>
);
}
Hi, Thanks for your response. Am only doing for ios for now so this is what i did based on what you responded but still not able to search. The searchbar is there but when i search for any item it doest show anyting.
Below is the code:
function ServiceScreen() { const [servicesSearchData, setservicesSearchData] = useState([]);
const onChangeText = text => { let servicesDataFilter = filterservicesSearchData; let servicesSearchResult = servicesDataFilter.filter(itemData => itemData.title.toUpperCase().includes(text.toUpperCase()), ); setservicesSearchData(servicesSearchResult); };
const SearchServices = (item) => {
return (
<ScrollView
contentInsetAdjustmentBehavior="automatic">
<Pressable
key={item.nid}
style={{
backgroundColor: '#FFFFFF',
flexDirection: 'row',
width: '94%',
flexDirection: 'row',
marginHorizontal: 16,
padding: 12,
borderRadius: 6,
backgroundColor: '#FFFFFF',
alignSelf: 'center',
shadowColor: '#3D3D3D',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.1,
shadowRadius: 2.05,
elevation: 2,
}}
android_ripple={{ color: '#121212', borderless: false }}
onPress={() => {
stateNavigator.navigate('servicesDetails', {
dataitem: [item.field_services_image, item.title, item.view_node],
});
}}>
<Image
imageStyle={{ borderRadius: 10 }}
style={styles.servicesimageStyle}
source={{
uri: https://example.com${item.field_services_image}
,
}}
/>
<Text
style={{
color: '#3D3D3D',
fontFamily: 'Heebo-Bold',
fontWeight: '800',
fontSize: 17,
paddingVertical: 16,
}}>
{item.title}
)
};
const renderServices = useCallback(({ item }) => {
return (
<Pressable
key={item.nid}
style={{
backgroundColor: '#FFFFFF',
flexDirection: 'row',
width: '94%',
flexDirection: 'row',
marginHorizontal: 16,
padding: 12,
borderRadius: 6,
backgroundColor: '#FFFFFF',
alignSelf: 'center',
shadowColor: '#3D3D3D',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.1,
shadowRadius: 2.05,
elevation: 2,
}}
android_ripple={{ color: '#121212', borderless: false }}
onPress={() => {
stateNavigator.navigate('servicesDetails', {
dataitem: [item.field_services_image, item.title, item.view_node],
});
}}>
<Image
imageStyle={{ borderRadius: 10 }}
style={styles.servicesimageStyle}
source={{
uri: https://example.com${item.field_services_image}
,
}}
/>
<Text
style={{
color: '#3D3D3D',
fontFamily: 'Heebo-Bold',
fontWeight: '800',
fontSize: 17,
paddingVertical: 16,
}}>
{item.title}
)
});
return ( <> {Platform.OS === 'android' ? ( <NavigationBar title="Services" titleFontSize={standard => (standard ? 18 : 28)} titleFontFamily={'Heebo-Bold'} titleFontWeight="800" titleColor={'#000000'} largeTitle={true} barTintColor={'red'} navigationAccessibilityLabel="Services" tintColor={'#ffffff'}
) : ( null ) }
{Platform.OS === 'ios' ? (
<NavigationBar
title="Services"
titleFontSize={standard => (standard ? 18 : 26)}
titleFontFamily={'Heebo-Bold'}
titleFontWeight="800"
titleColor={'#000000'}
largeTitle={true}
barTintColor={'#ffffff'}
navigationAccessibilityLabel="Services"
tintColor={'#05A550'}
>
<SearchBar
toolbar={false}
text={servicesSearchData}
autoCapitalize="none"
obscureBackground={false}
barTintColor={Platform.OS === 'android' ? '#dcdcdc' : null}
placeholder={(toolbar) => toolbar ? 'Search' : ''}
onChangeText={text => onChangeText(text)}
>
<SearchServices text={servicesSearchData} />
</SearchBar>
<StatusBar tintStyle="dark" barTintColor="white" />
</NavigationBar>
) : (
null
)
}
<ScrollView
contentInsetAdjustmentBehavior="automatic"
>
<FlatList
data={servicesSearchData}
ItemSeparatorComponent={spacepopularcontent}
ListEmptyComponent={<ListEmptyComponent />}
contentContainerStyle={{
flexGrow: 1,
paddingVertical: 16,
}}
contentInsetAdjustmentBehavior="automatic"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
nestedScrollEnabled={true}
bounces={true}
collapsable={false}
endFillColor={'transparent'}
keyboardDismissMode="on-drag"
renderItem={renderServices}
/>
</ScrollView>
</>
); }
export default ServiceScreen;
Wrap your SearchServices
in a ScrollView/FlatList
with contentInsetAdjustmentBehavior
set to true.
Also, you should move your SearchServices
component outside the render of ServiceScreen
.
const SearchServices = ({ text }) => (
<ScrollView contentInsetAdjustmentBehavior="automatic">
...
</ScrollView>
);
const ServiceScreen = () => {
const [text, setText] = useState('');
return (
<ScrollView contentInsetAdjustmentBehavior="automatic">
<NavigationBar>
<SearchBar
toolbar
text={text}
onChangeText={text => setText(text)}>
<SearchServices text={text} />
</SearchBar>
</NavigationBar>
</ScrollView>
);
}
Hi, its perfeectly working. Thanks soo much for your time. However, i couldnt search. Do i need to a function to search for item ?
Is it possibel you give a clear example ?
Thanks
The zoom sample shows the search in action. You need to use the search text
to filter your results.
Hi Graham, thanks soo much for your time. I still couldnt get how get the search to filter the items. Am able to use TextInput to do that so i will stick to that as this is taking almost two week to get it done.
Thanks soo much for your time and i really appreciate.
Don't give up now :( Have you tried using the text prop to filter the results?
Yes i did and its still not working. It will be wonderfull if i am able to use the native searchbar. Please below is the full code and you can paste it and see if you can do something about it for me. Am pulling the data from an api server so when you paste it anywhere you should get the same result am getting here.
import React, { useState, useEffect, useContext, useCallback, useMemo } from 'react'; import { View, StyleSheet, Text, Platform, Pressable, Image, FlatList, ActivityIndicator, SafeAreaView, Alert, ScrollView } from 'react-native'; import { NavigationContext } from 'navigation-react'; import { NavigationBar, StatusBar, CoordinatorLayout, SearchBar, TabBar, } from 'navigation-react-native';
function ServiceScreen() { const [isLoading, setisLoading] = useState(true); const [text, setText] = useState(''); const [servicesSearchData, setservicesSearchData] = useState("");
const { stateNavigator } = useContext(NavigationContext);
const dataservices = [ { 'id': '1', 'title': "Laboratory", 'field_services_image': './assets/images/hospitalfrontniew.jpg', 'created': 'Monday date' }, { 'id': '2', 'title': "Pharmacy", 'field_services_image': '/../../assets/images/hospitalfrontniew.jpg', 'created': 'Tuesday date' }, { 'id': '3', 'title': "X-Ray", 'field_services_image': '/../../assets/images/hospitalfrontniew.jpg', 'created': 'Wednesday date' }, { 'id': '4', 'title': "Ultrasound Scan", 'field_news_image': '/../../assets/images/hospitalfrontniew.jpg', 'created': 'Thurday date' }, { 'id': '5', 'title': "Theatre / Operation", 'field_news_image': '../../assets/images/hospitalfrontniew.jpg', 'created': 'Friday date' }, ]
const spacepopularcontent = () => { return ( <View style={{ width: '100%', height: 12, backgroundColor: 'transparent' }} /> ); };
useEffect(() => { const fetchCategories = () => { fetch('https://example.com/services-api-page') .then(jsonData => jsonData.json()) .then(data => { setisLoading(false); setservicesSearchData(data); setfilterservicesSearchData(data); }) .catch(error => { Alert.alert('Error', error); setisLoading(false); }); }; fetchCategories(); }, []);
const onChangeText = text => { let servicesDataFilter = filterservicesSearchData; let servicesSearchResult = servicesDataFilter.filter(itemData => itemData.title.toUpperCase().includes(text.toUpperCase()), ); setservicesSearchData(servicesSearchResult); };
const SearchServices = (item) => {
return (
// <FlatList
// data={servicesSearchData}
// ItemSeparatorComponent={spacepopularcontent}
// ListEmptyComponent={https://example.com${item.field_services_image}
,
}}
/>
<Text
style={{
color: '#3D3D3D',
fontFamily: 'Heebo-Bold',
fontWeight: '800',
fontSize: 17,
paddingVertical: 16,
}}>
{item.title}
)
};
const renderServices = useCallback(({ item }) => {
return (
<Pressable
key={item.nid}
style={{
backgroundColor: '#FFFFFF',
flexDirection: 'row',
width: '94%',
flexDirection: 'row',
marginHorizontal: 16,
padding: 12,
borderRadius: 6,
backgroundColor: '#FFFFFF',
alignSelf: 'center',
shadowColor: '#3D3D3D',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.1,
shadowRadius: 2.05,
elevation: 2,
}}
android_ripple={{ color: '#121212', borderless: false }}
onPress={() => {
stateNavigator.navigate('servicesDetails', {
dataitem: [item.field_services_image, item.title, item.view_node],
});
}}>
<Image
imageStyle={{ borderRadius: 10 }}
style={styles.servicesimageStyle}
source={{
uri: https://example.com${item.field_services_image}
,
}}
/>
<Text
style={{
color: '#3D3D3D',
fontFamily: 'Heebo-Bold',
fontWeight: '800',
fontSize: 17,
paddingVertical: 16,
}}>
{item.title}
)
});
const ListEmptyComponent = () => { return (
);
};
if (isLoading) { return (
);
}
return ( <> <ScrollView contentInsetAdjustmentBehavior="automatic" showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} contentContainerStyle={{ flexGrow: 1 }} automaticallyAdjustKeyboardInsets={true} keyboardShouldPersistTaps="always" bounces={true} focusable={true} endFillColor={"transparent"} centerContent={false}
{Platform.OS === 'android' ? ( <NavigationBar title="Services" titleFontSize={standard => (standard ? 18 : 28)} titleFontFamily={'Heebo-Bold'} titleFontWeight="800" titleColor={'#000000'} largeTitle={true} barTintColor={'red'} navigationAccessibilityLabel="Services" tintColor={'#ffffff'}
) : ( null ) }
{Platform.OS === 'ios' ? (
<NavigationBar
title="Services"
titleFontSize={standard => (standard ? 18 : 26)}
titleFontFamily={'Heebo-Bold'}
titleFontWeight="800"
titleColor={'#000000'}
largeTitle={true}
barTintColor={'#ffffff'}
navigationAccessibilityLabel="Services"
tintColor={'#05A550'}
>
<SearchBar
toolbar={false}
text={text}
autoCapitalize="none"
obscureBackground={false}
barTintColor={Platform.OS === 'android' ? '#dcdcdc' : null}
placeholder={(toolbar) => toolbar ? 'Search' : ''}
onChangeText={text => setText(text)}
>
<SearchServices text={text} />
</SearchBar>
<StatusBar tintStyle="dark" barTintColor="white" />
</NavigationBar>
) : (
null
)
}
<View collapsable={false}>
<FlatList
data={servicesSearchData}
ItemSeparatorComponent={spacepopularcontent}
ListEmptyComponent={<ListEmptyComponent />}
contentContainerStyle={{
flexGrow: 1,
paddingVertical: 16,
}}
contentInsetAdjustmentBehavior="automatic"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
nestedScrollEnabled={true}
bounces={true}
collapsable={false}
endFillColor={'transparent'}
keyboardDismissMode="on-drag"
renderItem={renderServices}
/>
</View>
</ScrollView>
</>
); }
const styles = StyleSheet.create({ SafeAreaView: { flex: 1, backgroundColor: '#0A1C34', }, Main: { flex: 1, backgroundColor: '#FAFAFA', position: 'relative', }, btnclick: { flex: 1, alignItems: 'center', marginBottom: 12, backgroundColor: '#ffffff', }, ActivityIndicatorView: { width: '100%', height: '100%', backgroundColor: 'white', alignItems: 'center', justifyContent: 'center', }, ImageStyleWrapper: { width: '100%', justifyContent: 'center', alignItems: 'center', margin: 10, }, ImageStyle: { width: '40%', height: 140, }, Title: { color: '#3D3D3D', fontSize: 16, marginBottom: 4, fontFamily: 'Heebo-Bold', }, catLoc1: { color: '#838B8B', fontSize: 14, fontFamily: 'Spartan-Bold', marginRight: 8, textDecorationLine: 'line-through', }, catLoc2: { color: '#FF9907', fontSize: 14, fontFamily: 'Spartan-Bold', }, locNTextBlock: { flexDirection: 'row', alignItems: 'center', paddingBottom: 12, }, categoryIcon: { width: 48, height: 48, backgroundColor: 'rgba(255,255,255,0.4)', borderRadius: 40, }, AnimatedImageView: { backgroundColor: '#000000', flex: 1, }, loaderView: { width: 74, height: 74, }, deliveryEstime: { fontSize: 20, marginBottom: 12, fontWeight: 'bold', color: '#ffffff', }, topBarBox: { width: '100%', height: 56, borderColor: 'transparent', borderWidth: 1, fontSize: 14, fontWeight: 'normal', fontFamily: 'Heebo-Medium', paddingHorizontal: 16, flexDirection: 'row', backgroundColor: '#F2F2F2', alignItems: 'center', alignSelf: 'center', borderRadius: 10, }, searchInputBox: { flex: 1, height: 56, borderColor: 'transparent', fontSize: 18, fontFamily: 'Heebo-Medium', fontWeight: '600', }, loadingEmptyContainer: { flex: 1, position: 'absolute', width: '100%', height: '100%', justifyContent: 'center', backgroundColor: '#FFFFFF' }, loadingEmptyContainer: { width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', alignSelf: 'center', }, loadingEmptyTxt: { color: '#555555', fontSize: 17, marginBottom: 16, fontFamily: 'GoogleSans-Bold', }, servicesimageStyle: { width: 165, height: 105, marginRight: 16, borderRadius: 6, }, servicesheaderTxtWrapper: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', }, searchIcon: { width: '8%', }, });
export default ServiceScreen;
I'm always happy to help, but I can't do it for you :(
Thanks for your time. I have tried to paste the zoom Grid.js example but am getting error colors is not defined. Can you check that? If am able to get that to work then its easier to understand.
Thanks
colors
is a string array. You can remove the colors
prop from Grid
component and paste this array at the top of the file instead
const colors = [
'maroon', 'red', 'crimson', 'orange', 'brown', 'sienna', 'olive',
'purple', 'fuchsia', 'indigo', 'green', 'navy', 'blue', 'teal', 'black'
];
Hi Graham, I have managed to get it working now. I changed the colors strings and it worked and then change colors strings to my fetched data and its working perfectly. The Navigation Router search is smooth and i love it.
Thanks you soo much for your time and i really appreciate.
Nice. Well done for keeping at it. Never give up and you'll get there. Glad I could help.
You should try the search on Android. It's super good, too.
Yeah sure. Am trying the android as well. I appreciate the encouragement. Thanks
Don't forget to use a Material3 theme
Hi, Thanks soo much for your time. Am really happy with the library and trust me its the best so far. Am having challenges using the search. I have tried everything i can but still cant get the search to filter to filter data when searching. I know am asking for too much but please help and i will be very grateful.
I checked the example you gave with zoom sample but still cant get it to work.
This has taken more than two weeks to get it working. I am able to get it working when i use the textinput but i want to use the native search with is much better.
Below is my code. Thanks in advance. Hopefully others will learn from this.
++++++++++++++++++++
++++++++++++++