UI controls
Map
All SDK distributions contain a standard set of React components for controlling the map. Add the components over MapView in a regular React Native layout and pass them the map instance from MapController.
The standard set includes:
- IndoorControl to switch floors.
- TrafficControl to display the traffic level and manage the visibility of traffic jams on the map.
- ZoomControl to scale the map.
- CompassControl to display the current map rotation angle relative to the north.
- MyLocationControl to fly to the current user location.
- CopyrightControl to display copyright inside MapView. The copyright appears automatically, you can configure its position using the
copyrightAlignmentandcopyrightEdgeInsetsproperties of MapViewProps.
import React from 'react';
import { StyleSheet, View } from 'react-native';
import {
CompassControl,
IndoorControl,
MapView,
MyLocationControl,
TrafficControl,
ZoomControl,
type MapControllerState,
} from '@2gis/dgis-mobile-sdk-full';
export function MapWithControls({
controllerState,
requestLocationPermission,
}: {
controllerState: MapControllerState;
requestLocationPermission: () => void;
}) {
const map =
controllerState.status === 'ready' ? controllerState.controller.map : null;
return (
<View style={styles.root}>
<MapView controllerState={controllerState} style={styles.map} />
{map !== null && (
<>
<View style={styles.rightControls}>
<TrafficControl map={map} />
<CompassControl map={map} />
<ZoomControl map={map} />
</View>
<View style={styles.leftControls}>
<IndoorControl map={map} />
<MyLocationControl
map={map}
onPermissionRequest={requestLocationPermission}
/>
</View>
</>
)}
</View>
);
}
const styles = StyleSheet.create({
root: { flex: 1 },
map: { flex: 1 },
rightControls: {
position: 'absolute',
right: 16,
bottom: 32,
gap: 8,
},
leftControls: {
position: 'absolute',
left: 16,
bottom: 32,
gap: 8,
},
});
To change the component colors, use the SDK factories:
import {
makeTrafficControlColors,
makeZoomControlColors,
} from '@2gis/dgis-mobile-sdk-full';
const palette = {
background: '#1F2937',
transparentBackground: 'rgba(31,41,55,0.6)',
primaryContent: '#FFFFFF',
tertiaryContent: '#9CA3AF',
quaternaryContent: '#4B5563',
activeContent: '#38BDF8',
lowAlert: '#22C55E',
mediumAlert: '#F59E0B',
highAlert: '#EF4444',
};
<TrafficControl map={map} colors={makeTrafficControlColors(palette)} />;
<ZoomControl map={map} colors={makeZoomControlColors(palette)} />;
Directory
The current React Native SDK does not export a ready-made search widget. You can implement a search bar and a result list in the application using SearchManager.suggest() and SearchManager.search().
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { FlatList, Text, TextInput, View } from 'react-native';
import {
SearchManager,
SuggestQueryBuilder,
type Context,
type Suggest,
} from '@2gis/dgis-mobile-sdk-full';
export function SearchBox({ context }: { context: Context }) {
const searchManager = useMemo(
() => SearchManager.createOnlineManager(context),
[context],
);
const [suggests, setSuggests] = useState<Suggest[]>([]);
const futureRef = useRef<ReturnType<SearchManager['suggest']> | null>(null);
useEffect(() => {
return () => {
futureRef.current?.destroy();
searchManager.destroy();
};
}, [searchManager]);
const onChangeText = (text: string) => {
if (text.trim() === '') {
setSuggests([]);
return;
}
futureRef.current?.destroy();
const query = SuggestQueryBuilder.fromQueryText(text).build();
const future = searchManager.suggest(query);
futureRef.current = future;
future.onComplete(
result => {
if (futureRef.current !== future) {
return;
}
futureRef.current = null;
setSuggests(result.suggests);
future.destroy();
},
error => {
if (futureRef.current !== future) {
return;
}
futureRef.current = null;
console.warn(error);
future.destroy();
},
);
};
return (
<View>
<TextInput onChangeText={onChangeText} />
<FlatList
data={suggests}
keyExtractor={(item, index) => `${item.title.text}-${index}`}
renderItem={({ item }) => <Text>{item.title.text}</Text>}
/>
</View>
);
}