Version 0.2.1 Alpha¶
Date de sortie : 15 juillet 2024
Statut : Version alpha
Build : 0.2.1
Vue d'ensemble¶
La version 0.2.1 marque une étape importante dans l'évolution de MINE - Indoor Navigation Engine. Elle introduit un système complet de composants UI qui améliore fortement l'expérience développeur et l'interface utilisateur finale. Cette version fournit des composants prêts à l'emploi, personnalisables et parfaitement intégrés à vos cartes.
Version alpha - Stable
Même si nous restons en alpha, cette version a été largement testée et est bien plus stable que la v0.1.0. L'API peut toutefois encore évoluer selon vos retours.
Points forts¶
-
Système de composants UI
Ensemble complet de composants préconstruits et personnalisables pour une meilleure UX
-
Support de thème
Mode sombre/clair intégré avec personnalisation complète
-
Bascule 3D/2D
Commutateur de vue carte élégant avec transitions fluides
-
Recherche intelligente
Barre de recherche avancée avec suggestions
Nouvelles fonctionnalités¶
Utilitaires de composants UI¶
Un système puissant d'utilitaires pour gérer et personnaliser les composants UI de votre interface de navigation.
Fonctionnalités clés :
- 🎨 Composants pré-stylés conformes aux guidelines Material Design
- 🔧 Personnalisation facile via des objets de configuration
- 📱 Layouts responsives qui s'adaptent aux tailles d'écran
- ♿ Accessibilité intégrée
- 🎭 Support d'animations pour des transitions fluides
Exemple d'utilisation :
import com.machinestalk.indoornavigationengine.ui.components.UIComponentManager
import com.machinestalk.indoornavigationengine.ui.components.ComponentConfig
class NavigationActivity : AppCompatActivity() {
private lateinit var componentManager: UIComponentManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialiser le gestionnaire de composants UI
componentManager = UIComponentManager(this).apply {
// Configurer le style des composants
setComponentConfig(ComponentConfig(
cornerRadius = 12.dp,
elevation = 4.dp,
animationDuration = 300,
enableHapticFeedback = true
))
}
}
}
import com.machinestalk.indoornavigationengine.ui.components.UIComponentManager;
import com.machinestalk.indoornavigationengine.ui.components.ComponentConfig;
public class NavigationActivity extends AppCompatActivity {
private UIComponentManager componentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialiser le gestionnaire de composants UI
componentManager = new UIComponentManager(this);
ComponentConfig config = new ComponentConfig.Builder()
.setCornerRadius(12)
.setElevation(4)
.setAnimationDuration(300)
.setEnableHapticFeedback(true)
.build();
componentManager.setComponentConfig(config);
}
}
Bouton de bascule carte 3D/2D¶
Un bouton élégant et animé permettant de passer sans effort de la vue 3D à la vue 2D.
Fonctionnalités :
- ✨ Animations de transition fluides
- 🎯 Mémorisation de la préférence utilisateur
- 📐 Position ajustable à l'écran
- 🎨 Icône et couleurs personnalisables
- 📱 Taille adaptée au tactile (48dp minimum)
Implémentation :
import com.machinestalk.indoornavigationengine.ui.components.MapSwitcherButton
// Ajouter le switcher à votre layout
val mapSwitcher = MapSwitcherButton(this).apply {
// Positionner le bouton
setPosition(MapSwitcherButton.Position.TOP_RIGHT)
// Personnaliser l'apparence
setIconTint(Color.WHITE)
setBackgroundColor(Color.parseColor("#2196F3"))
setElevation(8.dp)
// Gérer les changements de mode
setOnViewModeChangedListener { mode ->
when (mode) {
ViewMode.MODE_3D -> {
Toast.makeText(context, "Passage en 3D", Toast.LENGTH_SHORT).show()
}
ViewMode.MODE_2D -> {
Toast.makeText(context, "Passage en 2D", Toast.LENGTH_SHORT).show()
}
}
}
}
// Ajouter à la scène
sceneView.addUIComponent(mapSwitcher)
<com.machinestalk.indoornavigationengine.ui.components.MapSwitcherButton
android:id="@+id/mapSwitcher"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:iconTint="@color/white"
app:buttonBackground="@color/primary"
app:elevation="8dp" />
États visuels :
| État | Icône | Description |
|---|---|---|
| Mode 3D | 🗺️ |
Vue perspective 3D |
| Mode 2D | 🗂️ |
Vue 2D en plongée |
| Transition | ⏳ |
Animation en cours |
Barre de recherche avec menu déroulant¶
Une interface de recherche puissante avec autocomplétion intelligente et suggestions.
Capacités :
- 🔍 Suggestions en temps réel
- 📍 Recherche par nom de POI, catégorie ou position
- 🎯 Éléments récemment recherchés
- 🗂️ Résultats catégorisés
- ⌨️ Navigation clavier
- 📱 Intégration recherche vocale (optionnelle)
Implémentation :
import com.machinestalk.indoornavigationengine.ui.components.SearchBar
import com.machinestalk.indoornavigationengine.ui.components.SearchResult
val searchBar = SearchBar(this).apply {
// Texte d'aide
setHint("Rechercher lieux, boutiques ou services")
// Activer la recherche vocale
enableVoiceSearch = true
// Fournisseur de recherche
setSearchProvider { query ->
// Retourner les résultats
searchPOIs(query)
}
// Sélection d'un résultat
setOnResultSelectedListener { result ->
// Naviguer vers la position sélectionnée
navigateToLocation(result.location)
}
// Configurer l'apparence du dropdown
setDropdownConfig(DropdownConfig(
maxResults = 10,
showCategories = true,
showIcons = true,
groupByCategory = true
))
}
// Ajouter au layout
sceneView.addUIComponent(searchBar)
// Exemple de fonction de recherche
fun searchPOIs(query: String): List<SearchResult> {
return poiManager.search(query).map { poi ->
SearchResult(
id = poi.id,
title = poi.name,
subtitle = poi.category,
icon = getCategoryIcon(poi.category),
location = poi.position
)
}
}
import com.machinestalk.indoornavigationengine.ui.components.SearchBar;
import com.machinestalk.indoornavigationengine.ui.components.SearchResult;
SearchBar searchBar = new SearchBar(this);
searchBar.setHint("Rechercher lieux, boutiques ou services");
searchBar.setEnableVoiceSearch(true);
// Fournisseur de recherche
searchBar.setSearchProvider(query -> {
return searchPOIs(query);
});
// Gestion de la sélection
searchBar.setOnResultSelectedListener(result -> {
navigateToLocation(result.getLocation());
});
// Ajouter à la scène
sceneView.addUIComponent(searchBar);
Catégories de résultats :
- 🏪 Boutiques & magasins
- 🍽️ Restaurants & cafés
- 🚻 Services & équipements
- 🚪 Entrées & sorties
- 🅿️ Parkings
- 🚶 Points d'intérêt
Bouton de localisation actuelle¶
Un bouton mis en avant qui centre la carte sur la position de l'utilisateur.
Fonctionnalités :
- 📍 Animation fluide vers la position utilisateur
- 🔄 Rafraîchissement automatique de la localisation
- 🎨 Icône et style personnalisables
- 💫 Animation pulsée en mode actif
- ⚠️ Gestion des permissions intégrée
Implémentation :
import com.machinestalk.indoornavigationengine.ui.components.CurrentLocationButton
val locationButton = CurrentLocationButton(this).apply {
// Positionner le bouton
setPosition(CurrentLocationButton.Position.BOTTOM_RIGHT)
setMargin(16.dp)
// Personnaliser l'apparence
setIconTint(Color.WHITE)
setBackgroundColor(Color.parseColor("#4CAF50"))
// Animation pulsée quand suivi actif
enablePulseAnimation = true
// Gestion des mises à jour de position
setOnLocationUpdateListener { location ->
sceneView.animateCameraToLocation(
location = location,
duration = 500,
zoom = 18f
)
}
// Gestion des refus de permission
setOnPermissionDeniedListener {
showPermissionDialog()
}
}
sceneView.addUIComponent(locationButton)
@Composable
fun MapWithLocationButton() {
Box(modifier = Modifier.fillMaxSize()) {
IndoorNavigationScene(
mapBuild = mapData,
modifier = Modifier.fillMaxSize()
)
CurrentLocationButton(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(16.dp),
onLocationClick = { location ->
// Gestion du clic localisation
}
)
}
}
Support des composants UI personnalisés¶
Créez vos propres composants UI intégrés au moteur de navigation.
Classes de base :
BaseUIComponent- Fondement de tous les composants UIOverlayComponent- Pour les overlays flottantsPanelComponent- Pour les panneaux et feuillesButtonComponent- Pour les boutons personnalisésIndicatorComponent- Pour les indicateurs d'état
Exemple de composant personnalisé :
import com.machinestalk.indoornavigationengine.ui.components.BaseUIComponent
class FloorSelectorComponent(context: Context) : BaseUIComponent(context) {
private val floorButtons = mutableListOf<Button>()
init {
setupLayout()
}
private fun setupLayout() {
// Créer un layout personnalisé
val layout = LinearLayout(context).apply {
orientation = LinearLayout.VERTICAL
setPadding(8.dp, 8.dp, 8.dp, 8.dp)
}
// Ajouter dynamiquement les boutons d'étage
addView(layout)
}
fun setFloors(floors: List<Floor>) {
floorButtons.clear()
floors.forEach { floor ->
val button = Button(context).apply {
text = floor.name
setOnClickListener {
onFloorSelected(floor)
}
}
floorButtons.add(button)
}
}
override fun onAttached(sceneView: MineSceneView) {
// Composant attaché à la scène
super.onAttached(sceneView)
}
override fun onDetached() {
// Nettoyage
super.onDetached()
}
}
Support mode sombre/clair¶
Basculement automatique du thème selon les préférences système avec options de personnalisation complètes.
Fonctionnalités :
- 🌓 Détection automatique du thème système
- 🎨 Transitions de thème fluides
- 💾 Persistance de la préférence utilisateur
- 🖌️ Surcharges de thème par composant
- 🎭 Schémas de couleurs personnalisés
Implémentation :
import com.machinestalk.indoornavigationengine.ui.theme.ThemeManager
import com.machinestalk.indoornavigationengine.ui.theme.ThemeMode
// Configurer le gestionnaire de thème
val themeManager = ThemeManager(this).apply {
// Suivre le thème système (par défaut)
setThemeMode(ThemeMode.SYSTEM)
// Ou forcer un mode
// setThemeMode(ThemeMode.LIGHT)
// setThemeMode(ThemeMode.DARK)
// Écouter les changements de thème
setOnThemeChangedListener { mode ->
when (mode) {
ThemeMode.LIGHT -> applyLightTheme()
ThemeMode.DARK -> applyDarkTheme()
}
}
}
fun applyLightTheme() {
sceneView.setThemeConfig(ThemeConfig(
primaryColor = Color.parseColor("#2196F3"),
backgroundColor = Color.WHITE,
textColor = Color.BLACK,
mapBackgroundColor = Color.parseColor("#F5F5F5")
))
}
fun applyDarkTheme() {
sceneView.setThemeConfig(ThemeConfig(
primaryColor = Color.parseColor("#1976D2"),
backgroundColor = Color.parseColor("#121212"),
textColor = Color.WHITE,
mapBackgroundColor = Color.parseColor("#1E1E1E")
))
}
Palettes de couleurs :
| Élément | Couleur | Usage |
|---|---|---|
| Primaire | #2196F3 |
Boutons, accents |
| Arrière-plan | #FFFFFF |
Fond principal |
| Surface | #F5F5F5 |
Cartes, panneaux |
| Texte primaire | #212121 |
Texte principal |
| Texte secondaire | #757575 |
Sous-titres |
| Élément | Couleur | Usage |
|---|---|---|
| Primaire | #1976D2 |
Boutons, accents |
| Arrière-plan | #121212 |
Fond principal |
| Surface | #1E1E1E |
Cartes, panneaux |
| Texte primaire | #FFFFFF |
Texte principal |
| Texte secondaire | #B0B0B0 |
Sous-titres |
Thèmes personnalisés¶
Créez des thèmes sur-mesure alignés à votre identité visuelle.
Configuration de thème :
import com.machinestalk.indoornavigationengine.ui.theme.CustomTheme
val brandTheme = CustomTheme.Builder()
// Couleurs de marque
.setPrimaryColor(Color.parseColor("#FF5722"))
.setSecondaryColor(Color.parseColor("#FFC107"))
.setAccentColor(Color.parseColor("#4CAF50"))
// Arrière-plans
.setBackgroundColor(Color.WHITE)
.setSurfaceColor(Color.parseColor("#F5F5F5"))
// Couleurs de texte
.setTextPrimaryColor(Color.parseColor("#212121"))
.setTextSecondaryColor(Color.parseColor("#757575"))
// Style des composants
.setCornerRadius(16.dp)
.setElevation(8.dp)
// Style de carte
.setPathColor(Color.parseColor("#4CAF50"))
.setPathWidth(10f)
.setPoiMarkerColor(Color.parseColor("#FF5722"))
// Typographie
.setFontFamily(R.font.custom_font)
.setTextSizeLarge(20.sp)
.setTextSizeMedium(16.sp)
.setTextSizeSmall(14.sp)
.build()
// Appliquer le thème personnalisé
sceneView.setCustomTheme(brandTheme)
Prévisualisation du thème :
// Activer l'aperçu du thème en debug
if (BuildConfig.DEBUG) {
ThemeManager.showThemePreview(this, brandTheme)
}
Corrections de bugs¶
Problème d'affichage des composants UI¶
Problème : Les composants UI pouvaient disparaître ou se rendre incorrectement après une rotation d'écran ou un retour depuis l'arrière-plan.
Cause racine : Gestion de cycle de vie insuffisante dans le système d'attachement des composants.
Résolution : - Restauration d'état pour tous les composants UI - Gestion des composants sensible au cycle de vie - Meilleure gestion de la hiérarchie de vues - Amélioration de la gestion mémoire lors des changements de configuration
Impact : Les composants conservent désormais état et position de façon fiable sur tous les événements de cycle de vie.
Avant :
// Les composants pouvaient perdre leur état à la rotation
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Les composants disparaissaient
}
Après :
// Les composants restaurent leur état automatiquement
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Les composants maintiennent état et position
componentManager.restoreState()
}
Problèmes du bouton de bascule 3D/2D¶
Problème : Le bouton de bascule rencontrait plusieurs soucis : - Événements tactiles parfois non pris en compte - Saccades d'animation pendant les transitions - Position incorrecte sur certains écrans - État non persistant entre sessions
Résolution : - Cible tactile portée à 48dp pour l'accessibilité - Animations optimisées avec accélération matérielle - Positionnement responsive - Persistance des préférences via SharedPreferences
Modifications techniques :
// Amélioration de la gestion tactile
mapSwitcher.apply {
minimumWidth = 48.dp
minimumHeight = 48.dp
// Animations accélérées matériellement
setLayerType(View.LAYER_TYPE_HARDWARE, null)
// Transitions fluides
animate()
.alpha(1f)
.setDuration(200)
.setInterpolator(FastOutSlowInInterpolator())
}
Impact sur les performances : - Fréquence d'animation passée de ~45fps à 60fps stables - Temps de réponse tactile réduit de 40%
Problèmes connus¶
Mise en page du bottom sheet sur petits écrans¶
Problème de layout
Gravité : Moyenne
Plateformes : Petits écrans (< 5,5" diagonale)
Statut : Correctif prévu pour v0.3.0
Description : Le bottom sheet peut ne pas s'afficher de façon optimale sur les petits écrans, avec du contenu qui dépasse parfois la zone visible.
Scénarios concernés : - Résultats de recherche volumineux - Fiches POI très détaillées - Panneaux de sélection multi-étages
Contournement actuel :
// Limiter le contenu du bottom sheet sur petits écrans
if (isSmallScreen()) {
bottomSheet.apply {
maxHeight = screenHeight * 0.6f
enableScrolling = true
showExpandButton = true
}
}
fun isSmallScreen(): Boolean {
val displayMetrics = resources.displayMetrics
val screenHeight = displayMetrics.heightPixels / displayMetrics.density
return screenHeight < 640
}
Statut : Nous refondons le layout du bottom sheet pour mieux gérer les petits écrans. Le correctif inclura : - Calcul adaptatif de la hauteur - Meilleur comportement de scroll - Sections repliables pour contenus longs
Position de la barre de recherche sur écrans moyens¶
Problème de position
Gravité : Faible
Plateformes : Écrans moyens (smartphones 5,5" - 7" tablettes)
Statut : En investigation
Description : Sur certains écrans moyens (notamment petites tablettes), la barre de recherche peut être légèrement décalée, surtout en paysage.
Impact : - Possible chevauchement avec d'autres éléments UI - Zone tactile partiellement masquée - Alignement visuel imparfait
Contournement temporaire :
// Ajustement manuel sur écrans moyens
searchBar.apply {
if (isMediumScreen() && isLandscape()) {
setMargin(
top = 8.dp,
start = 16.dp,
end = 16.dp
)
}
}
fun isMediumScreen(): Boolean {
val screenSize = resources.configuration.screenLayout and
Configuration.SCREENLAYOUT_SIZE_MASK
return screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE
}
Statut : Nous étudions un système de positionnement unifié pour toutes tailles et orientations d'écran.
Mise à niveau depuis v0.1.0¶
Changements majeurs¶
⚠️ Aucun breaking change — Cette version est rétrocompatible avec v0.1.0.
Étapes de migration¶
- Mettre à jour la dépendance
=== "Gradle (Kotlin)"
```kotlin
dependencies {
implementation("com.machinestalk:indoornavigationengine:0.2.1-alpha")
}
```
=== "Gradle (Groovy)"
```groovy
dependencies {
implementation 'com.machinestalk:indoornavigationengine:0.2.1-alpha'
}
```
-
Synchroniser et reconstruire
./gradlew clean build -
Optionnel : ajouter les nouveaux composants UI
// Ajouter les nouveaux composants à votre app sceneView.addUIComponent(MapSwitcherButton(this)) sceneView.addUIComponent(SearchBar(this)) sceneView.addUIComponent(CurrentLocationButton(this))
Mises à jour recommandées¶
Même si non obligatoires, nous conseillons d'adopter les nouvelles fonctionnalités :
// Avant (v0.1.0)
val sceneView = MineSceneView(this)
setContentView(sceneView)
// Après (v0.2.1) - avec les nouveaux composants UI
val sceneView = MineSceneView(this).apply {
// Ajouter les composants UI
addUIComponent(MapSwitcherButton(context))
addUIComponent(SearchBar(context))
addUIComponent(CurrentLocationButton(context))
// Activer le support de thème
ThemeManager(context).setThemeMode(ThemeMode.SYSTEM)
}
setContentView(sceneView)
Tests & qualité¶
Couverture de test¶
| Fonctionnalité | Couverture | Statut |
|---|---|---|
| Composants UI | 87% | ✅ OK |
| Système de thème | 92% | ✅ OK |
| Fonctionnalité de recherche | 85% | ✅ OK |
| Commutateur de carte | 90% | ✅ OK |
| Services de localisation | 78% | ⚠️ Partiel |
Matrice de test appareils¶
| Catégorie d'appareil | Tailles d'écran | Versions Android | Statut |
|---|---|---|---|
| Téléphones (petits) | 4,7" - 5,5" | 9 - 14 | ⚠️ Problèmes mineurs |
| Téléphones (grands) | 5,5" - 6,7" | 9 - 14 | ✅ OK |
| Tablettes (7") | 7" - 8" | 10 - 14 | ⚠️ Problèmes mineurs |
| Tablettes (10"+) | 10" - 12" | 10 - 14 | ✅ OK |
Métriques de performance¶
| Métrique | v0.1.0 | v0.2.1 | Amélioration |
|---|---|---|---|
| Temps de chargement initial | 2.8s | 2.1s | ⬇️ 25% |
| Utilisation mémoire | 145MB | 128MB | ⬇️ 12% |
| Framerate | 45fps | 58fps | ⬆️ 29% |
| Rendu des composants | 180ms | 95ms | ⬇️ 47% |
Et après - v0.3.0¶
Nous travaillons déjà sur la prochaine version ! Au programme :
Fonctionnalités confirmées¶
- 🗺️ Navigation multi-étages - Navigation fluide entre niveaux
- 📍 Catégories de POI - Catégorisation et filtrage enrichis
- 🎯 Optimisation d'itinéraire - Algorithmes plus rapides
- 🔔 Notifications - Prompts de navigation in-app
- 📊 Analytics - Suivi d'usage et insights
À l'étude¶
- 🌐 Cartes hors-ligne - Support complet offline
- 🎤 Navigation vocale - Instructions audio
- ♿ Itinéraires accessibles - Parcours sans obstacles
- 🎮 Mode AR - Overlay de navigation en réalité augmentée
Planning¶
Sortie prévue : T4 2024
Retours & support¶
Vos retours guident notre développement !
-
Signaler un bug
Un bug ? Aidez-nous à le corriger !
-
Demander une fonctionnalité
Une idée ?
-
Obtenir de l'aide
Besoin d'assistance ?
-
Documentation
Explorez les guides et l'API
Ressources supplémentaires¶
- 📖 Guide des composants UI - Documentation détaillée des composants
- 🎨 Personnalisation des thèmes - Guide complet de thématisation
- 🚀 Guide de démarrage rapide - Pour démarrer vite
- 💻 Exemples d'usage - Exemples complets
- ❓ FAQ - Questions fréquentes
- 🐛 Dépannage - Problèmes courants et solutions