Repository: Fliggy-Mobile/fbutton Branch: master Commit: 2103beae4fd2 Files: 10 Total size: 82.9 KB Directory structure: gitextract_8cspt6ck/ ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_CN.md ├── example/ │ ├── .gitignore │ ├── lib/ │ │ └── main.dart │ └── pubspec.yaml ├── lib/ │ └── fbutton.dart └── pubspec.yaml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store .dart_tool/ .packages .pub/ build/ .idea/ .metadata *.iml pubspec.lock android/ ios/ ================================================ FILE: CHANGELOG.md ================================================ ## 2.0.1 - optimization ## 2.0.0 - Delete the following parameters and use **style** instead: - `textColor` - `fontSize` - `fontStyle` - `fontHeight` - `textWeight` - Delete the following parameters: - `splashColor` - `focusNode` - `autofocus` - Delete the `effect` parameter - Delete `disabledTextColor` and use `disableStyle` instead - **FButtonCorner** changed to **FCorner** - **FButtonCornerStyle** changed to **FornerStyle** - Add the `activeMaskColor` parameter. The color of the mask when the button is pressed. Adjust the alpha of the color value to ensure that the view behind can be displayed. - Add **Hover** support. - The color in **hover** state can be configured through `hoverColor`. - `onHover` can help developers perceive **hover** state changes. - Add `onPressedDown` and `onPressedUp` and `onPressedCancel` to help developers to make corresponding changes when pressing, lifting or canceling the press. - Add `loadingWidget` parameter, so that developers can define their own loading style - Add Neumorphism style support. - Neumorphism style support can be turned on/off through the `isSupportNeumorphism` parameter - The `highlightShadowColor` parameter can configure the bright shadow color after enabling the Neumorphism style - The `lightOrientation` parameter can adjust the direction of the light source - Add `surfaceStyle` parameter to support the definition of surface style. - Flat - Convex - Concave ## 1.1.0 - Add **style** parameter to configure text style. The following parameters will be removed in subsequent versions: - `textColor` - `fontSize` - `fontStyle` - `fontHeight` - `textWeight` - Add the **alignment** parameter to cancel the default centering - Remove default Padding - Remove the default background color - `onPress' is no longer a required parameter ## 1.0.4 - add @immutable to fbutton.dart - minSDK 2.2 ## 1.0.3 - Remove a few bad attributes - Increase text configurability ================================================ FILE: LICENSE ================================================ Copyright 2020-present Fliggy Android Team . Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at following link. http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================

FButton

From then on, developers only need to master one Button component, which is enough.

Support corners, borders, icons, special effects, loading mode, high-quality Neumorphism style.

Author:Newton(coorchice.cb@alibaba-inc.com)

**English | [简体中文](https://github.com/Fliggy-Mobile/fbutton/blob/master/README_CN.md)** > Like it? Please cast your **Star** 🥰 ! # ✨ Features - Rich **corner** effect - Exquisite **border** decoration - **Gradient effect** - Flexible **icon** support - Intimate **Loading** mode - Cool interaction **Special effects** - More sense of space **Shadow** - High-quality **Neumorphism** style # 🛠 Guide ## ⚙️ Parameters ### 🔩 Basic parameters |Param|Type|Necessary|Default|desc| |---|---|:---:|---|---| |onPressed|VoidCallback|true|null|Click callback. If null, FButton will enter an unavailable state| |onPressedDown|VoidCallback|false|null|Callback when pressed| |onPressedUp|VoidCallback|false|null|Callback when lifted| |onPressedCancel|VoidCallback|false|null|Callback when cancel is pressed| |height|double|false|null|height| |width|double|false|null|width| |style|TextStyle|false|null|text style| |disableStyle|TextStyle|false|null|Unavailable text style| |alignment|Alignment|false|null|alignment| |text|String|false|null|button text| |color|Color|false|null|Button color| |disabledColor|Color|false|null|Color when FButton is unavailable| |padding|EdgeInsetsGeometry|false|null|FButton internal spacing| |corner|FCorner|false|null|Configure corners of Widget| |cornerStyle|FCornerStyle|false|FCornerStyle.round|Configure the corner style of Widget. round-rounded corners, bevel-beveled| |strokeColor|Color|false|Colors.black|Border color| |strokeWidth|double|false|0|Border width. The border will appear when `strokeWidth > 0`| |gradient|Gradient|false|null|Configure gradient colors. Will override the `color`| |activeMaskColor|Color|否|Colors.transparent|The color of the mask when pressed| |surfaceStyle|FSurface|false|FSurface.Flat|Surface style. Default [FSurface.Flat]. See [FSurface] for details| ### 💫 Effect parameters |Param|Type|Necessary|Default|desc| |---|---|:---:|---|---| |clickEffect|bool|false|false|Whether to enable click effects| |hoverColor|Color|false|null|FButton color when hovering| |onHover|ValueChanged|false|null|Callback when the mouse enters/exits the component range| |highlightColor|Color|false|null|The color of the FButton when touched. `effect:true` required| ### 🔳 Shadow parameters |Param|Type|Necessary|Default|desc| |---|---|:---:|---|---| |shadowColor|Color|false|Colors.grey|Shadow color| |shadowOffset|Offset|false|Offset.zero|Shadow offset| |shadowBlur|double|false|1.0|Shadow blur degree, the larger the value, the larger the shadow range| ### 🖼 Icon & Loading parameters |Param|Type|Necessary|Default|desc| |---|---|:---:|---|---| |image|Widget|false|null|An icon can be configured for FButton| |imageMargin|double|false|6.0|Spacing between icon and text| |imageAlignment|ImageAlignment|false|ImageAlignment.left|Relative position of icon and text| |loading|bool|false|false|Whether to enter the Loading state| |loadingWidget|Widget|false|null|Loading widget in loading state. Will override the default Loading effect| |clickLoading|bool|false|false|Whether to enter Loading state after clicking FButton| |loadingColor|Color|false|null|Loading colors| |loadingStrokeWidth|double|false|4.0|Loading width| |hideTextOnLoading|bool|false|false|Whether to hide text in the loading state| |loadingText|String|false|null|Loading text| |loadingSize|double|false|12|Loading size| ### 🍭 Neumorphism Style |Param|Type|Necessary|Default|desc| |---|---|:---:|---|---| |isSupportNeumorphism|bool|false|false|Whether to support the Neumorphism style. Open this item [highlightColor] will be invalid| |lightOrientation|FLightOrientation|false|FLightOrientation.LeftTop|Valid when [isSupportNeumorphism] is true. The direction of the light source is divided into four directions: upper left, lower left, upper right, and lower right. Used to control the illumination direction of the light source, which will affect the highlight direction and shadow direction| |highlightShadowColor|Color|false|null|After the Neumorphism style is turned on, the bright shadow color| ## 📺 Demo ### 🔩 Basic Demo ![](https://gw.alicdn.com/tfs/TB1fUw0NoY1gK0jSZFCXXcwqXXa-720-298.png) ```dart // FButton #1 FButton( height: 40, alignment: Alignment.center, text: "FButton #1", style: TextStyle(color: Colors.white), color: Color(0xffffab91), onPressed: () {}, ) // FButton #2 FButton( padding: const EdgeInsets.fromLTRB(12, 8, 12, 8), text: "FButton #2", style: TextStyle(color: Colors.white), color: Color(0xffffab91), corner: FCorner.all(6.0), ) // FButton #3 FButton( padding: const EdgeInsets.fromLTRB(12, 8, 12, 8), text: "FButton #3", style: TextStyle(color: Colors.white), disableStyle: TextStyle(color: Colors.black38), color: Color(0xffF8AD36), /// set disable Color disabledColor: Colors.grey[300], corner: FCorner.all(6.0), ) ``` By simply configuring `text` and` onPressed`, you can construct an available **FButton**. If `onPressed` is not set, **FButton** will be automatically recognized as not unavailable. At this time, ** FButton ** will have a default unavailable status style. You can also freely configure the style of **FButton** when it is not available via the `disabledXXX` attribute. ### 🎈 Corner & Stroke ![](https://gw.alicdn.com/tfs/TB1qFejbggP7K4jSZFqXXamhVXa-698-598.gif) ```dart // #1 FButton( width: 130, text: "FButton #1", style: TextStyle(color: Colors.white), color: Color(0xffFF7043), onPressed: () {}, clickEffect: true, /// 配置边角大小 /// /// set corner size corner: FCorner.all(25), ), // #2 FButton( width: 130, text: "FButton #2", style: TextStyle(color: Colors.white), color: Color(0xffFFA726), onPressed: () {}, clickEffect: true, corner: FCorner( leftBottomCorner: 40, leftTopCorner: 6, rightTopCorner: 40, rightBottomCorner: 6, ), ), // #3 FButton( width: 130, text: "FButton #3", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 10), /// 设置边角风格 /// /// set corner style cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xffF9A825), ), // #4 FButton( width: 130, padding: EdgeInsets.fromLTRB(6, 16, 30, 16), text: "FButton #4", style: TextStyle(color: Colors.white), color: Color(0xff00B0FF), onPressed: () {}, clickEffect: true, corner: FCorner( rightTopCorner: 25, rightBottomCorner: 25), cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xff000000), ), ``` You can add rounded corners to **FButton** via the `corner` property. You can even control each fillet individually。 By default, the corners of **FButton** are rounded. By setting `cornerStyle: FCornerStyle.bevel`, you can get a bevel effect. **FButton** supports control borders, provided that `strokeWidth> 0` can get the effect 🥳. ### 🌈 Gradient ![](https://gw.alicdn.com/tfs/TB1YgA.NoT1gK0jSZFrXXcNCXXa-486-518.png) ```dart FButton( width: 100, height: 60, text: "#1", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), /// 配置渐变色 /// /// set gradient gradient: LinearGradient(colors: [ Color(0xff00B0FF), Color(0xffFFc900), ]), onPressed: () {}, clickEffect: true, corner: FCorner.all(8), ) ``` Through the `gradient` attribute, you can build **FButton** with gradient colors. You can freely build many types of gradient colors. ### 🍭 Icon ![](https://gw.alicdn.com/tfs/TB1YBUVNoz1gK0jSZLeXXb9kVXa-528-302.png) ```dart FButton( width: 88, height: 38, padding: EdgeInsets.all(0), text: "Back", style: TextStyle(color: Colors.white), color: Color(0xffffc900), onPressed: () { toast(context, "Back!"); }, clickEffect: true, corner: FCorner( leftTopCorner: 25, leftBottomCorner: 25,), /// 配置图标 /// /// set icon image: Icon( Icons.arrow_back_ios, color: Colors.white, size: 12, ), /// 配置图标与文字的间距 /// /// Configure the spacing between icon and text imageMargin: 8, ), FButton( onPressed: () {}, image: Icon( Icons.print, color: Colors.grey, ), imageMargin: 8, /// 配置图标与文字相对位置 /// /// Configure the relative position of icons and text imageAlignment: ImageAlignment.top, text: "Print", style: TextStyle(color: textColor), color: Colors.transparent, ), ``` The `image` property can set an image for **FButton** and you can adjust the position of the image relative to the text, through` imageAlignment`. If the button does not need a background, just set `color: Colors.transparent`. ### 🔥 Effect ![](https://gw.alicdn.com/tfs/TB1IKhaNBr0gK0jSZFnXXbRRXXa-698-178.gif) ```dart FButton( width: 200, text: "Try Me!", style: TextStyle(color: textColor), color: Color(0xffffc900), onPressed: () {}, clickEffect: true, corner: FCorner.all(9), /// 配置按下时颜色 /// /// set pressed color highlightColor: Color(0xffE65100).withOpacity(0.20), /// 配置 hover 状态时颜色 /// /// set hover color hoverColor: Colors.redAccent.withOpacity(0.16), ), ``` The highlight color of **FButton** can be configured through the `highlightColor` property。 `hoverColor` can configure the color when the mouse moves to the range of **FButton**, which will be used during Web development. ### 🔆 Loading ![](https://gw.alicdn.com/tfs/TB1dbvTXODsXe8jSZR0XXXK6FXa-698-698.gif) ```dart FButton( text: "Click top loading", style: TextStyle(color: textColor), color: Color(0xffffc900), ... /// 配置 loading 大小 /// /// set loading size loadingSize: 15, /// 配置 loading 与文本的间距 /// // Configure the spacing between loading and text imageMargin: 6, /// 配置 loading 的宽 /// /// set loading width loadingStrokeWidth: 2, /// 是否支持点击自动开始 loading /// /// Whether to support automatic loading by clicking clickLoading: true, /// 配置 loading 的颜色 /// /// set loading color loadingColor: Colors.white, /// 配置 loading 状态时的文本 /// /// set loading text loadingText: "Loading...", /// 配置 loading 与文本的相对位置 /// /// Configure the relative position of loading and text imageAlignment: ImageAlignment.top, ), // #2 FButton( width: 170, height: 70, text: "Click to loading", style: TextStyle(color: textColor), color: Color(0xffffc900), onPressed: () { }, ... imageMargin: 8, loadingSize: 15, loadingStrokeWidth: 2, clickLoading: true, loadingColor: Colors.white, loadingText: "Loading...", /// loading 时隐藏文本 /// /// Hide text when loading hideTextOnLoading: true, ) FButton( width: 170, height: 70, alignment: Alignment.center, text: "Click to loading", style: TextStyle(color: Colors.white), color: Color(0xff90caf9), ... imageMargin: 8, clickLoading: true, hideTextOnLoading: true, /// 配置自定义 loading 样式 /// /// Configure custom loading style loadingWidget: CupertinoActivityIndicator(), ), ``` Through the `loading` attribute, you can configure **Loading** effects for ** FButton **. When **FButton** is in **Loading** state, **FButton** will enter an unavailable state, onPress will no longer be triggered, and unavailable styles will also be applied. At the same time `loadingText` will overwrite` text` if it is not **null**. The click start **Loading** effect can be achieved through the `clickLoading` attribute. The position of `loading` will be affected by the` imageAlignment` attribute. When `hideTextOnLoading: true`, if **FButton** is in` loading` state, its text will be hidden. Through `loadingWidget`, developers can set completely customized loading styles. ## Shadow ![](https://gw.alicdn.com/tfs/TB11OxcNBr0gK0jSZFnXXbRRXXa-698-368.gif) ```dart FButton( width: 200, text: "Shadow", textColor: Colors.white, color: Color(0xffffc900), onPressed: () {}, clickEffect: true, corner: FCorner.all(28), /// 配置阴影颜色 /// /// set shadow color shadowColor: Colors.black87, /// 设置组件高斯与阴影形状卷积的标准偏差。 /// /// Sets the standard deviation of the component's Gaussian convolution with the shadow shape. shadowBlur: _shadowBlur, ), ``` **FButton** allows you to configure the color, size, and position of the shadow. ### 🍭 Neumorphism Style ![](https://gw.alicdn.com/tfs/TB18CN4dTM11u4jSZPxXXahcXXa-832-644.gif) ```dart FButton( /// 开启 Neumorphism 支持 /// /// Turn on Neumorphism support isSupportNeumorphism: true, /// 配置光源方向 /// /// Configure light source direction lightOrientation: lightOrientation, /// 配置亮部阴影 /// /// Configure highlight shadow highlightShadowColor: Colors.white, /// 配置暗部阴影 /// /// Configure dark shadows shadowColor: mainShadowColor, strokeColor: mainBackgroundColor, strokeWidth: 3.0, width: 190, height: 60, text: "FWidget", style: TextStyle( color: mainTextTitleColor, fontSize: neumorphismSize_2_2), alignment: Alignment.center, color: mainBackgroundColor, ... ) ``` **FButton** brings an incredible, ultra-high texture **Neumorphism** style to developers. Developers only need to configure the `isSupportNeumorphism` parameter to enable and disable the **Neumorphism** style. If you want to adjust the style of **Neumorphism**, you can make subtle adjustments through several attributes related to Shadow, among which: - shadowColor: configure the shadow of the shadow - highlightShadowColor: configure highlight shadow **FButton** also provides `lightOrientation` parameters, and even allows developers to adjust the care angle, and has obtained different **Neumorphism** effects. # 😃 How to use? Add dependencies in the project `pubspec.yaml` file: ## 🌐 pub dependency ``` dependencies: fbutton: ^ ``` > ⚠️ Attention,please go to [**pub**] (https://pub.dev/packages/fbutton) to get the latest version number of **FButton** ## 🖥 git dependencies ``` dependencies: fbutton: git: url: 'git@github.com:Fliggy-Mobile/fbutton.git' ref: '' ``` > ⚠️ Attention,please refer to [**FButton**] (https://github.com/Fliggy-Mobile/fbutton) official project for branch number or tag. # 💡 License ``` Copyright 2020-present Fliggy Android Team . Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at following link. http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ### Like it? Please cast your [**Star**](https://github.com/Fliggy-Mobile/fbutton) 🥰 ! --- # How to run Demo project? 1. **clone** project to local 2. Enter the project `example` directory and run the following command ``` flutter create . ``` 3. Run the demo in `example` ================================================ FILE: README_CN.md ================================================

FButton

从此开发者只用掌握一种 Button 组件,就够了。

支持圆角、边框、图标、特效、Loading 模式、高质感的 Neumorphism 风格。

主理人:纽特(coorchice.cb@alibaba-inc.com)

**[English](https://github.com/Fliggy-Mobile/fbutton) | 简体中文** > 感觉还不错?请投出您的 **Star** 吧 🥰 ! # ✨ 特性 - 丰富的 **边角** 效果 - 精美的 **边框** 装饰 - **渐变效果** 也不在话下 - 灵活的 **图标** 支持 - 贴心的 **Loading** 模式 - 炫酷的交互 **特效** - 更具空间感的 **阴影** - 高质感的 **Neumorphism** 风格 # 🛠 使用指南 ## ⚙️ 参数 ### 🔩 基础参数 |参数|类型|必要|默认值|说明| |---|---|:---:|---|---| |onPressed|VoidCallback|是|null|点击回调。如果为 null,FButton 会进入不可用状态| |onPressedDown|VoidCallback|false|null|按下时会回调| |onPressedUp|VoidCallback|false|null|抬起时会回调| |onPressedCancel|VoidCallback|false|null|按下取消时会回调| |height|double|否|null|高度| |width|double|否|null|宽度| |style|TextStyle|false|null|文本样式| |disableStyle|TextStyle|false|null|不可用文本样式| |alignment|Alignment|false|null|对齐方式| |text|String|否|null|按钮文本| |color|Color|否|null|按钮颜色| |disabledColor|Color|否|null|FButton 不可用状态时的颜色| |padding|EdgeInsetsGeometry|否|null|FButton 内间距| |corner|FCorner|否|null|配置 Widget 的边角| |cornerStyle|FCornerStyle|否|FCornerStyle.round|配置 Widget 的边角样式。round-圆角,bevel-斜切| |strokeColor|Color|否|Colors.black|边框颜色| |strokeWidth|double|否|0|边框宽度。当 strokeWidth>0 时边框就会出现| |gradient|Gradient|否|null|配置渐变色。会覆盖 color 属性| |activeMaskColor|Color|否|Colors.transparent|按下时的蒙层颜色| |surfaceStyle|FSurface|false|FSurface.Flat|表面的风格。默认 [FSurface.Flat]。详见 [FSurface]| ### 💫 Effect 参数 |参数|类型|必要|默认值|说明| |---|---|:---:|---|---| |clickEffect|bool|否|false|是否启用点击特效| |hoverColor|Color|否|null|鼠标悬停状态时 FButton 的颜色| |onHover|ValueChanged|false|null|鼠标进入/退出组件范围时会回调| |highlightColor|Color|否|null|触摸时 FButton 的颜色。需要 effect=true| ### 🔳 阴影参数 |参数|类型|必要|默认值|说明| |---|---|:---:|---|---| |shadowColor|Color|否|Colors.grey|阴影颜色| |shadowOffset|Offset|否|Offset.zero|阴影偏移| |shadowBlur|double|否|1.0|阴影模糊程度,值越大,阴影范围越大| ### 🖼 图标和 Loading 参数 |参数|类型|必要|默认值|说明| |---|---|:---:|---|---| |image|Widget|否|null|可为 FButton 配置一个图标| |imageMargin|double|否|6.0|图标与文本的间距| |imageAlignment|ImageAlignment|否|ImageAlignment.left|图标与文本的相对位置| |loading|bool|否|false|是否进入 Loading 状态| |loadingWidget|Widget|false|null|loading 状态时的 Loading 小部件。会覆盖默认的 Loading 效果| |clickLoading|bool|否|false|是否在点击 FButton 后进入 Loading 状态| |loadingColor|Color|否|null|Loading 的颜色| |loadingStrokeWidth|double|否|4.0|Loading 的宽度| |hideTextOnLoading|bool|否|false|Loading 状态下是否隐藏文本| |loadingText|String|否|null|Loading 状态下的文本| |loadingSize|double|否|12|Loading 的大小| ### 🍭 Neumorphism 风格 |参数|类型|必要|默认值|说明| |---|---|:---:|---|---| |isSupportNeumorphism|bool|false|false|是否支持 Neumorphism 风格。开启该项 [highlightColor] 将会失效| |lightOrientation|FLightOrientation|false|FLightOrientation.LeftTop|当 [isSupportNeumorphism] 为 true 时有效。光源方向,分为左上、左下、右上、右下四个方向。用来控制光源照射方向,会影响高亮方向和阴影方向| |highlightShadowColor|Color|false|null|开启 Neumorphism 风格后的,亮部阴影颜色| ## 📺 使用示例 ### 🔩 基本使用 ![](https://gw.alicdn.com/tfs/TB1fUw0NoY1gK0jSZFCXXcwqXXa-720-298.png) ```dart // FButton #1 FButton( height: 40, alignment: Alignment.center, text: "FButton #1", style: TextStyle(color: Colors.white), color: Color(0xffffab91), onPressed: () {}, ) // FButton #2 FButton( padding: const EdgeInsets.fromLTRB(12, 8, 12, 8), text: "FButton #2", style: TextStyle(color: Colors.white), color: Color(0xffffab91), corner: FCorner.all(6.0), ) // FButton #3 FButton( padding: const EdgeInsets.fromLTRB(12, 8, 12, 8), text: "FButton #3", style: TextStyle(color: Colors.white), disableStyle: TextStyle(color: Colors.black38), color: Color(0xffF8AD36), /// 配置不可用颜色 disabledColor: Colors.grey[300], corner: FCorner.all(6.0), ) ``` 通过简单的配置 `text` 以及 `onPressed`,即可构造一个可用 **FButton**。 如果没有设置 `onPressed`,**FButton** 会自动被识别 **未不可用状态** 。此时 **FButton** 会有一个默认的不可用状态样式。 你也可以自由的配置 **FButton** 不可用状态下的样式通过 `disabledXXX` 属性。 ### 🎈 边角 & 边框 ![](https://gw.alicdn.com/tfs/TB1qFejbggP7K4jSZFqXXamhVXa-698-598.gif) ```dart // #1 FButton( width: 130, text: "FButton #1", style: TextStyle(color: Colors.white), color: Color(0xffFF7043), onPressed: () {}, clickEffect: true, /// 配置边角大小 /// /// set corner size corner: FCorner.all(25), ), // #2 FButton( width: 130, text: "FButton #2", style: TextStyle(color: Colors.white), color: Color(0xffFFA726), onPressed: () {}, clickEffect: true, corner: FCorner( leftBottomCorner: 40, leftTopCorner: 6, rightTopCorner: 40, rightBottomCorner: 6, ), ), // #3 FButton( width: 130, text: "FButton #3", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 10), /// 设置边角风格 /// /// set corner style cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xffF9A825), ), // #4 FButton( width: 130, padding: EdgeInsets.fromLTRB(6, 16, 30, 16), text: "FButton #4", style: TextStyle(color: Colors.white), color: Color(0xff00B0FF), onPressed: () {}, clickEffect: true, corner: FCorner( rightTopCorner: 25, rightBottomCorner: 25), cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xff000000), ), ``` 你可以为 **FButton** 添加圆角,通过 `corner` 属性。甚至,你可以单独控制每一个圆角。 默认情况下,**FButton** 的边角为圆角。通过设置 `cornerStyle: FCornerStyle.bevel`,可以获得斜角效果。 **FButton** 支持控件边框,前提是 `strokeWidth > 0` 即可获得效果 🥳。 ### 🌈 渐变色 ![](https://gw.alicdn.com/tfs/TB1YgA.NoT1gK0jSZFrXXcNCXXa-486-518.png) ```dart FButton( width: 100, height: 60, text: "#1", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), /// 配置渐变色 /// /// set gradient gradient: LinearGradient(colors: [ Color(0xff00B0FF), Color(0xffFFc900), ]), onPressed: () {}, clickEffect: true, corner: FCorner.all(8), ) ``` 通过 `gradient` 属性,可以构建带有渐变色的 **FButton** 你可以自由构建多种类型的渐变色。 ### 🍭 图标 ![](https://gw.alicdn.com/tfs/TB1YBUVNoz1gK0jSZLeXXb9kVXa-528-302.png) ```dart FButton( width: 88, height: 38, padding: EdgeInsets.all(0), text: "Back", style: TextStyle(color: Colors.white), color: Color(0xffffc900), onPressed: () { toast(context, "Back!"); }, clickEffect: true, corner: FCorner( leftTopCorner: 25, leftBottomCorner: 25,), /// 配置图标 /// /// set icon image: Icon( Icons.arrow_back_ios, color: Colors.white, size: 12, ), /// 配置图标与文字的间距 /// /// Configure the spacing between icon and text imageMargin: 8, ), FButton( onPressed: () {}, image: Icon( Icons.print, color: Colors.grey, ), imageMargin: 8, /// 配置图标与文字相对位置 /// /// Configure the relative position of icons and text imageAlignment: ImageAlignment.top, text: "Print", style: TextStyle(color: textColor), color: Colors.transparent, ), ``` `image` 属性能够为 **FButton** 设置一个图片而且你能够调整图片相对与文本的位置,通过 `imageAlignment`。 如果按钮不需要背景,设置 `color: Colors.transparent` 即可。 ### 🔥 特效 ![](https://gw.alicdn.com/tfs/TB1IKhaNBr0gK0jSZFnXXbRRXXa-698-178.gif) ```dart FButton( width: 200, text: "Try Me!", style: TextStyle(color: textColor), color: Color(0xffffc900), onPressed: () {}, clickEffect: true, corner: FCorner.all(9), /// 配置按下时颜色 /// /// set pressed color highlightColor: Color(0xffE65100).withOpacity(0.20), /// 配置 hover 状态时颜色 /// /// set hover color hoverColor: Colors.redAccent.withOpacity(0.16), ), ``` 通过 `highlightColor` 属性可以配置 **FButton** 的按压时的高亮颜色 `hoverColor` 可配置鼠标移到 **FButton** 范围中时的颜色,这在 Web 开发时会被用到。 ### 🔆 Loading ![](https://gw.alicdn.com/tfs/TB1dbvTXODsXe8jSZR0XXXK6FXa-698-698.gif) ```dart FButton( text: "Click top loading", style: TextStyle(color: textColor), color: Color(0xffffc900), ... /// 配置 loading 大小 /// /// set loading size loadingSize: 15, /// 配置 loading 与文本的间距 /// // Configure the spacing between loading and text imageMargin: 6, /// 配置 loading 的宽 /// /// set loading width loadingStrokeWidth: 2, /// 是否支持点击自动开始 loading /// /// Whether to support automatic loading by clicking clickLoading: true, /// 配置 loading 的颜色 /// /// set loading color loadingColor: Colors.white, /// 配置 loading 状态时的文本 /// /// set loading text loadingText: "Loading...", /// 配置 loading 与文本的相对位置 /// /// Configure the relative position of loading and text imageAlignment: ImageAlignment.top, ), // #2 FButton( width: 170, height: 70, text: "Click to loading", style: TextStyle(color: textColor), color: Color(0xffffc900), onPressed: () { }, ... imageMargin: 8, loadingSize: 15, loadingStrokeWidth: 2, clickLoading: true, loadingColor: Colors.white, loadingText: "Loading...", /// loading 时隐藏文本 /// /// Hide text when loading hideTextOnLoading: true, ) FButton( width: 170, height: 70, alignment: Alignment.center, text: "Click to loading", style: TextStyle(color: Colors.white), color: Color(0xff90caf9), ... imageMargin: 8, clickLoading: true, hideTextOnLoading: true, /// 配置自定义 loading 样式 /// /// Configure custom loading style loadingWidget: CupertinoActivityIndicator(), ), ``` 通过 `loading` 属性,可为 **FButton** 配置 **Loading** 效果。 当 **FButton** 处于 **Loading** 状态时,**FButton** 将会进入不可用状态,`onPress` 将不会再被触发,不可用样式也将被应用。 同时 `loadingText` 将会覆盖 `text`,如果它不为 **null** 的话。 通过 `clickLoading` 属性可以实现点击开始 **Loading** 的效果。 其中 `loading` 的位置会受到 `imageAlignment` 属性的影响。 当 `hideTextOnLoading: true` 时,如果 **FButton** 处于 `loading` 状态,那么其文本将会被隐藏起来。 通过 `loadingWidget`,开发者可以设置完全自定义的 loading 样式。 ## 阴影 ![](https://gw.alicdn.com/tfs/TB11OxcNBr0gK0jSZFnXXbRRXXa-698-368.gif) ```dart FButton( width: 200, text: "Shadow", textColor: Colors.white, color: Color(0xffffc900), onPressed: () {}, clickEffect: true, corner: FCorner.all(28), /// 配置阴影颜色 /// /// set shadow color shadowColor: Colors.black87, /// 设置组件高斯与阴影形状卷积的标准偏差。 /// /// Sets the standard deviation of the component's Gaussian convolution with the shadow shape. shadowBlur: _shadowBlur, ), ``` **FButton** 允许配置阴影的颜色、大小、以及位置。 ### 🍭 Neumorphism 风格 ![](https://gw.alicdn.com/tfs/TB18CN4dTM11u4jSZPxXXahcXXa-832-644.gif) ```dart FButton( /// 开启 Neumorphism 支持 /// /// Turn on Neumorphism support isSupportNeumorphism: true, /// 配置光源方向 /// /// Configure light source direction lightOrientation: lightOrientation, /// 配置亮部阴影 /// /// Configure highlight shadow highlightShadowColor: Colors.white, /// 配置暗部阴影 /// /// Configure dark shadows shadowColor: mainShadowColor, strokeColor: mainBackgroundColor, strokeWidth: 3.0, width: 190, height: 60, text: "FWidget", style: TextStyle( color: mainTextTitleColor, fontSize: neumorphismSize_2_2), alignment: Alignment.center, color: mainBackgroundColor, ... ) ``` **FButton** 为开发者带来了不可思议的,超高质感的 **Neumorphism** 风格。 开发者只需要简单的通过配置 `isSupportNeumorphism` 参数,就可以开启和关闭 **Neumorphism** 风格。 如果想要调整 **Neumorphism** 的样式,可以通过 Shadow 相关的几个属性进行细微的调整,其中: - shadowColor: 配置暗部阴影 - highlightShadowColor:配置亮部阴影 **FButton** 还提供了 `lightOrientation` 参数,甚至使得开发者能够调整关照角度,已获得不同的 **Neumorphism** 效果。 # 😃 如何使用? 在项目 `pubspec.yaml` 文件中添加依赖: ## 🌐 pub 依赖方式 ``` dependencies: fbutton: ^<版本号> ``` > ⚠️ 注意,请到 [**pub**](https://pub.dev/packages/fbutton) 获取 **FButton** 最新版本号 ## 🖥 git 依赖方式 ``` dependencies: fbutton: git: url: 'git@github.com:Fliggy-Mobile/fbutton.git' ref: '<分支号 或 tag>' ``` > ⚠️ 注意,分支号 或 tag 请以 [**FButton**](https://github.com/Fliggy-Mobile/fbutton) 官方项目为准。 # 💡 License ``` Copyright 2020-present Fliggy Android Team . Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at following link. http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ### 感觉还不错?请投出您的 [**Star**](https://github.com/Fliggy-Mobile/fbutton) 吧 🥰 ! --- # 如何运行 Demo 工程? 1.**clone** 工程到本地 2.进入工程 `example` 目录,运行以下命令 ``` flutter create . ``` 3.运行 `example` 中的 Demo ================================================ FILE: example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .packages .pub-cache/ .pub/ /build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Generated.xcconfig **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages web/ .flutter-plugins-dependencies README.md test/ macos/ ================================================ FILE: example/lib/main.dart ================================================ import 'package:fcontrol/fdefine.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:fbutton/fbutton.dart'; import 'package:fradio/fradio.dart'; import 'dart:math' as math; import 'package:fcommon/fcommon.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( home: FButtonPage(), ); } } class FButtonPage extends StatefulWidget { @override _FButtonPageState createState() => _FButtonPageState(); } class _FButtonPageState extends State { var _shadowBlur; @override void initState() { _shadowBlur = 5.0; super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: mainBackgroundColor, appBar: AppBar( backgroundColor: mainBackgroundColor, title: const Text( 'FButton', style: TextStyle(color: mainTextTitleColor), ), centerTitle: true, ), body: SingleChildScrollView( child: Container( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ /// Normal FButton buildTitle("FButton"), buildSmallMargin(), /// Normal FButton 1 buildNormalButton1(), buildMiddleMargin(), /// Normal FButton 2 buildNormalButton2(), buildMiddleMargin(), /// Normal FButton 3 buildNormalButton3(), buildMiddleMargin(), buildTitle("Corner"), buildSmallMargin(), /// Corner FButton buildCornerButton1(), buildBigMargin(), /// Corner FButton buildCornerButton2(), buildMiddleMargin(), buildTitle("Gradient"), buildSmallMargin(), /// Gradient FButton buildGradientButton1(), buildMiddleMargin(), /// Gradient FButton buildGradientButton2(), buildMiddleMargin(), /// Gradient FButton buildGradientButton3(), buildMiddleMargin(), /// Stroke FButton buildTitle("Stroke"), buildSmallMargin(), buildStrokeButton(), buildMiddleMargin(), buildTitle("Image"), buildSmallMargin(), /// Image buildImageButton1(context), buildBigMargin(), /// Image buildImageButton2(), buildBigMargin(), buildTitle("Loading"), buildMiddleMargin(), /// Loading buildLoadingButton1(), buildMiddleMargin(), /// Loading buildLoadingButton2(), buildSmallMargin(), /// Effect FButton buildTitle("Effect"), buildSmallMargin(), /// Hover buildEffectButton(), buildMiddleMargin(), buildTitle("Shadow"), buildSmallMargin(), /// Shadow buildShadowButton(), /////// buildBigMargin(), buildTitle("Neumorphism Style"), buildMiddleMargin(), buildMiddleMargin(), /// Neumorphism neumorphismDemo(), buildBiggestMargin(), buildBiggestMargin(), ], ), ), ), )); } Stack neumorphismDemo() { return Stack( children: [ Padding( padding: EdgeInsets.only(left: 20, right: 20, top: 50, bottom: 50), child: Column( children: [ /// Neumorphism Style 1 neumorphismDemo_1(), buildMiddleMargin(), buildMiddleMargin(), /// Neumorphism Style 2 neumorphismDemo_2(), ], ), ), Positioned( left: 25, top: 0, child: Transform.rotate( angle: -math.pi / 4.0, alignment: Alignment.center, child: FRadio.custom( value: FLightOrientation.LeftTop, groupValue: lightOrientation, normal: Image.asset("assets/icon_light_unselected.png"), selected: Image.asset("assets/icon_light_selected.png"), onChanged: (value) { setState(() { lightOrientation = value; }); }, ), )), Positioned( right: 25, top: 0, child: Transform.rotate( angle: math.pi / 4.0, alignment: Alignment.center, child: FRadio.custom( value: FLightOrientation.RightTop, groupValue: lightOrientation, normal: Image.asset("assets/icon_light_unselected.png"), selected: Image.asset("assets/icon_light_selected.png"), onChanged: (value) { setState(() { lightOrientation = value; }); }, ), )), Positioned( right: 25, bottom: 0, child: Transform.rotate( angle: -math.pi / (3.0 / 4.0), alignment: Alignment.center, child: FRadio.custom( value: FLightOrientation.RightBottom, groupValue: lightOrientation, normal: Image.asset("assets/icon_light_unselected.png"), selected: Image.asset("assets/icon_light_selected.png"), onChanged: (value) { setState(() { lightOrientation = value; }); }, ), )), Positioned( left: 25, bottom: 0, child: Transform.rotate( angle: math.pi / (3.0 / 4.0), alignment: Alignment.center, child: FRadio.custom( value: FLightOrientation.LeftBottom, groupValue: lightOrientation, normal: Image.asset("assets/icon_light_unselected.png"), selected: Image.asset("assets/icon_light_selected.png"), onChanged: (value) { setState(() { lightOrientation = value; }); }, ), )), ], ); } FLightOrientation lightOrientation = FLightOrientation.LeftTop; double neumorphismSize_1 = 30; double neumorphismSize_2 = 30; double neumorphismSize_3 = 30; Widget neumorphismDemo_1() { return StatefulBuilder(builder: (context, setState) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ FButton( lightOrientation: lightOrientation, /// 开启 Neumorphism 支持 isSupportNeumorphism: true, highlightShadowColor: Colors.white, shadowColor: mainShadowColor, width: 60, height: 60, image: Icon( Icons.call, color: mainTextTitleColor, size: neumorphismSize_1, ), alignment: Alignment.center, color: mainBackgroundColor, corner: FCorner.all(8.0), onPressed: () {}, onPressedDown: () { setState(() { neumorphismSize_1 = 26; }); }, onPressedUp: () { setState(() { neumorphismSize_1 = 30; }); }, onPressedCancel: () { setState(() { neumorphismSize_1 = 30; }); }, ), FButton( lightOrientation: lightOrientation, /// 开启 Neumorphism 支持 isSupportNeumorphism: true, highlightShadowColor: Colors.white, shadowColor: mainShadowColor, width: 60, height: 60, image: Icon( Icons.mic, color: mainTextTitleColor, size: neumorphismSize_2, ), alignment: Alignment.center, color: mainBackgroundColor, corner: FCorner.all(8.0), onPressed: () {}, onPressedDown: () { setState(() { neumorphismSize_2 = 26; }); }, onPressedUp: () { setState(() { neumorphismSize_2 = 30; }); }, onPressedCancel: () { setState(() { neumorphismSize_2 = 30; }); }, ), FButton( lightOrientation: lightOrientation, /// 开启 Neumorphism 支持 isSupportNeumorphism: true, strokeColor: mainBackgroundColor, strokeWidth: 3.0, highlightShadowColor: Colors.white, shadowColor: mainShadowColor, width: 60, height: 60, image: Icon( Icons.photo_camera, color: mainTextTitleColor, size: neumorphismSize_3, ), alignment: Alignment.center, color: mainBackgroundColor, corner: FCorner.all(8.0), onPressed: () {}, onPressedDown: () { setState(() { neumorphismSize_3 = 26; }); }, onPressedUp: () { setState(() { neumorphismSize_3 = 30; }); }, onPressedCancel: () { setState(() { neumorphismSize_3 = 30; }); }, ), ], ); }); } double neumorphismSize_2_1 = 30; double neumorphismSize_2_2 = 18; Widget neumorphismDemo_2() { return StatefulBuilder(builder: (context, setState) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ FButton( lightOrientation: lightOrientation, /// 开启 Neumorphism 支持 isSupportNeumorphism: true, highlightShadowColor: Colors.white, shadowColor: mainShadowColor, strokeColor: mainBackgroundColor, strokeWidth: 3.0, width: 60, height: 60, image: Icon( Icons.play_arrow, color: mainTextTitleColor, size: neumorphismSize_2_1, ), alignment: Alignment.center, color: mainBackgroundColor, corner: FCorner.all(30.0), onPressed: () {}, onPressedDown: () { setState(() { neumorphismSize_2_1 = 26; }); }, onPressedUp: () { setState(() { neumorphismSize_2_1 = 30; }); }, onPressedCancel: () { setState(() { neumorphismSize_2_1 = 30; }); }, ), FButton( /// 配置光源方向 /// /// Configure light source direction lightOrientation: lightOrientation, /// 开启 Neumorphism 支持 /// /// Turn on Neumorphism support isSupportNeumorphism: true, /// 配置亮部阴影 /// /// Configure highlight shadow highlightShadowColor: Colors.white, /// 配置暗部阴影 /// /// Configure dark shadows shadowColor: mainShadowColor, strokeColor: mainBackgroundColor, strokeWidth: 3.0, width: 190, height: 60, text: "FWidget", style: TextStyle( color: mainTextTitleColor, fontSize: neumorphismSize_2_2), alignment: Alignment.center, color: mainBackgroundColor, corner: FCorner.all(30.0), onPressed: () {}, onPressedDown: () { setState(() { neumorphismSize_2_2 = 16; }); }, onPressedUp: () { setState(() { neumorphismSize_2_2 = 18; }); }, onPressedCancel: () { setState(() { neumorphismSize_2_2 = 18; }); }, ), ], ); }); } Widget buildShadowButton() { return StatefulBuilder(builder: (context, setState) { return Column( children: [ buildMiddleMargin(), FButton( width: 200, height: 50, alignment: Alignment.center, text: "Shadow", style: TextStyle(color: Colors.white), color: Color(0xffb39ddb), onPressed: () {}, clickEffect: true, corner: FCorner.all(28), shadowColor: Color(0xff3754AA).withOpacity(0.78), shadowBlur: _shadowBlur, ), buildMiddleMargin(), Container( width: 200, child: Slider( label: _shadowBlur.toString(), value: _shadowBlur, min: 0.0, max: 20, divisions: 40, activeColor: Color(0xff9fa8da), inactiveColor: Color(0xff9fa8da).withOpacity(0.38), onChanged: (v) { setState(() { _shadowBlur = v; }); }, ), ), ], ); }); } FButton buildEffectButton() { return FButton( width: 200, height: 50, alignment: Alignment.center, text: "Try Me!", style: TextStyle(color: Colors.white), color: Color(0xff81d4fa), onPressed: () {}, clickEffect: true, corner: FCorner.all(9), highlightColor: Color(0xffff8a65), hoverColor: Color(0xff80deea), shadowColor: mainShadowColor, shadowBlur: 6.0, shadowOffset: Offset(2.0, 2.0), ); } Widget buildLoadingButton2() { return StatefulBuilder(builder: (context, setState) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ FButton( padding: EdgeInsets.all(12.0), text: "Click left loading", style: TextStyle(color: Colors.white), color: Color(0xffffab91), onPressed: () { print("Loading..."); }, clickEffect: true, corner: FCorner.all(9), loadingSize: 15, imageMargin: 16, loadingStrokeWidth: 2, clickLoading: true, loadingColor: Colors.white, loadingText: "Loading...", ), SizedBox( width: 10, ), FButton( padding: EdgeInsets.all(12.0), text: "Click top loading", style: TextStyle(color: Colors.white), color: Color(0xffb39ddb), onPressed: () { print("Loading..."); }, clickEffect: true, corner: FCorner.all(9), loadingSize: 15, imageMargin: 6, loadingStrokeWidth: 2, clickLoading: true, loadingColor: Colors.white, loadingText: "Loading...", imageAlignment: ImageAlignment.top, loadingWidget: RefreshProgressIndicator(), ), ], ), buildMiddleMargin(), FButton( width: 170, height: 70, alignment: Alignment.center, text: "Click to loading", style: TextStyle(color: Colors.white), color: Color(0xff90caf9), onPressed: () { print("Loading..."); }, clickEffect: true, corner: FCorner.all(9), image: Icon( Icons.cloud_download, size: 18, color: Colors.white, ), imageMargin: 8, loadingSize: 15, loadingStrokeWidth: 2, clickLoading: true, loadingColor: Colors.white, loadingText: "Loading...", hideTextOnLoading: true, loadingWidget: CupertinoActivityIndicator(), ), buildMiddleMargin(), FButton( width: 100, height: 30, alignment: Alignment.center, text: "Reset", style: TextStyle(color: mainTextTitleColor), corner: FCorner.all(25), onPressed: () { setState(() {}); }, color: Color(0xffffab91), // clickEffect: true, highlightShadowColor: Color(0xfffbe9e7), shadowColor: Color(0xffff7043), isSupportNeumorphism: true, shadowBlur: 10.0, ), ], ); }); } Widget buildLoadingButton1() { return FButton( width: 200, height: 50, text: "loading", style: TextStyle(color: Colors.white), color: Color(0xffa5d6a7), onPressed: () { print("Loading..."); }, clickEffect: true, corner: FCorner.all(30), loadingSize: 15, imageMargin: 16, loadingStrokeWidth: 2, loading: true, loadingColor: Colors.white, loadingText: "Loading...", ); } Row buildImageButton2() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ FButton( onPressed: () {}, image: Icon( Icons.add_a_photo, color: Color(0xffff8a65), ), imageMargin: 8, text: "Take Photo", style: TextStyle(color: mainTextTitleColor), color: Colors.transparent, ), SizedBox( width: 36, ), FButton( onPressed: () {}, image: Icon( Icons.print, color: Colors.grey, ), imageMargin: 8, imageAlignment: ImageAlignment.top, text: "Print", style: TextStyle(color: mainTextTitleColor), color: Colors.transparent, ), ], ); } Row buildImageButton1(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ FButton( width: 88, height: 38, padding: EdgeInsets.all(0), text: "Back", style: TextStyle(color: Colors.white), color: Color(0xff9ccc65), onPressed: () { toast(context, "Back!"); }, clickEffect: true, corner: FCorner(leftTopCorner: 25, leftBottomCorner: 25), image: Icon( Icons.arrow_back_ios, color: Colors.white, size: 12, ), imageMargin: 8, ), Container( height: 38, child: VerticalDivider(width: 0.25, color: Colors.black)), FButton( width: 88, height: 38, padding: EdgeInsets.all(0), text: "Forward", style: TextStyle(color: Colors.white), color: Color(0xffd4e157), onPressed: () { toast(context, "Forward!"); }, corner: FCorner(rightTopCorner: 25, rightBottomCorner: 25), image: Icon( Icons.arrow_forward_ios, color: Colors.white, size: 12, ), imageMargin: 8, imageAlignment: ImageAlignment.right, ), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 0, 0), child: FButton( width: 38, height: 38, padding: EdgeInsets.all(0), color: Color(0xff26c6da), onPressed: () { toast(context, "Search!"); }, clickEffect: true, corner: FCorner.all(19), image: Icon( Icons.search, color: Colors.white, ), ), ), ], ); } Padding buildStrokeButton() { return Padding( padding: const EdgeInsets.fromLTRB(28, 0, 28, 0), child: FButton( text: "Stroke FButton", style: TextStyle(color: Colors.black87), color: Colors.white, onPressed: () {}, clickEffect: true, corner: FCorner.all(6), strokeWidth: 1, strokeColor: Colors.black87, padding: EdgeInsets.all(10.0), ), ); } Padding buildGradientButton3() { return Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: FButton( width: 200, height: 50, alignment: Alignment.center, text: "RadialGradient FButton", style: TextStyle(color: Colors.white), gradient: RadialGradient( center: const Alignment(0.6, 0.2), radius: 0.2, colors: [ const Color(0xFF0099FF), const Color(0xffff7043), ], stops: [0.4, 1.0], ), onPressed: () {}, clickEffect: true, corner: FCorner.all(9), ), ); } Padding buildGradientButton2() { return Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: FButton( width: 200, height: 90, alignment: Alignment.center, text: "SweepGradient FButton", style: TextStyle(color: Colors.white), color: Colors.black54, gradient: SweepGradient( center: Alignment.center, startAngle: 0.0, endAngle: math.pi * 2, colors: const [ Colors.blue, Colors.green, Colors.yellow, Colors.red, Colors.blueAccent, ], ), onPressed: () {}, clickEffect: true, corner: FCorner.all(9), ), ); } Padding buildGradientButton1() { return Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: FButton( width: 200, height: 50, alignment: Alignment.center, text: "LinearGradient FButton", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), gradient: LinearGradient(colors: [ Color(0xff00B0FF), Color(0xffFFc900), ]), onPressed: () {}, clickEffect: true, corner: FCorner.all(9), ), ); } Widget buildCornerButton2() { return Container( width: 360, padding: const EdgeInsets.fromLTRB(18, 0, 18, 0), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xffFF7043), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 10), cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xffD84315), ), FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xffFFA726), onPressed: () {}, clickEffect: true, corner: FCorner( leftBottomCorner: 40, leftTopCorner: 6, rightTopCorner: 40, rightBottomCorner: 6, ), cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xffEF6C00), ), ], ), buildSmallMargin(), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), onPressed: () {}, clickEffect: true, corner: FCorner(rightTopCorner: 25, rightBottomCorner: 25), cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xffF9A825), ), FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xff00B0FF), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 35, rightTopCorner: 35), cornerStyle: FCornerStyle.bevel, strokeWidth: 0.5, strokeColor: Color(0xff0288D1), ), ], ), ], ), ); } Widget buildCornerButton1() { return Container( width: 360, padding: const EdgeInsets.fromLTRB(18, 0, 18, 0), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xffFF7043), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 18), ), FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xffFFA726), onPressed: () {}, clickEffect: true, corner: FCorner( leftBottomCorner: 40, leftTopCorner: 6, rightTopCorner: 40, rightBottomCorner: 6, ), ), ], ), buildSmallMargin(), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xffFFc900), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 25, leftBottomCorner: 25), ), FButton( width: 150, height: 50, alignment: Alignment.center, text: "Corner FButton", style: TextStyle(color: Colors.white), color: Color(0xff00B0FF), onPressed: () {}, clickEffect: true, corner: FCorner(leftTopCorner: 35, rightTopCorner: 35), ), ], ), ], ), ); } Padding buildNormalButton3() { return Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: FButton( padding: const EdgeInsets.fromLTRB(12, 8, 12, 8), text: "FButton #3", style: TextStyle(color: Colors.white), disableStyle: TextStyle(color: Colors.black38), color: Color(0xffF8AD36), disabledColor: Colors.grey[300], corner: FCorner.all(6.0), ), ); } Padding buildNormalButton2() { return Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: FButton( padding: const EdgeInsets.fromLTRB(12, 8, 12, 8), text: "FButton #2", style: TextStyle(color: Colors.white), color: Color(0xffffab91), corner: FCorner.all(6.0), ), ); } Widget buildNormalButton1() { return Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), child: FButton( height: 40, alignment: Alignment.center, text: "FButton #1", style: TextStyle(color: Colors.white), color: Color(0xffffab91), onPressed: () {}, clickEffect: true, highlightColor: Colors.red, hoverColor: Colors.blue, corner: FCorner.all(6.0), ), ); } } ================================================ FILE: example/pubspec.yaml ================================================ name: fbutton_example description: Demonstrates how to use the fbutton plugin. publish_to: 'none' environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 fcommon: git: url: 'git@github.com:Fliggy-Mobile/fcommon.git' ref: 'master' fsuper: ^0.1.5 fswitch: ^1.1.2 fradio: ^1.0.1 ffloat: ^1.0.1 frefresh: ^1.1.0 fdottedline: ^1.0.0 dev_dependencies: flutter_test: sdk: flutter fbutton: path: ../ # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: assets: - assets/ # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages ================================================ FILE: lib/fbutton.dart ================================================ export 'package:fcontrol/fdefine.dart'; import 'package:fcontrol/fcontrol.dart'; import 'package:fcontrol/fdefine.dart'; import 'package:flutter/material.dart'; /// [FButton] 图片相对与文字的位置 /// /// [FButton] The position of the picture relative to the text enum ImageAlignment { /// 文字左边 /// /// Left of text left, /// 文字顶部 /// /// Top of text top, /// 文字右边 /// /// Right side of text right, /// 文字底部 /// /// Bottom of text bottom, } /// FButton 提供了一个常用按钮效果的实现集合。支持配置圆角、各种特效、边角、边框以及 Loading等。 /// FButton 让开发者可以只熟悉一个按钮组件,就能实现常见的按钮。而无需掌握多种不同类型的按钮组件。 /// /// FButton provides a collection of commonly used button effects. /// Support for configuring rounded corners, various special effects, corners, borders, and loading. /// FButton allows developers to familiarize themselves with just one button component and implement common buttons. /// No need to master many different types of button components. // ignore: must_be_immutable class FButton extends StatefulWidget { /// 当按下按钮时,会触发该函数。如果未设置该函数,按钮将进入不可用状态。 /// /// When the button is pressed, the function is triggered.If this function is not set, the button will enter an unavailable state. final VoidCallback onPressed; /// 按钮上的文字。 /// /// The text on the button. final String text; /// 按钮文本样式 /// /// Button text style final TextStyle style; /// 禁用按钮文本样式 /// /// Disable button text style final TextStyle disableStyle; /// 文本在组件中的相对位置。[Alignment] /// /// The relative position of the text in the component. [Alignment] final Alignment alignment; /// 按钮的颜色 /// /// Button color final Color color; /// 按钮不可用颜色 /// /// Button is not available in color final Color disabledColor; /// 鼠标进入按钮范围时,按钮的颜色。 /// /// the color of the button when the mouse enters the button range. final Color hoverColor; /// 按压按钮时的按钮颜色。 /// /// the button color when the button is pressed. final Color highlightColor; /// 按压按钮时的蒙层颜色。调整颜色值的 alpha,以确保背后的视图能够展示。 /// /// The color of the mask when the button is pressed. Adjust the alpha of the color value to ensure that the view behind can be displayed. final Color activeMaskColor; /// 内间距。 /// /// Internal spacing final EdgeInsetsGeometry padding; /// 宽度。 /// /// width final double width; /// 高度。 /// /// height. final double height; /// 为组件设置边角。 /// /// Set corners for widget final FCorner corner; /// 设置边角风格,默认 [FCornerStyle.round] /// /// Set rounded corner style, default [FCornerStyle.round] final FCornerStyle cornerStyle; /// 设置边框颜色。 /// /// Set the border color. final Color strokeColor; /// 设置边框宽 /// /// Set border width final double strokeWidth; /// 设置组件阴影颜色 /// /// Set component shadow color final Color shadowColor; /// 开启 Neumorphism 风格后的,亮部阴影颜色 /// /// After the Neumorphism style is turned on, the bright shadow color final Color highlightShadowColor; /// 设置组件阴影偏移 /// /// Set component shadow offset final Offset shadowOffset; /// 设置组件高斯与阴影形状卷积的标准偏差。 /// /// Sets the standard deviation of the component's Gaussian convolution with the shadow shape. final double shadowBlur; /// 是否开启基于阴影的点击特效。 /// /// Whether to enable shadow-based click effects. final bool clickEffect; /// 设置组件渐变色背景。会覆盖 [color] 配置 /// 你可选择 [LinearGradient],[RadialGradient],[SweepGradient] 等.. /// /// Sets the gradient background of the component. [BackgroundColor] /// You can choose [LinearGradient], [RadialGradient], [SweepGradient], etc .. final Gradient gradient; /// 设置图标 /// /// Settings icon final Widget image; /// 设置图标与文本的间距 /// /// Set the distance between the icon and the text final double imageMargin; /// 设置图标与文本的相对位置。详见 [ImageAlignment] /// /// Set the relative position of the icon and the text. See [ImageAlignment] for details final ImageAlignment imageAlignment; /// 是否启动 Loading 状态。Loading 状态会覆盖 [image] 配置 /// /// Whether to start the loading state. Loading status will override [image] configuration final bool loading; /// loading 状态时的 Loading 小部件。会覆盖默认的 Loading 效果 /// /// Loading widget in loading state. Will override the default Loading effect final Widget loadingWidget; /// Loading 的颜色 /// /// Loading colors final Color loadingColor; /// Loading 的宽度 /// /// Loading width final double loadingStrokeWidth; /// Loading 的大小 /// /// Loading size final double loadingSize; /// 是否启用点击进入 Loading 状态的模式 /// /// Whether to enable click to enter the loading mode final bool clickLoading; /// Loading 状态下是否隐藏文本 /// /// Whether to hide text in the loading state final bool hideTextOnLoading; /// Loading 状态下展示的文本 /// /// Text displayed under Loading final String loadingText; /// 表面的风格。默认 [FSurface.Flat]。详见 [FSurface] /// /// Surface style. Default [FSurface.Flat]. See [FSurface] for details final FSurface surfaceStyle; /// 鼠标进入/退出组件范围时会回调 /// /// Callback when the mouse enters/exits the component range final ValueChanged onHover; /// 按下时会回调 /// /// Callback when pressed final VoidCallback onPressedDown; /// 抬起时会回调 /// /// Callback when lifted final VoidCallback onPressedUp; /// 按下取消时会回调 /// /// Callback when cancel is pressed final VoidCallback onPressedCancel; /// 是否支持 Neumorphism 风格。开启该项 [highlightColor] 将会失效 /// /// Whether to support the Neumorphism style. Open this item [highlightColor] will be invalid final bool isSupportNeumorphism; /// 当 [isSupportNeumorphism] 为 true 时有效。光源方向,分为左上、左下、右上、右下四个方向。用来控制光源照射方向,会影响高亮方向和阴影方向 /// /// Valid when [isSupportNeumorphism] is true. The direction of the light source is divided into four directions: upper left, lower left, upper right, and lower right. Used to control the illumination direction of the light source, which will affect the highlight direction and shadow direction final FLightOrientation lightOrientation; FButton({ Key key, this.onPressed, this.text, this.color = Colors.transparent, this.disabledColor, this.hoverColor, this.highlightColor, this.padding, this.width, this.height, this.corner, this.cornerStyle = FCornerStyle.round, this.strokeColor, this.strokeWidth, this.shadowColor, this.shadowOffset, this.shadowBlur = 0.0, this.gradient, this.image, this.imageMargin = 6.0, this.imageAlignment = ImageAlignment.left, this.loading = false, this.loadingColor, this.loadingStrokeWidth = 4.0, this.clickLoading = false, this.hideTextOnLoading = false, this.loadingText, this.loadingSize = 12, this.clickEffect = false, this.style, this.disableStyle, this.alignment, this.activeMaskColor = Colors.transparent, this.surfaceStyle = FSurface.Flat, this.onHover, this.onPressedDown, this.onPressedUp, this.onPressedCancel, this.isSupportNeumorphism = false, this.highlightShadowColor, this.loadingWidget, this.lightOrientation = FLightOrientation.LeftTop, }) : super(key: key); @override State createState() { return _FButton(); } } class _FButton extends State with SingleTickerProviderStateMixin { double shadowBlur; Color shadowColor; Tween shadowTween; AnimationController animationController; bool get enabled => widget.onPressed != null && !loading; bool loading = false; @override void initState() { super.initState(); updateParam(); animationController = AnimationController( duration: Duration(milliseconds: 300), vsync: this, ); shadowTween = Tween(begin: 0, end: widget.shadowBlur); animationController.addListener(() { setState(() { shadowBlur = shadowTween.evaluate(animationController); }); }); } @override void didUpdateWidget(FButton oldWidget) { super.didUpdateWidget(oldWidget); updateParam(); } @override void dispose() { animationController.dispose(); super.dispose(); } updateParam() { shadowBlur = widget.shadowBlur; shadowColor = widget.shadowColor; loading = widget.loading; } @override Widget build(BuildContext context) { double disableOpacity = 0.58; /// Handle the relationship between [image] and [loading] Widget image = loading ? widget.loadingWidget ?? SizedBox( width: widget.loadingSize, height: widget.loadingSize, child: CircularProgressIndicator( strokeWidth: widget.loadingStrokeWidth, valueColor: AlwaysStoppedAnimation(widget.loadingColor == null ? Theme.of(context).accentColor.withOpacity(disableOpacity) : widget.loadingColor.withOpacity(disableOpacity)), ), ) : widget.image; /// Corner BorderRadius borderRadius = widget.corner == null ? BorderRadius.all(Radius.circular(0)) : BorderRadius.only( topLeft: Radius.circular(widget.corner.leftTopCorner), topRight: Radius.circular(widget.corner.rightTopCorner), bottomRight: Radius.circular(widget.corner.rightBottomCorner), bottomLeft: Radius.circular(widget.corner.leftBottomCorner), ); /// side Color sideColor = widget.strokeColor ?? Colors.transparent; BorderSide borderSide = BorderSide( width: widget.strokeWidth ?? 0, color: sideColor, style: BorderStyle.solid, ); /// shape FShape shape = FShape( borderShape: widget.cornerStyle == FCornerStyle.round ? FBorderShape.RoundedRectangle : FBorderShape.BeveledRectangle, side: borderSide, borderRadius: borderRadius, ); /// Handle the relationship between loading text and regular text String loadingText = widget.loadingText == null ? widget.text : widget.loadingText; String text = loading ? loadingText : widget.text; Widget layerText = _buildTextLayer(text); Widget layerRow = _buildRowLayer(text, image, layerText); ///////////////// Widget layerContainer = FControl( lightOrientation: widget.lightOrientation, width: widget.width, height: widget.height, padding: widget.padding, gradient: widget.gradient, shape: shape, surface: widget.surfaceStyle, supportDropShadow: (shadowColor != null && shadowBlur != 0.0) || widget.isSupportNeumorphism, dropShadow: FShadow( highlightColor: widget.isSupportNeumorphism ? widget.highlightShadowColor ?? Colors.white.withOpacity(0.83) : Colors.transparent, highlightBlur: widget.isSupportNeumorphism ? _shadowBlur : 0.0, highlightDistance: shadowDistance, shadowColor: shadowColor ?? Color(0xffd1d9e6), shadowBlur: _shadowBlur, shadowDistance: shadowDistance, shadowOffset: widget.shadowOffset, ), supportInnerShadow: widget.isSupportNeumorphism, innerShadow: FShadow( highlightColor: widget.highlightShadowColor ?? Colors.white.withOpacity(0.83), highlightBlur: _shadowBlur, highlightDistance: shadowDistance, shadowColor: shadowColor ?? Color(0xffd1d9e6), shadowBlur: _shadowBlur, shadowDistance: shadowDistance, ), appearance: widget.isSupportNeumorphism ? FAppearance.Neumorphism : FAppearance.Material, onTapCallback: (_, __) { onPressed(); }, onTapDownCallback: (_, __) { widget.onPressedDown?.call(); }, onTapUpCallback: (_, __) { widget.onPressedUp?.call(); }, onTapCancelCallback: (_, __) { widget.onPressedCancel?.call(); }, maskColor: widget.activeMaskColor, colorForCallback: (sender, state) { if (state == FState.Highlighted) { return widget.isSupportNeumorphism ? widget.color : widget.highlightColor; } else if (state == FState.Disable) { return widget.disabledColor ?? (widget.color ?? FDisableColor).withOpacity(disableOpacity); } return widget.color; }, disabled: !enabled, hoverColor: widget.hoverColor, onHover: widget.onHover != null ? (v) { widget.onHover(v); } : null, child: Container( alignment: widget.alignment, child: layerRow, ), ); ///////////////// Widget result = Semantics( button: true, enabled: enabled, child: layerContainer, ); return result; } double get _shadowBlur { if ((shadowBlur == null || shadowBlur == 0.0) && widget.isSupportNeumorphism) { return 6.0; } else { return shadowBlur; } } double get shadowDistance { if (widget.isSupportNeumorphism) { return widget.shadowOffset?.dy ?? 3.0; } else { return widget.shadowOffset?.dy ?? 0.0; } } Text _buildTextLayer(String text) { return Text( text ?? "", style: enabled ? widget.style : widget.disableStyle ?? widget.style, ); } Widget _buildRowLayer(String text, Widget image, Widget layerText) { if (image == null) return layerText; var showLoading = (loading && widget.hideTextOnLoading); if (showLoading || text == null || text == "") { return image; } else { switch (widget.imageAlignment) { case ImageAlignment.left: return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ image, SizedBox(width: widget.imageMargin), layerText, ], ); case ImageAlignment.top: return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ image, SizedBox(height: widget.imageMargin), layerText, ], ); case ImageAlignment.right: return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ layerText, SizedBox(width: widget.imageMargin), image, ], ); case ImageAlignment.bottom: return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ layerText, SizedBox(height: widget.imageMargin), image, ], ); } } return layerText; } onPressed() { widget.onPressed?.call(); if (widget.clickLoading && !loading) { loading = true; setState(() {}); } else if (widget.clickEffect) { pressOutEffect(); } } pressOutEffect() { shadowBlur = (shadowBlur ?? 0) + 6; shadowColor = widget.shadowColor; if (shadowColor == null) { if (widget.isSupportNeumorphism) { shadowColor = Color(0xffd1d9e6); } else if (widget.strokeColor != null) { shadowColor = widget.strokeColor.withOpacity(0.58); } else { shadowColor = widget.color.withOpacity(0.58); } } shadowTween ..begin = shadowBlur ..end = widget.shadowBlur; animationController ..value = 0.0 ..forward(); } } ================================================ FILE: pubspec.yaml ================================================ name: fbutton description: Let developers just need to grasp only one button component. version: 2.0.1 author: CoorChice homepage: https://github.com/Fliggy-Mobile/fbutton environment: sdk: ">=2.2.0 <3.0.0" dependencies: flutter: sdk: flutter fcontrol: ^1.0.0 dev_dependencies: flutter_test: sdk: flutter # fcontrol: # path: ../fcontrol # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: # This section identifies this Flutter project as a plugin project. # The androidPackage and pluginClass identifiers should not ordinarily # be modified. They are used by the tooling to maintain consistency when # adding or updating assets for this project. # plugin: # androidPackage: com.taobao.fapi.fbutton # pluginClass: FbuttonPlugin # To add assets to your plugin package, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # # For details regarding assets in packages, see # https://flutter.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. # To add custom fonts to your plugin package, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts in packages, see # https://flutter.dev/custom-fonts/#from-packages