From 65ba11fc35b41ebac684900e6255d6a8cdd1b14d Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Sun, 19 Jun 2022 17:02:43 +0100 Subject: [PATCH] feat: Example App Home Page UI --- .gitignore | 1 + lib/home.dart | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/main.dart | 64 ++---------- 3 files changed, 288 insertions(+), 57 deletions(-) create mode 100644 lib/home.dart diff --git a/.gitignore b/.gitignore index dbef116..605e7b9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .dart_tool/ .packages build/ +.idea/ # If you're building an application, you may want to check-in your pubspec.lock pubspec.lock diff --git a/lib/home.dart b/lib/home.dart new file mode 100644 index 0000000..70ad2da --- /dev/null +++ b/lib/home.dart @@ -0,0 +1,280 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; + +class home extends StatefulWidget { + @override + State createState() => _homeState(); +} + +class _homeState extends State { + // final CategoriesScroller categoriesScroller = CategoriesScroller(); + + ScrollController controller = ScrollController(); + + bool closeTopContainer = false; + + double topContainer = 0; + + @override + void initState() { + super.initState(); + controller.addListener(() { + double value = controller.offset /300; + setState(() { + topContainer = value; + closeTopContainer = controller.offset > 0; + }); + }); + } + + @override + Widget build(BuildContext context) { + final double categoryHeight = MediaQuery.of(context).size.height *0.48; + return SafeArea( + child: Scaffold( + backgroundColor: Color(0xFFBCD51C), + body: Container( + height: MediaQuery.of(context).size.height, + child: Column( + children: [ + AnimatedOpacity( + duration: const Duration(milliseconds: 120), + opacity: closeTopContainer ? 0 : 1, + child: AnimatedContainer( + duration: const Duration(milliseconds: 1000), + width: MediaQuery.of(context).size.width, + alignment: Alignment.topCenter, + height: closeTopContainer ? 0 : categoryHeight, + child: Container( + padding: EdgeInsets.only(left: MediaQuery.of(context).size.width*0.05), + color: Color(0xFFBCD51C), + width: MediaQuery.of(context).size.width, + child: Column( + children: [ + SizedBox( + height: MediaQuery.of(context).size.height*0.1, + ), + Container( + alignment: Alignment.centerLeft, + child: Text("Hi Cartez,",style: TextStyle(fontSize: 28),) + ), + Container( + alignment: Alignment.centerLeft, + child:Text("Welcome back",style: TextStyle(fontSize: 28,fontWeight: FontWeight.bold),), + ), + SizedBox( + height: 20, + ), + Text("Available balance",style: TextStyle(fontSize: 14),), + SizedBox( + height: 18, + ), + Text("\$3,100,",style: TextStyle(fontSize: 45,fontWeight: FontWeight.bold),), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 3, + width: 3, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black, + ), + ), + SizedBox( + width: 7, + ), + Container( + height: 5, + width: 5, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black, + ), + ), + SizedBox( + width: 7, + ), + Container( + height: 3, + width: 3, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black, + ), + ), + ], + ), + SizedBox( + height: MediaQuery.of(context).size.height*0.05, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Container( + height: 55, + width: 55, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black, + ), + child:Icon(Icons.add_box_rounded, color: Colors.white,size: 32,), + alignment: Alignment.center, + ), + SizedBox( + height: 10, + ), + Text("Top Up",style: TextStyle(fontSize: 13,fontWeight: FontWeight.bold),), + ], + ), + Column( + children: [ + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black, + ), + child: Icon(Icons.send_outlined, color: Colors.white,size: 32,), + alignment: Alignment.center, + ), + SizedBox( + height: 10, + ), + Text("Send",style: TextStyle(fontSize: 13,fontWeight: FontWeight.bold),), + ], + ), + Column( + children: [ + Container( + height: 50, + width: 50, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.black, + ), + child: Icon(Icons.call_received_outlined, color: Colors.white,size: 32,), + alignment: Alignment.center, + ), + SizedBox( + height: 10, + ), + Text("Request",style: TextStyle(fontSize: 13,fontWeight: FontWeight.bold),), + ], + ), + ], + ) + ], + ), + ) + ), + ), + Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(20),topRight: Radius.circular(20)), + ), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height*0.055, + child: Padding( + padding: EdgeInsets.fromLTRB(MediaQuery.of(context).size.width*0.08, MediaQuery.of(context).size.height*0.01, 0,0), + child: Text("Last Transaction",style: TextStyle(fontSize: 20,fontWeight: FontWeight.bold),), + ), + ), + Expanded( + child: Container( + color: Colors.white, + child: ListView.builder( + controller: controller, + itemCount: 50, + itemBuilder: (context, index) { + double scale = 1.0; + if (topContainer >0.5) { + scale = index + 0.5 - topContainer; + if (scale < 0) { + scale = 0; + } else if (scale > 1) { + scale = 1; + } + } + return Opacity( + opacity: scale, + child: Align( + alignment: Alignment.topCenter, + child: Container( + padding: EdgeInsets.only(left: MediaQuery.of(context).size.width*0.053), + height: MediaQuery.of(context).size.height *0.1, + width: MediaQuery.of(context).size.width, + child: Row( + children: [ + Container( + height: 46, + width: 46, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFFEDEDE6), + ), + child: Icon(Icons.shopping_bag_outlined, color: Colors.black,), + alignment: Alignment.center, + ), + Padding( + padding: EdgeInsets.only(left: 20,top: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Gold",style: TextStyle(fontSize: 20,fontWeight: FontWeight.w900),), + Text("Transaction ID $index",style: TextStyle(fontSize: 15,fontWeight: FontWeight.w500),), + ], + ), + ), + ], + ) + ) + ), + ); + }), + )), + ], + ), + ), + bottomNavigationBar: BottomNavigationBar( + currentIndex: 0, + selectedItemColor: Colors.black, + backgroundColor: Colors.white, + type: BottomNavigationBarType.fixed, + onTap: (int index) { + + }, + items:[ + BottomNavigationBarItem( + icon: Icon(Icons.home_filled, color: Colors.black,), + label: '', + ), + BottomNavigationBarItem( + icon: Icon(Icons.account_balance_wallet_outlined, color: Colors.black,), + label: '', + ), + BottomNavigationBarItem( + icon: Icon(Icons.qr_code_scanner, color: Colors.black,), + label: '', + ), + BottomNavigationBarItem( + icon: Icon(Icons.bar_chart, color: Colors.black,), + label: '', + ), + BottomNavigationBarItem( + icon: Icon(Icons.perm_identity, color: Colors.black,), + label: '', + ), + ], + ), + ), + ); + } +} + diff --git a/lib/main.dart b/lib/main.dart index 202509b..cade902 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:clnapp/home.dart'; import 'package:flutter/material.dart'; void main() { @@ -7,21 +8,12 @@ void main() { class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); - // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', + debugShowCheckedModeBanner: false, theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), @@ -31,16 +23,6 @@ class MyApp extends StatelessWidget { class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - final String title; @override @@ -50,49 +32,14 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { int _counter = 0; - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. return Scaffold( appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( @@ -106,10 +53,13 @@ class _MyHomePageState extends State { ), ), floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, + onPressed: (){ + Navigator.pushReplacement(context, + MaterialPageRoute(builder: (context) => home())); + }, tooltip: 'Increment', child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + ), ); } }