DEV Community

Cover image for Enhancing the Map Widget in Ensemble: Introducing Fixed & Draggable Markers 🚀
Sharjeel Yunus
Sharjeel Yunus

Posted on • Edited on

Enhancing the Map Widget in Ensemble: Introducing Fixed & Draggable Markers 🚀

At Ensemble, we’re constantly looking for ways to enhance developer experience by making our low-code/no-code framework more intuitive and powerful. Recently, I worked on upgrading our Map Widget to introduce two powerful new features that simplify the location selection and marker interactions:

fixedMarker: Pins a marker at the map’s center, letting users navigate the map beneath it.

draggableMarker: Empowers users to drag and reposition markers freely.

These features address critical user needs while boosting flexibility. Let’s dive into why we built them, how they work under the hood, and how you can leverage them in your apps.


🎯 Why We Built These Features

Previously, our Map Widget’s markers were static, forcing users to jump through hoops to adjust locations. Here’s what drove our update:

1️⃣ Simplifying Precise Location Selection

  • Problem: Apps like delivery services or property listings require pinpoint accuracy. Moving static markers was cumbersome.
  • Solution: fixedMarker keeps the marker centered while users pan the map, making location selection seamless.

2️⃣ Enabling Manual Marker Placement

  • Problem: Use cases like marking custom meeting points needed manual drag-and-drop flexibility.
  • Solution: draggableMarker lets users reposition markers intuitively with a simple drag.

🚀 Under the Hood: Implementing the Features

📍 fixedMarker: Always Center Stage

Step 1: Centralizing Marker Data

We created a unified class to manage the marker’s position and icon, ensuring consistency and reducing rendering overhead.

class FixedMarker {
  LatLng position;
  BitmapDescriptor? icon;

  FixedMarker({required this.position, this.icon});
}

// Initialize with a default position
FixedMarker _fixedMarker = FixedMarker(position: widget.controller.defaultCameraLatLng);
Enter fullscreen mode Exit fullscreen mode

Step 2: Optimizing Position Updates

By updating the marker’s position only when it changes (and debouncing map movements), we eliminated flickering and improved performance.

void _onCameraMove(CameraPosition position) {
  if (widget.controller.onCameraMove != null) {
    _cameraMoveDebouncer.run(() async {
      LatLngBounds bounds =
          await (await _controller.future).getVisibleRegion();
      _executeCameraMoveAction(widget.controller.onCameraMove!, bounds);
    });
  }

  // Only update the position if it's different
  if (widget.controller.fixedMarker &&
      _fixedMarker.position != position.target) {
    setState(() {
      _fixedMarker.position = position.target;
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

🖱️ draggableMarker: Freedom to Drag and Drop

Enabling Marker Drag

We added a flag to toggle drag functionality and linked it to an event handler that updates the marker’s stored position after movement. The marker’s new position is persisted in real-time, allowing seamless integration with other app components.

markerPayload.marker = Marker(
  markerId: markerId,
  position: markerPayload.latLng,
  icon: markerAsset ?? BitmapDescriptor.defaultMarker,
  draggable: widget.controller.draggableMarker, // Enables dragging
  consumeTapEvents: true,
  onDrag: (latLng) {
    _moveCamera(latLng); // Update position on drag
  },
  onTap: () {
    _selectMarker(markerId);
  },
);
Enter fullscreen mode Exit fullscreen mode

🛠️ How to Use These Features in Your Ensemble App

Enable fixedMarker

Keep the marker centered while panning by setting fixedMarker: true in your Map configuration.

Map:
  fixedMarker: true
Enter fullscreen mode Exit fullscreen mode

Enable draggableMarker

Allow users to drag markers freely with draggableMarker: true.

Map:
  draggableMarker: true
Enter fullscreen mode Exit fullscreen mode

Combine Both for Ultimate Flexibility

Enable both flags to let users start with a centered marker that becomes draggable on demand.

Map:
  fixedMarker: true
  draggableMarker: true
Enter fullscreen mode Exit fullscreen mode

🚀 Ready to Try It Yourself?

Explore these features in Ensemble Studio or dive deeper into our documentation:


🔑 Lessons Learned

1️⃣ Debounce Strategically: Throttling camera move events reduced redundant state updates.

2️⃣ Optimize Marker Caching: Centralizing marker data streamlined state management.

3️⃣ Prioritize Developer Control: Clear configuration flags let developers tailor interactions to their app’s needs.


🌟 What’s Next?

We’re just getting started! What features would you like to see in the Map Widget?

  • Live location tracking?
  • Customizable gesture controls?

Let us know in the comments below! 💬

🚀 Happy building!

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay