fastor_app_ui_widget 1.0.185 fastor_app_ui_widget: ^1.0.185 copied to clipboard
Coding Faster By Build Fast UI Widget
Features #
- Reduce 28% of chars in writing code & lines breaks.
- Get ride of RenderFlex overflowed by pixels.
- Basics ui widget with extra feature not found at normal widget. Example widget:
- PageFastor, TextFastor, ImageFastor, RowFastor, ColumnFastor, TextFieldFastor ..etc
- Helping make coding faster by use Utils. Example Classes:
- NetworkManager, LanguageTools, ... etc.
Get Start #
1- import dependence in yaml file:
fastor_app_ui_widget:
2- at any class must import
import 'package:fastor_app_ui_widget/fastor_app_ui_widget.dart';
Reference #
documentation #
https://pub.dev/documentation/fastor_app_ui_widget/latest/index.html
tutorial source code #
https://github.com/AbdallahAndroid/fastor_app
Tutorial Content #
Content: Widget #
Page Shapes | TextView | Button | ImageView |
Row | Column | TextField | CheckboxFastor |
Content: Classes Helper #
Tutorial : PageFastor #
Scroll Screen #
- Get ride of RenderFlex overflowed by pixels.
- Simple Example Create "PageFastor"
@override
Widget build(BuildContext context) {
return PageFastor(this,
content: getContent() );
}
- Example For Content Long Data
Widget getContent() {
return Column( children: getLongDataForTestScroll() ,);
}
List<Widget> getLongDataForTestScroll() {
List<Widget> data = [];
for (int i = 1; i <= 70; i++) {
var w = TextFastor(
"Get ride of RenderFlex, data number $i",
fontSize: 15,
width: 300,
color: Colors.yellow,
margin: EdgeInsets.all(5),
);
data.add(w);
}
return data;
}
Toolbar Custom Shape #
Create any shape of Toolbar you want in Custom shape then put it at page template by using parameter "toolbar"
@override
Widget build(BuildContext context) {
return PageFastor(this,
toolbar: ToolbarSimpleFastor( context, "Page Shapes"),
toolbar_height : 70,
content: getContent() );
}
- The Default height of toolbar is 70
- When the toolbar you draw different than 70 you can set height of toolbar by using "toolbar_height"
Background Feature #
Asset
set Image png to background, to make all content scrolling while the background image still hold at background
Asset with Opacity
@override
Widget build(BuildContext context) {
return PageFastor(this,
toolbar: ToolbarSimpleFastor( context, "Page Shapes"),
toolbar_height : 70,
//background
assetBackground: const AssetImage("assets/images/background.png"),
assetBackgroundOpacity: 0.3,
content: getContent() );
}
Custom Widget
set Custom Widget hold at background, to make all content scrolling while the background widget still holding while scrolling
@override
Widget build(BuildContext context) {
return PageFastor(this,
toolbar: ToolbarSimpleFastor( context, "Page Shapes"),
toolbar_height : 70,
//background
widgetBackground: CustomWidgetBackground(),
content: getContent() );
}
Navigation Bottom #
Custom Shape Navigation #
set Custom Widget hold at bottom of screen to navigate between multi screens
@override
Widget build(BuildContext context) {
return PageFastor(this,
//toolbar
toolbar: ToolbarSimpleFastor( context, "Page Shapes"),
toolbar_height : 70,
//navigation bottom
navigationBottom: NavigationFastor( context, 0),
navigationBottom_height: 70,
homeButtonsBackgroundColor: HexColor( "#1593bc"), //color background for home buttons
content: getContent() );
}
Change color #
Color of Home Buttons Android Device
By using parameter "homeButtonsBackgroundColor" you can write hexcode color
@override
Widget build(BuildContext context) {
return PageFastor(this,
homeButtonsBackgroundColor: HexColor( "#1593bc"), //color background for home buttons
content: getContent() );
}
Color of Status Bar
By using parameter "statusBarColorCustome" you can write hexcode color
@override
Widget build(BuildContext context) {
return PageFastor(this,
statusBarColorCustome: HexColor( "#595629"),
content: getContent() );
}
Tutorial : TextFastor #
Why use Fastor widget ? #
- Reduce 28% of chars in writing code
- Reduce 28% of lines breaks
Feature Fastor #
- Margin without use Container
- Padding without use Container
- Decoration background without use Container
- Text Align without use Style
- Text Decoration without use Style
- Font size without use Style
- Font family without use Style
- On tap without use GestureDetector
Table Result : Percentage of code writing reduction #
Using Fastor widget reduce writing code by 28% chars when you compare with normal flutter widget
See source code compare between Fastor and Normal at this page
Get Start #
Full Example
TextFastor(
"Text Fastor Simple" ,
textAlign: TextAlign.center,
textDecoration: TextDecoration.underline,
color: Colors.blue,
fontSize: 25,
fontFamily: FontProject.marina,
margin: EdgeInsets.all( 25 ),
padding: EdgeInsets.all( 10),
decoration: BoarderHelper.cardView(
colorLine: Colors.red,
colorBackground: Colors.yellow,
radiusSize: 15
),
// backgroundColor: Colors.green,
maxLines: 2,
onPressed: (){
Log.i( "click on fastor widget");
},
);
Compare Text() Normal Vs TextFastor() #
Widget getContent() {
return Column( children: [
textview_normal(),
textview_fastor()
],);
}
Widget textview_normal() {
return GestureDetector( child: Container(
child: Text(
"Text Normal" ,
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(
decoration: TextDecoration.underline,
decorationColor: Colors.blue,
color: Colors.blue,
fontSize: 25,
fontFamily: FontProject.marina
),
),
margin: EdgeInsets.all( 25 ),
padding: EdgeInsets.all( 10),
decoration: BoxDecoration(
border: Border.all(color: Colors.red ) ,
borderRadius: BorderRadius.all(
Radius.circular( 15 )
) ,
color: Colors.yellow //background color
),
// color: Colors.green,
),
onTap: (){
Log.i( "click on Normal");
},
);
}
Widget textview_fastor() {
return TextFastor(
"Text Fastor" ,
textAlign: TextAlign.center,
textDecoration: TextDecoration.underline,
color: Colors.blue,
fontSize: 25,
fontFamily: FontProject.marina,
margin: EdgeInsets.all( 25 ),
padding: EdgeInsets.all( 10),
decoration: BoarderHelper.cardView(
colorLine: Colors.red,
colorBackground: Colors.yellow,
radiusSize: 15
),
// backgroundColor: Colors.green,
maxLines: 2,
onPressed: (){
Log.i( "click on fastor widget");
},
);
}
Tutorial : ButtonFastor #
Feature Fastor #
- Margin without use Container
- Padding without use Container
- Decoration background without use Container
- Text Align without use Style
- Text Decoration without use Style
- Font size without use Style
- Font family without use Style
- On tap without use GestureDetector
Get Start #
See source code compare between Fastor and Normal at this page
Full Example
ButtonFastor(
"Button Fastor",
() {
print("click on btn type fastor");
},
margin: EdgeInsets.symmetric( vertical: 40),
textColor: Colors.blue,
background: Colors.black,
fontFamily: FontProject.marina,
textFontSize: 15,
borderLine: Colors.blue,
borderRadius: 15,
);
}
Compare Text() Normal Vs TextFastor() #
EdgeInsets.symmetric( vertical: 30),
child: ElevatedButton(
onPressed: () {
print("click on btn type normal");
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
shape: RoundedRectangleBorder (
borderRadius: BorderRadius.circular(15),
side: BorderSide(width: 1,color: Colors.blue)
)),
child: Text(
"Button Normal",
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(
color: Colors.blue,
fontSize: 15,
fontFamily: FontProject.marina
),
)
),
// color: Colors.green,
);
Tutorial : ImageFastor #
Feature Fastor #
- Background color/image without use Container
- Padding without use Container
- Aspect Ratio Image
- Radius Corner for Image
- On tap without use GestureDetector
Set Image type url + Corner Radius + Background color + opacity + onPressed + margin #
ImageFastor(
context: context,
width: 278,
height: 181,
margin: EdgeInsets.all( 10),
radius_all: 25,
boxFit_background: BoxFit.cover,
urlBackground: square_url_image_example,
colorBackground: Colors.amber,
opacity: 0.7,
onPressed: (){
print("click on image");
},
);
}
Set Image type assets + Corner Radius #
return ImageFastor(
context: context,
width: 300,
height: 600,
radius_all: 25,
assetAspectRatio: AssetImage("assets/images/background.png"),
);
Set Image auto-responsive between website screen desktop, website screen mobile and mobile real device #
same code working in all platform with save the aspect ratio size of image with all screen size of any device.
Screen Size : Website Desktop
Screen Size : Website Browser Mobile Chrome
Screen Size : Android Mobile
ImageFastor(
context: context,
width: 300,
height: 300,
radius_all: 25,
assetAspectRatio: AssetImage("assets/images/logo_example.png"),
responsive_auto: true,
);
Tutorial : RowFastor #
Feature Fastor #
- "RowScrollFastor" Scroll Horizontal for get ride of RenderFlex overflowed by pixels
RowScrollFastor #
Using Fastor widget Scroll Horizontal for get ride of RenderFlex overflowed by pixels
See source code compare between Fastor and Normal at this page
RowScrollFastor( children: getChildren() );
Tutorial : ColumnFastor #
Feature Fastor #
- Have Decoration
- Have Space : Margin, Padding
- Have Alignment
- Can Set Fixed size width/height
ColumnFastor #
Using Fastor widget Scroll Horizontal for get ride of RenderFlex overflowed by pixels
See source code compare between Fastor and Normal at this page
ColumnFastor(
children: getChildren(),
margin: EdgeInsets.only(top: 20, bottom: 20, left: 60, right: 60),
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(15)),
color: Colors.yellow //background color
),
);
Tutorial : TextFieldFastor #
Feature Fastor #
- Call from constructor of class
// validate
this.validator,
this.autovalidateMode,
this.error_text = "Missed",
//text and hint
this.hint_text,
this.text_color,
this.fontSize,
this.hint_color,
//boarder and underline
this.isRemoveUnderline = false,
this.isShowBoarder,
//background
this.background_color,
this.decoration, //at the Container
//spaces
this.padding,
this.margin,
//controller
this.controller,
this.onChanged,
//input content type
this.keyboardType,
this.obscureText = false,
//size and max/min
this.width,
this.maxLength,
this.maxLines,
this.minLines,
//other
this.textAlign ,
this.focusNode,
this.prefixIcon
Get Start #
Tutorial : Without Use Any State Management
- use "setState()"
- Create Variable at class
var email_txt = "";
var email_valid = AutovalidateMode.disabled;
- Create Widget
return TextFieldFastor(
autovalidateMode: email_valid,
margin: EdgeInsets.only( top: 10 ),
padding: EdgeInsets.all( 5),
background_color: Colors.white,
validator: ValidatorTemplate.email( ),
keyboardType: TextInputType.emailAddress,
onChanged: (s){
email_txt = s;
Log.i( "tf_email() - change s: $s ");
}
);
- Validate Form after click of button
if(validateEmailAfterClick()) {
///TO-DO : After success success field
}
bool validateEmailAfterClick() {
var result = true; //default good
//email
if ( ToolsValidation.isEmail( email_txt ) == false ){
Log.i( "missed email");
result = false;
setState(() {
email_valid = AutovalidateMode.always;
});
}
return result;
}
Tutorial : Use State Management Type "Cubit" like using "BLoc"
-
Using "Cubit" it similar as Using "BLoc"
-
Create Cubit
class AuthCubit extends Cubit<AuthState> {
final LogInUseCase logInUseCase;
AuthCubit( ) : super(AuthInitialState()) {}
static AuthCubit get(context) => BlocProvider.of(context);
AuthResponse authResponse = AuthResponse();
Future login(String email_txt, String pass_txt) async {
//....
}
void resetError() {
emit( AuthInitialState() );
}
}
- Create Cubit State
abstract class AuthState {}
class AuthInitialState extends AuthState {}
class AuthLoadingState extends AuthState {}
class AuthSuccessState extends AuthState {
//.....
}
class AuthErrorState extends AuthState
{
//.....
}
- Declare Variable at class
AuthState? stateCurrent;
var emailValid = AutovalidateMode.disabled;
var emailController = TextEditingController();
var passValid = AutovalidateMode.disabled;
var passController = TextEditingController();
- This Way You Can Set Error Message To UI
void setErrorToInputFields() {
//email
if (ToolsValidation.isEmail(emailController.text) == false) {
Log.i("missed email");
emailValid = AutovalidateMode.always;
}
//pass
if (ToolsValidation.isPasswordValid(passController.text) == false) {
Log.i("missed pass");
passValid = AutovalidateMode.always;
}
}
- Listener Cubit State
Widget getContent() {
return BlocConsumer<AuthCubit, AuthState>(
listener: (context, state) {
stateCurrent = state;
if (state is AuthSuccessState) {
RouterPage.home(context);
}
},
builder: (context, state) {
if (state is AuthErrorState) {
setErrorToInputFields();
printMessageError();
}
return Column(children: [
tfEmail(),
tfPass(),
]);
);
}
- Create Widget TextFieldFastor
Widget tfEmail() {
return TextFieldFastor(
hint_text: "Email",
controller: emailController,
autovalidateMode: emailValid,
margin: EdgeInsets.only(top: 10),
padding: EdgeInsets.all(5),
background_color: Colors.white,
validator: ValidatorTemplate.email(),
keyboardType: TextInputType.emailAddress,
onChanged: (s) {
// Log.i("tfEmail() - change s: $s ");
bool isNotInit = stateCurrent! is AuthInitialState;
if (isNotInit) {
AuthCubit.get(context).resetError();
}
});
}
Widget tfPass() {
return TextFieldFastor(
hint_text: "Password",
controller: passController,
autovalidateMode: passValid,
margin: EdgeInsets.only(top: 10),
padding: EdgeInsets.all(5),
background_color: Colors.white,
validator: ValidatorTemplate.pass(),
keyboardType: TextInputType.number,
onChanged: (s) {
// Log.i("tf_pass() - change s: $s ");
});
}
Class Utils For TextField #
- class ValidatorTemplate : This have methods utils used at parameter "validator"
Tutorial : CheckboxFastor #
Feature Fastor #
- set color from constructor for active/inactive: color_inactive, color_active
- Set Text Style : color, font size, weight.
- Remove default padding found when use normal checkbox widget.
Get Start #
Simple Example
- Create Variable at class
bool isAgree = false;
- Create Widget
return CheckboxFastor( context: context, value: isAgree,
margin: EdgeInsets.only(top: 10),
text: "Are you agree to terms and condition.",
text_color: Colors.brown,
text_dimen: 20,
color_inactive : Colors.brown,
color_active: Colors.green,
onChanged: (updatedValue) {
setState(() {
isAgree = updatedValue!;
});
}
);
Helper Classes #
NetworkManager #
Feature #
- Fix Error "XMLHttpRequest" found in platform Web.
- Feature "CallBack()" return value like interface.
- Feature NetworkType.file : to upload file in all platform( Android/IPhone/Web).
- Class "NetworkHeaderTools" to generate "bearerToken()" and "basicAuth_usernameAndPassword()" easily.
Simple Example #
- There is many steps to call API, you need to prepare: Body, Url, Header, token.
- Here is guide
1- Generate Body
Map<String, dynamic> bodyParameter = Map();
bodyParameter[ "payment_method"] = "cash";
bodyParameter[ "price"] = "123";
2- Call Class "NetworkManagerDio.dart" #
We will return the response in format JSON
Response response = await NetworkManagerDio().post( url , body: bodyParameter );
if (response.statusCode == 200) {
var result = CityResponse.fromJson( response.data);
return result;
}
NetworkType #
NetworkManagerDio().get();
NetworkManagerDio().post();
NetworkManagerDio().put();
NetworkManagerDio().delete();
NetworkManagerDio().file();
Enum of Network type
enum NetworkTypeDio{
get,
post,
put,
delete,
file
}
Upload File
- What is class "xFile" it's famous used by plugin "cross_file".
- Generate XFile used by image picker
class "NetworkRequestFile"
this class used to set the path of file of "xFile" and set the key/value of file
Example upload file type "xFile"
Future _startAPI() async {
//body request
Map<String, dynamic> body = Map();
body[ "payment_method"] = "cash";
body[ "price"] = "123";
//set type requestFile
NetworkRequestFile? requestFile = NetworkRequestFile.fromXFileAndBody( xFile!, body );
//header
var token = await UserSingleTone.instance().getToken();
Map<String, String> header = NetworkHeaderTools.bearerToken( token );
NetworkManagerDio().file(urlApiLink,
requestFile: requestFile,
headers: header,
callback: (status, msg, json){
parseJson(json );
});
Types Of Webservice Network Dependence #
- dio : use class "NetworkManagerDio.dart"
- http : use class "NetworkManagerHttp.dart"
LanguageTools #
Arabic right-to-left "RTL" Layout Direction #
How To User Class "LanguageTools.dart" to auto change direction from ( English => Arabic )
@override
Widget build(BuildContext context) {
FastorStateManagement.instance().getCurrentContext();
return PageFastor(this, content: getDirection());
}
Widget getDirection() {
return Directionality(
textDirection: LanguageTools.getTextDirection(context),
child: Builder(
builder: (BuildContext context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
),
child: getContent(),
);
},
),
);
}
NavigationTools #
- add class "NavigationTools" for push() or pushAndRemove() or pushWithResumeLifecycle()
class NavigationTools {
//---------------------------------------------------------------------- tools general
static void push(BuildContext context, Widget page ) {
var materialPageRoute = MaterialPageRoute(builder: (context) => page);
Navigator.push(context , materialPageRoute );
}
/**
* this make librasry "need_resume" working with push to next page
*/
static void pushResume(BuildContext context, Widget page, ResumableState resume ) {
var materialPageRoute = MaterialPageRoute(builder: (context) => page);
resume.push( context, materialPageRoute );
}
/**
* clearPrevious pages
*/
static void pushAndRemoveUntil(BuildContext context, Widget page ) {
var materialPageRoute = MaterialPageRoute(builder: (ctx) => page);
Navigator.pushAndRemoveUntil(context, materialPageRoute, (e) => false);
}
}
InternetTools #
- add class "InternetTools" for check for internet connection.
bool status = await InternetTools.isConnected();
At The End #
About Developer #
• 7 Years of experience build +20 App.
• Mobile Developer: Flutter & Native Android IOS.
• Skills: Dart, Java, Kotlin, Swift UIKit, SwiftUI
• OCA, Oracle Certified Associate.
Follow my Project on Instagram : #
How to contribute #
Want to contribute to the project? We will be proud to highlight you as one of our collaborators. Here are some points where you can contribute and make Fastor (and Flutter) even better.
Write articles or make videos teaching how to use Fastor (they will be inserted in the Readme and in the future in our Wiki). Offering PRs for code/tests. Including new functions. Any contribution is welcome!
Contact for contribute: #
License BSD 3 #
Copyright (c) 2022, Abdallah Mahmoud Ahmed Shehata
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of fastor-app.com nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.