User Location Render Mode
Demonstates UserLocation render modes, follow modes
import React, { ReactNode, useState } from 'react';
import {
MapView,
CircleLayer,
UserLocation,
Camera,
UserLocationRenderMode as UserLocationRenderModeType,
UserTrackingMode,
} from '@rnmapbox/maps';
import { Button, Platform, SafeAreaView, View } from 'react-native';
import { ButtonGroup, Text } from '@rneui/base';
import { DEFAULT_CENTER_COORDINATE } from '../../utils';
import { ExampleWithMetadata } from '../common/ExampleMetadata'; // exclude-from-doc
const SettingsGroup = ({
children,
label,
}: {
children: ReactNode;
label: string;
}) => (
<View>
<Text style={{ textAlign: 'center', fontWeight: 'bold' }}>{label}</Text>
{children}
</View>
);
const styles = { matchParent: { flex: 1 } };
function humanize(name: string): string {
const words = name.match(/[A-Za-z][a-z]*/g) || [];
return words.map((i) => i.charAt(0).toUpperCase() + i.substring(1)).join(' ');
}
enum ExampleRenderMode {
Normal = 'normal',
Native = 'native',
CustomChildren = 'customChildren',
Hidden = 'hidden',
}
const ANDROID_RENDER_MODES: ('normal' | 'compass' | 'gps')[] = [
'normal',
'compass',
'gps',
];
const UserLocationRenderMode = () => {
const [renderMode, setRenderMode] = useState<ExampleRenderMode>(
ExampleRenderMode.Normal,
);
const [followUserLocation, setFollowUserLocation] = useState(true);
const [followUserMode, setFollowUserMode] = useState(UserTrackingMode.Follow);
const [showsUserHeadingIndicator, setShowsUserHeadingIndicator] =
useState(false);
const [androidRenderMode, setAndroidRenderMode] = useState<
'normal' | 'compass' | 'gps'
>('normal');
return (
<SafeAreaView style={styles.matchParent}>
<View>
<Button
title={
followUserLocation
? 'Don`t follow User Location'
: 'Follow user location'
}
onPress={() => setFollowUserLocation((prevState) => !prevState)}
/>
<Button
title={
showsUserHeadingIndicator
? 'Hide user heading indicator'
: 'Show user heading indicator'
}
onPress={() =>
setShowsUserHeadingIndicator((prevState) => !prevState)
}
/>
<SettingsGroup label="Follow User Mode">
<ButtonGroup
buttons={Object.values(UserTrackingMode)}
selectedIndex={Object.values(UserTrackingMode).indexOf(
followUserMode,
)}
onPress={(index) => {
setFollowUserMode(Object.values(UserTrackingMode)[index]);
}}
/>
</SettingsGroup>
{Platform.OS === 'android' && (
<SettingsGroup label="Android Render Mode">
<ButtonGroup
disabled={renderMode !== ExampleRenderMode.Native}
buttons={ANDROID_RENDER_MODES}
selectedIndex={ANDROID_RENDER_MODES.indexOf(androidRenderMode)}
onPress={(index) => {
setAndroidRenderMode(ANDROID_RENDER_MODES[index]);
}}
/>
</SettingsGroup>
)}
</View>
<MapView style={styles.matchParent} tintColor={'red'}>
<Camera
defaultSettings={{
centerCoordinate: DEFAULT_CENTER_COORDINATE,
zoomLevel: 18,
}}
followUserLocation={followUserLocation}
followUserMode={followUserMode}
followZoomLevel={18}
onUserTrackingModeChange={(event) => {
if (!event.nativeEvent.payload.followUserLocation) {
setFollowUserLocation(false);
}
}}
/>
<UserLocation
visible={renderMode !== ExampleRenderMode.Hidden}
renderMode={
renderMode === ExampleRenderMode.Native
? UserLocationRenderModeType.Native
: UserLocationRenderModeType.Normal
}
showsUserHeadingIndicator={showsUserHeadingIndicator}
androidRenderMode={androidRenderMode}
>
{renderMode === ExampleRenderMode.CustomChildren
? [
<CircleLayer
key="customer-user-location-children-red"
id="customer-user-location-children-red"
style={{ circleColor: 'red', circleRadius: 8 }}
/>,
<CircleLayer
key="customer-user-location-children-white"
id="customer-user-location-children-white"
style={{ circleColor: 'white', circleRadius: 4 }}
/>,
]
: undefined}
</UserLocation>
</MapView>
<ButtonGroup
buttons={Object.values(ExampleRenderMode).map(humanize)}
selectedIndex={Object.values(ExampleRenderMode).indexOf(renderMode)}
onPress={(index) => {
setRenderMode(Object.values(ExampleRenderMode)[index]);
}}
/>
</SafeAreaView>
);
};
export default UserLocationRenderMode;
}