resolveAssetPathForPixelRatio function

Future<String> resolveAssetPathForPixelRatio(
  1. String assetPath, {
  2. double? devicePixelRatio,
})

Resolves asset path based on device pixel ratio, similar to Flutter's automatic asset selection.

Flutter automatically picks assets from folders like:

  • icons/ (1x)
  • icons/2.0x/ (2x)
  • icons/3.0x/ (3x)

This function does the same for native platform views:

  1. Tries to find asset at the exact pixel ratio (e.g., 3.0x for @3x devices)
  2. If not found, picks the closest bigger size
  3. Falls back to the original path if no resolution-specific asset is found
  • assetPath: The base asset path (e.g., "assets/icons/checkcircle.png")
  • devicePixelRatio: Optional device pixel ratio (defaults to current device)
  • Returns: Resolved asset path or original path if no resolution-specific asset found

Implementation

Future<String> resolveAssetPathForPixelRatio(
  String assetPath, {
  double? devicePixelRatio,
}) async {
  // Get device pixel ratio if not provided
  final pixelRatio = devicePixelRatio ??
      ui.PlatformDispatcher.instance.views.first.devicePixelRatio;

  // Round to nearest 0.5 (1.0, 1.5, 2.0, 2.5, 3.0, etc.)
  final roundedRatio = (pixelRatio * 2).round() / 2.0;

  // Extract directory and filename from path
  final pathParts = assetPath.split('/');
  if (pathParts.isEmpty) return assetPath;

  final fileName = pathParts.last;
  final directory = pathParts.length > 1
      ? pathParts.sublist(0, pathParts.length - 1).join('/')
      : '';

  // Try exact ratio first (e.g., 3.0x)
  final exactRatioPath = roundedRatio == 1.0
      ? assetPath
      : '$directory/${roundedRatio}x/$fileName';

  if (await _assetExists(exactRatioPath)) {
    return exactRatioPath;
  }

  // If exact ratio not found, try to find closest bigger size
  // Common ratios: 1.0, 1.5, 2.0, 2.5, 3.0, 4.0
  final possibleRatios = [1.0, 1.5, 2.0, 2.5, 3.0, 4.0];

  // Find all bigger ratios
  final biggerRatios = possibleRatios
      .where((r) => r > roundedRatio)
      .toList()
    ..sort();

  // Try each bigger ratio until we find one that exists
  for (final ratio in biggerRatios) {
    final ratioPath = ratio == 1.0
        ? assetPath
        : '$directory/${ratio}x/$fileName';
    if (await _assetExists(ratioPath)) {
      return ratioPath;
    }
  }

  // Fallback to original path
  return assetPath;
}