Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase similarities between Android and iOS vibrations #53

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

guplem
Copy link

@guplem guplem commented Jun 18, 2024

Ina completely subjective manner, I've worked on trying to increase the similarities between Android and iOS vibration effects (imitating iOS on Android).

Before I felt many vibrations felt too "hard" on almost all Android devices, making it impossible to use the same package in both platforms.

This has been tested on OnePlus Nord 3, Redmi A2 and Samsung Galaxy S24 ultra. Obviously, the results differ, but my team was happy with them.

@guplem
Copy link
Author

guplem commented Jun 19, 2024

We've further tested with more devices and I have to admit that even though we believe the proposed update is slightly better, the results differ A LOT between devices.

  • Samsung high-end devices rumble a lot, even for "short vibrations" (with the intent of impacts).
  • Cheap devices cannot do "short impacts", they won't be noticeable at all.
  • OnePlus Nord devices seem to be none of the only ones that perform impacts and rumbles, but imitating the "soft" vibration or very light impacts is quite difficult (they feel almost the same from "soft" to "select" to "light")

That's why we have finally opted not to include vibration on Android, since we cannot ensure a proper feeling from them.

@Alvish0407
Copy link

We've further tested with more devices and I have to admit that even though we believe the proposed update is slightly better, the results differ A LOT between devices.

  • Samsung high-end devices rumble a lot, even for "short vibrations" (with the intent of impacts).
  • Cheap devices cannot do "short impacts", they won't be noticeable at all.
  • OnePlus Nord devices seem to be none of the only ones that perform impacts and rumbles, but imitating the "soft" vibration or very light impacts is quite difficult (they feel almost the same from "soft" to "select" to "light")

That's why we have finally opted not to include vibration on Android, since we cannot ensure a proper feeling from them.

What did you specifically do to opted out just for android while using this package ?
Maybe removed permission from manifest ?

@Alvish0407
Copy link

iOS haptics feel very soft.
But the android ones are not that much user friendly (at-least on the devices i have used)

@guplem
Copy link
Author

guplem commented Jul 15, 2024

What did you specifically do to opted out just for android while using this package ?

We essentially did a wrapper class that looks like this:

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:haptic_feedback/haptic_feedback.dart';

/// Enables you to provide haptic feedback in response to user interactions with the app.
/// The vibrations follow the iOS Human Interface Guidelines:
/// https://developer.apple.com/design/human-interface-guidelines/playing-haptics#iOS
class Vibrate {
  /// Indicates that a task or action has completed.
  static success({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.success);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.success);
  }

  /// Indicates that a task or action has produced a warning of some kind.
  static warning({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.warning);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.warning);
  }

  /// Indicates that an error has occurred.
  static error({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.error);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.error);
  }

  /// Indicates a collision between small or lightweight UI objects.
  static light({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.light);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.light);
  }

  /// Indicates a collision between medium-sized or medium-weight UI objects.
  static medium({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.medium);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.medium);
  }

  /// Indicates a collision between large or heavyweight UI objects.
  static heavy({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.heavy);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.heavy);
  }

  /// Indicates a collision between hard or inflexible UI objects.
  static rigid({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.rigid);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.rigid);
  }

  /// Indicates a collision between soft or flexible UI objects.
  static soft({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.soft);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.soft);
  }

  /// Indicates that a UI element’s values are changing.
  static selection({iOS = true, android = false}) {
    if (iOS && Platform.isIOS) Haptics.vibrate(HapticsType.selection);
    if ((android || kDebugMode) && Platform.isAndroid) Haptics.vibrate(HapticsType.selection);
  }
}

@nohli
Copy link
Owner

nohli commented Aug 29, 2024

@guplem thanks a lot for opening this PR

Since you tested and improved the patterns, it probably makes sense to merge your changes, what do you think? Or is there a regression in the ux for some devices?

Can you please replace line 50 with the following, and check, if it solves at least some issues. In case you've tested it on devices < Android 8, it is currently broken (this is the fix):

        // https://developer.android.com/reference/android/os/Vibrator#vibrate(long[],%20int)
        val zeroDelay = longArrayOf(0)
        val lengthsWithZeroDelay = zeroDelay + pattern.lengths
        vibrator.vibrate(lengthsWithZeroDelay, -1)

@guplem
Copy link
Author

guplem commented Sep 4, 2024

Hi! @nohli I don't feel comfortable merging the changes without your testing... As I've commented above, some devices worked better and some other worse...

So, if you can, please test it and subjectively decide if it's appropriate to merge these changes, but our UX team decided to remove android vibrations altogether. They detected that's a practice that some other companies do as well, like Glovo, an app that apparently has many vibrations in iOS.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants