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

RefinedSize { small, normal, large, extraLarge } improvements #42

Open
Turbozanik opened this issue Jul 5, 2022 · 0 comments
Open

RefinedSize { small, normal, large, extraLarge } improvements #42

Turbozanik opened this issue Jul 5, 2022 · 0 comments
Labels
enhancement New feature or request

Comments

@Turbozanik
Copy link

Turbozanik commented Jul 5, 2022

Hi @FilledStacks first of all, you have made a great lib that really helped with adapting UI for different devices.

Second, I wanted to highlite the possible improvement for the library which will, IMO make it way more usefull.

Right now screen sizes are stored as an enum, which prevents us from adding any logic related variables to those objects.
And also makes library really hard to scale and repetitive, in some places.

For example you have the same repetitive code for all device types:

    if (deviceScreenType == DeviceScreenType.tablet) {
      if (deviceWidth >= ResponsiveSizingConfig.instance.refinedBreakpoints.tabletExtraLarge) {
        return RefinedSizeExtraLarge();
      }

      if (deviceWidth >= ResponsiveSizingConfig.instance.refinedBreakpoints.tabletLarge) {
        return RefinedSizeLarge();
      }

      if (deviceWidth >= ResponsiveSizingConfig.instance.refinedBreakpoints.tabletNormal) {
        return RefinedSizeNormal();
      }
    }

Existing enums are really limiting the library.

As I see it, thise can be replaced by abstract class + child class with this function @override.
Just like this:


abstract class RefinedSize {
  RefinedSize(this.mDeviceScreenTypeWidgetSizeMultiplier, this.mDeviceScreenTypeTextSizeMultiplier,
      this.mDeviceWithinCategoryWidgetScaleFactor, this.mDeviceWithinCategoryTextScaleFactor);

  final double mDeviceScreenTypeWidgetSizeMultiplier;
  final double mDeviceScreenTypeTextSizeMultiplier;

  final double mDeviceWithinCategoryWidgetScaleFactor;
  final double mDeviceWithinCategoryTextScaleFactor;
}

class RefinedSizeSmall extends RefinedSize {
  RefinedSizeSmall(super.mDeviceScreenTypeMultiplier, super.mDeviceScreenTypeTextSizeMultiplier,
      super.mDeviceWithinCategoryWidgetScaleFactor, super.mDeviceWithinCategoryTextScaleFactor);
}

class RefinedSizeNormal extends RefinedSize {
  RefinedSizeNormal(super.mDeviceScreenTypeMultiplier, super.mDeviceScreenTypeTextSizeMultiplier,
      super.mDeviceWithinCategoryWidgetScaleFactor, super.mDeviceWithinCategoryTextScaleFactor);
}

class RefinedSizeLarge extends RefinedSize {
  RefinedSizeLarge(super.mDeviceScreenTypeMultiplier, super.mDeviceScreenTypeTextSizeMultiplier,
      super.mDeviceWithinCategoryWidgetScaleFactor, super.mDeviceWithinCategoryTextScaleFactor);
}

class RefinedSizeExtraLarge extends RefinedSize {
  RefinedSizeExtraLarge(super.mDeviceScreenTypeMultiplier, super.mDeviceScreenTypeTextSizeMultiplier,
      super.mDeviceWithinCategoryWidgetScaleFactor, super.mDeviceWithinCategoryTextScaleFactor);
}

// Usage 
// Mobile
    if (deviceScreenType == DeviceScreenType.mobile) {
      if (deviceWidth >= ResponsiveSizingConfig.instance.refinedBreakpoints.mobileExtraLarge) {
        return RefinedSizeExtraLarge(MOBILE_WIDGET_SIZE_MULTIPLIER, MOBILE_TEXT_SIZE_MULTIPLIER,
            MOBILE_EXTRA_LARGE_WIDGET_SIZE_MULTIPLIER, MOBILE_EXTRA_LARGE_TEXT_SIZE_MULTIPLIER);
      }

      if (deviceWidth >= ResponsiveSizingConfig.instance.refinedBreakpoints.mobileLarge) {
        return RefinedSizeLarge(MOBILE_WIDGET_SIZE_MULTIPLIER, MOBILE_TEXT_SIZE_MULTIPLIER, MOBILE_LARGE_WIDGET_SIZE_MULTIPLIER,
            MOBILE_LARGE_TEXT_SIZE_MULTIPLIER);
      }

      if (deviceWidth >= ResponsiveSizingConfig.instance.refinedBreakpoints.mobileNormal) {
        return RefinedSizeNormal(MOBILE_WIDGET_SIZE_MULTIPLIER, MOBILE_TEXT_SIZE_MULTIPLIER, MOBILE_NORMAL_WIDGET_SIZE_MULTIPLIER,
            MOBILE_NORMAL_TEXT_SIZE_MULTIPLIER);
      }
    }

As you can see RefinedSize is holding all the necessary information to scale the UI any way we want.

Now we can use a unified scaling function to scale your widget to corresponding screen size:

mixin SizeHelperMixin {

  static double getScaledWidgetSize(double widgetSize, RefinedSize size) {
    return size.mDeviceScreenTypeWidgetSizeMultiplier * size.getWidgetSizeMultiplier() * widgetSize;
  }

  static double getScaledTextSize(BuildContext context, double textSize, RefinedSize size) {
    return size.mDeviceScreenTypeTextSizeMultiplier *
        size.getTextSizeMultiplier() *
        MediaQuery.of(context).textScaleFactor *
        textSize;
  }
}


If all this would be implemented, any user of this library will be able to extend it for his needs.

That allowed me to create a common mixin for all size scaling function. And now I can scale not only by device type, but also by small/normal/large/xlarge devices.

Overall pros:

  1. I don't really have to remember, or search for scale factors.
  2. I don't need multiple dimens constans for each screen size.
  3. It became way more scalebale, I can add new strange screen scale factor(in case I will need to open it on an unusual device)
  4. Now we can scale not only by device "dimension" but also by small/normal/large/xlarge.
  5. In case if we have the same layout for both mobile/tablet/etc devices we can use a size scaling functon instead of copying the layout.
// Usage 

return getDataWidget(
                data: data,
                logoWidth: SizeHelperMixin.getScaledWidgetSize(Dimens.size200, sizingInformation.refinedSize),
                profileBorderRadius: SizeHelperMixin.getScaledWidgetSize(Dimens.size32, sizingInformation.refinedSize),
                profileImageRadius: SizeHelperMixin.getScaledWidgetSize(Dimens.size20, sizingInformation.refinedSize),
                profileNamePadding: EdgeInsets.only(top: SizeHelperMixin.getScaledWidgetSize(Dimens.size20, sizingInformation.refinedSize)),
                profileNameText: "Alisa",
                profileNameTextStyle: QuizTimeStyles.getScaledTextStyleWhite15(context),
                profileStatImageWidth: SizeHelperMixin.getScaledWidgetSize(Dimens.size20, sizingInformation.refinedSize),
                profileStartImagePadding: EdgeInsets.only(right: Dimens.size12),
                );

It's a lot to cover, so it seems to be a bit raw, tell me if you will have any questions/ideas, I can also share the changes I have made.

@Eimen2018 Eimen2018 added the enhancement New feature or request label Aug 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants