超级响应式


一个Flutter响应式库,它

  • 易于使用且易于阅读
  • 使您的应用在所有设备上看起来都很棒
  • 使您的应用更易读
  • 使您的应用更易于维护

入门

欢迎来到Super Responsive!!!

入门非常简单。

首先,将您的应用包装在Super Responsive widget中。

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SuperResponsive(
      breakPoints: BreakPoints(
        // you can add up to 6 breakpoints
        // first and second are required!
        first: 1200,
        second: 900,
        third: 600,
      ),
      child: MaterialApp(
        title: 'Super Responsive App',
        initialRoute: '/',
      ),
    );
  }
}

然后您将能够使用我们的所有功能!!!

响应式值

– responsiveValue()

为了获得响应式设计,我们应该有一个响应式的值。
这个值可以是我们指定的任何范围,例如

如果我们想让一个容器的宽度在500和100之间,这意味着
当我们的屏幕宽度等于或大于
我们的第一个断点时,容器的宽度将为500,当我们的屏幕宽度等于
或小于我们的最后一个断点时(这将是最后一个断点
我们指定的)。

...
/// in a more graphical way
/// breakpoints extremes -> [600, 1200]
/// our value's range -> [100, 500]
/// when screen width == 800 in the range of [600, 1200], 
/// this value will be mapped to the range of [100, 500]
/// and it will return the value = 233.333
/// all this calculation is made by the (mapValue) function,
/// that can also be used by you in any way you want to.

@override
Widget build(BuildContext context) {
  return Container(
    width: context.responsiveValue(100, 500),
    height: 300,
    color: Colors.red,
  );
}
...

– breakpoints.when()

如果您不想以这种方式计算该值,而是想根据当前断点分配
特定值,您可以在Breakpoints类中使用when
方法。

...
@override
Widget build(BuildContext context) {
  return Container(
    // context.breakpoints will return the breakpoints
    // of the closest SuperResponsive widget in the widget tree
    width: context.breakpoints.when(
      first: (breakpoint) => breakpoint*0.5, // 50% of the breakpoint
      second: (_) => 300, // 300px
      third: (_) => context.responsiveValue(100, 300), // or a responsive value
      fourth: (_) => 50, // we don't have a fourth breakpoint in our SuperResponsive widget,
      // so it will return the last valid case, in this case third: (_) => context.responsiveValue(100, 300)
    ),
    height: 300,
    color: Colors.red,
  );
}
...

– customResponsiveValue()

也可以使用自定义响应式值。
它将根据您指定的新的断点范围
和值范围来计算该值。

...
@override
Widget build(BuildContext context) {
  return Container(
    width: context.customReponsiveValue(
    // you can use some of your breakpoints, or any
    // other value that you want
    breakpointsRange: (breakPoints) => 
        Range(breakpoints.second, breakpoints.first),
    valueRange: Range(100, 500),
  ),
    height: 300,
    color: Colors.red,
  );
}
...

响应式 Widget

...
@override
Widget build(BuildContext context) {
  return ResponsiveWidget(
    // The amount of widgets must be equal to the amount 
    // of breakpoints we have specified in our SuperResponsive widget
    children: [
      WidgetLarge(),
      WidgetMedium(),
      WidgetSmall(),
    ],
    // ! we can also specify new breakpoints for only this widget
    // ! this will override the breakpoints of the SuperResponsive widget
    // ! and the amount of children must be equal to these new breakpoints
    // breakpoints: BreakPoints(
    //   first: 1000,
    //   second: 800,
    //   third: 500,
    // ),
  );
}
...

ResponsiveText

...
@override
Widget build(BuildContext context) {
  return ResponsiveText(
    text: "Super Responsive",
    fontSizeRange: Range(20, 30),
    // ! we can also specify custom breakpoints for only this widget
    // ! this means that the result of the responsive value set 
    // ! for the font size, will be set to the closest value of the
    // ! textBreakpoints. For example, if the value should be
    // ! 17, it will be set to 17 because it is the closest value from the 
    // ! set of textBreakpoints 
    // textBreakpoints: [
    // 30,
    // 15,
    // 20,
    // ]
  );
}
...

Responsive Gap

...
@override
Widget build(BuildContext context) {
  // ! it'll return a SizedBox square with dimension equal
  // ! to the responsive value of range [100, 300]
  return ResponsiveGap(100, 300);
  
  // ! you can also create an "INVERSE" gap, which will 
  // ! have as a dimension the inverse value. For example,
  // ! if the value is 300 and the range is [100, 300],
  // ! it will have a final value of 100
  return ResponsiveGap(100, 300, reversed: true);
}
...

响应式布局

使用这个widget,您将能够编写复杂的布局
并使它们更易于阅读、理解和维护。

概念很简单,指定您想要的布局数量,子项
这些布局可用的,您的断点(通常是您的SuperResponsive断点)
然后是您的布局。

...
@override
Widget build(BuildContext context) {
  return ResponsiveLayout(
    layoutCount: 3,
    children: [
      Widget0(),
      Widget1(),
      Widget2(),
      Widget3(),
      Widget4(),
    ],
    // ! you can use any breakpoints you want
    breakpoints: (breakpoints) => breakpoints,
    layouts: (child) => [
      // ! Some complex layout with multiple Rows and Columns
      Column(
        children: [
          // ! the function child() will return the child 
          // ! of that specific index => child(0) == Widget0()
          Row(children:[child(1), child(0)]).expanded(),
          // ! .expanded({int flex}) is an extension on Widget
          // ! it can be used if you want to wrap your widget inside 
          // ! an Expanded widget, it has been mainly created to make your
          // ! layout more readable and to be used by Columns or Rows
          Row(children:[child(2), child(2)]).expanded(flex: 2),
          // ! there is also the extension .flexible({int flex, FlexFit fit})
          child(3).flexible(flex: 2),
        ]   
      ),
      // ! some very simple layout
      Row(children:[child(3), child(3)]),
      // ! or just return one of your children
      child(4),
    ]
  );
}
...

⚠ 警告!!!!

不要在已经包装在Expanded或Flexible widget中的widget上使用.expanded()和.flexible()。
这样做会导致意外行为和非常糟糕的错误!!!。

这样做会导致意外行为和非常糟糕的错误!!!。

百分比值

这里是我们提供的函数

double responsivePercentageValue({
required double valuePercentage,
required Range? valueRange,
required double limit,
}){}

它将返回某个限制的指定百分比,并且
如果指定了值范围,则会进行限制。

它还带有两个有用的BuildContext类扩展

...
@override
Widget build(BuildContext context) {
  return Container(
    // width will be always 50% of the current screen width
    width: context.percentageValueWidth(50),
    // height will be 50% of the screen height but clamped to the value of the 
    // given range
    height: context.percentageValueHeight(50, Range(100, 300)),
    color: Colors.red,
  );
}
..

百分比值构建器

...
@override
Widget build(BuildContext context) {
  return PercentageValueBuilder(
    // you can specify if this widget should use the screen size to calculate 
    // the percentage value or its constraints
    //useScreenSize: true
    builder: (
      context,
      cosntraints, // BoxConstraints given by a LayoutBuilder
      breakpoints, // breakpoints form the closest SuperResponsive widget
      // these two functions will calculate an specified percentage of the 
      // available space (constraints.maxWidth/maxHeight) or the screen width/height 
      // if useScreenSize is set to true 
      percentageValueWidth, 
      percentageValueHeight,
    ) => Container(
          width: percentageValueWidth(50) // width will be always 50% of the screen width
          // height will be 50% of the screen height but clamped to the value of the 
          // given range
          height: percentageValueHeight(50, Range(100, 200))
      ),
  );
}
...

路线图

(目前有点空)

  • 添加示例
  • 添加测试

GitHub

查看 Github