FABs terminados y completamente funcionales

parent 9a727607
...@@ -32,8 +32,6 @@ migrate_working_dir/ ...@@ -32,8 +32,6 @@ migrate_working_dir/
.pub-cache/ .pub-cache/
.pub/ .pub/
/build/ /build/
*generated_plugin*
*GeneratedPluginRegistrant*
# Symbolication related # Symbolication related
app.*.symbols app.*.symbols
......
import 'package:flutter/material.dart';
import 'package:prueba_multimedia/action_button.dart';
import 'package:prueba_multimedia/expandable_fab.dart';
class AgregarArchivoExpandableFab extends StatelessWidget {
const AgregarArchivoExpandableFab({super.key});
@override
Widget build(BuildContext context) {
return ExpandableFab(
distance: 60,
icon: Icon(Icons.add),
children: loadActionButtons(context)
);
}
void _showAction(BuildContext context) {
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Funcionalidad a implementar'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('CLOSE'),
),
],
);
},
);
}
List<Widget> loadActionButtons(BuildContext context){
final buttons = <Widget>[];
for(var element in _ActionButtons.values){
buttons.add(ActionButton(
onPressed: () => _showAction(context),
label: element.label,
icon: element.icon)
);
}
return buttons;
}
}
enum _ActionButtons{
NUEVO_ARCHIVO('Archivo', Icon(Icons.description_outlined)),
NUEVA_CARPETA('Carpeta', Icon(Icons.folder_outlined)),
NUEVO_ENLACE('Enlace', Icon(Icons.link_outlined));
final String label;
final Icon icon;
const _ActionButtons(this.label, this.icon);
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'action_button.dart';
import 'expandable_fab.dart';
class ConVertexFabBar extends StatefulWidget {
const ConVertexFabBar({super.key});
@override
State<ConVertexFabBar> createState() => _ConVertexFabBarState();
}
class _ConVertexFabBarState extends State<ConVertexFabBar> {
bool _convertirOpen = false;
bool _agregarOpen = false;
final _agregarKey = GlobalKey<ExpandableFabState>();
final _convertirKey = GlobalKey<ExpandableFabState>();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: (_agregarOpen || _convertirOpen)? MediaQuery.of(context).size.height : 56,
child: Stack(
children: [
GestureDetector(
onTap: () {
setState(() {
_agregarOpen = false;
_convertirOpen = false;
});
_agregarKey.currentState?.close();
_convertirKey.currentState?.close();
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [..._buildFABs()],
)
],
),
);
}
List<Widget> _buildFABs() {
final toRet = <Widget>[];
// Convertir FAB
toRet.add(Stack(
alignment: Alignment.bottomLeft,
children: [
ExpandableFab(
invert: true,
distance: 60,
icon: Icon(Icons.label_important_outline),
label: 'Convertir',
children: _loadConvertirActionButtons(context),
key: _convertirKey
),
SizedBox(
width: 130,
height: 56,
child: GestureDetector(
onTap: () {
setState(() {
_agregarOpen = false;
_convertirOpen = !_convertirOpen;
});
_agregarKey.currentState?.close();
_convertirKey.currentState?.tap();
},
),
)
],
));
// Agregar FAB
toRet.add(Stack(
alignment: Alignment.bottomRight,
children: [
ExpandableFab(
distance: 60,
icon: Icon(Icons.add),
children: _loadAgregarActionButtons(context),
key: _agregarKey,
),
SizedBox(
width: 56,
height: 56,
child: GestureDetector(
onTap: () {
setState(() {
_convertirOpen = false;
_agregarOpen = !_agregarOpen;
});
_convertirKey.currentState?.close();
_agregarKey.currentState?.tap();
},
),
)
],
));
return toRet;
}
List<Widget> _loadAgregarActionButtons(BuildContext context){
final buttons = <Widget>[];
for(var element in _AgregarActionButtons.values){
buttons.add(ActionButton(
onPressed: () => _showPlaceholderAction(context),
label: element.label,
icon: element.icon)
);
}
return buttons;
}
List<Widget> _loadConvertirActionButtons(BuildContext context){
final buttons = <Widget>[];
for(var element in _ConvertirActionButtons.values){
buttons.add(ActionButton(
onPressed: () => _showPlaceholderAction(context),
label: element.label,
icon: element.icon)
);
}
return buttons;
}
void _showPlaceholderAction(BuildContext context) {
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Funcionalidad a implementar'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('CLOSE'),
),
],
);
},
);
}
}
enum _AgregarActionButtons{
NUEVO_ARCHIVO('Archivo', Icon(Icons.description_outlined)),
NUEVA_CARPETA('Carpeta', Icon(Icons.folder_outlined)),
NUEVO_ENLACE('Enlace', Icon(Icons.link_outlined));
final String label;
final Icon icon;
const _AgregarActionButtons(this.label, this.icon);
}
enum _ConvertirActionButtons{
COPIAR_ARCHIVOS('Copiar', Icon(Icons.copy)),
COMPRIMIR_ARCHIVOS('Comprimir', Icon(Icons.splitscreen_outlined)),
REEMPLAZAR_ARCHIVOS('Reemplazar', Icon(Icons.change_circle_outlined));
final String label;
final Icon icon;
const _ConvertirActionButtons(this.label, this.icon);
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:prueba_multimedia/action_button.dart';
import 'package:prueba_multimedia/expandable_fab.dart';
class ConvertirExpandableFab extends StatelessWidget {
const ConvertirExpandableFab({super.key});
@override
Widget build(BuildContext context) {
return ExpandableFab(
invert: true,
distance: 60,
icon: Icon(Icons.label_important_outline),
label: 'Convertir',
children: loadActionButtons(context)
);
}
void _showAction(BuildContext context) {
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Funcionalidad a implementar'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('CLOSE'),
),
],
);
},
);
}
List<Widget> loadActionButtons(BuildContext context){
final buttons = <Widget>[];
for(var element in _ActionButtons.values){
buttons.add(ActionButton(
onPressed: () => _showAction(context),
label: element.label,
icon: element.icon)
);
}
return buttons;
}
}
enum _ActionButtons{
COPIAR_ARCHIVOS('Copiar', Icon(Icons.copy)),
COMPRIMIR_ARCHIVOS('Comprimir', Icon(Icons.splitscreen_outlined)),
REEMPLAZAR_ARCHIVOS('Reemplazar', Icon(Icons.change_circle_outlined));
final String label;
final Icon icon;
const _ActionButtons(this.label, this.icon);
}
\ No newline at end of file
...@@ -21,10 +21,10 @@ class ExpandableFab extends StatefulWidget { ...@@ -21,10 +21,10 @@ class ExpandableFab extends StatefulWidget {
}); });
@override @override
State<ExpandableFab> createState() => _ExpandableFabState(); State<ExpandableFab> createState() => ExpandableFabState();
} }
class _ExpandableFabState extends State<ExpandableFab> class ExpandableFabState extends State<ExpandableFab>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late final AnimationController _controller; late final AnimationController _controller;
late final Animation<double> _expandAnimation; late final Animation<double> _expandAnimation;
...@@ -52,6 +52,16 @@ class _ExpandableFabState extends State<ExpandableFab> ...@@ -52,6 +52,16 @@ class _ExpandableFabState extends State<ExpandableFab>
super.dispose(); super.dispose();
} }
void tap(){
_toggle();
}
void close(){
if(_open){
_toggle();
}
}
void _toggle(){ void _toggle(){
setState(() { setState(() {
_open = !_open; _open = !_open;
...@@ -67,13 +77,16 @@ class _ExpandableFabState extends State<ExpandableFab> ...@@ -67,13 +77,16 @@ class _ExpandableFabState extends State<ExpandableFab>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
width: (widget.label != null || _open)? 170 : 56, width: _computeWidth(),
height: _open? 56 + (widget.distance*widget.children.length) : 56, height: _open? 56 + (widget.distance*widget.children.length) : (MediaQuery.of(context).size.height),
child: SizedBox.expand( child: SizedBox.expand(
child: Stack( child: Stack(
alignment: widget.invert? Alignment.bottomLeft : Alignment.bottomRight, alignment: widget.invert? Alignment.bottomLeft : Alignment.bottomRight,
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [
GestureDetector(
onTap: () {if(_open) _toggle();},
),
_buildTapToCloseFab(), _buildTapToCloseFab(),
..._buildExpandingActionButtons(), ..._buildExpandingActionButtons(),
_buildTapToOpenFab()] _buildTapToOpenFab()]
...@@ -163,6 +176,17 @@ class _ExpandableFabState extends State<ExpandableFab> ...@@ -163,6 +176,17 @@ class _ExpandableFabState extends State<ExpandableFab>
return children; return children;
} }
double _computeWidth() {
if(_open){
if(widget.label != null) return 170.0;
return 130.0;
}
else{
if(widget.label != null) return 130.0;
return 56.0;
}
}
} }
class _ExpandingActionButton extends StatelessWidget { class _ExpandingActionButton extends StatelessWidget {
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:prueba_multimedia/agregar_archivo_expandable_fab.dart'; import 'package:prueba_multimedia/convertex_fab_bar.dart';
import 'package:prueba_multimedia/convertir_expandable_fab.dart';
class PaginaPrincipal extends StatelessWidget { class PaginaPrincipal extends StatelessWidget {
const PaginaPrincipal({super.key}); const PaginaPrincipal({super.key});
...@@ -11,12 +10,30 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -11,12 +10,30 @@ class PaginaPrincipal extends StatelessWidget {
appBar: AppBar( appBar: AppBar(
title: Text('ConVertex'), title: Text('ConVertex'),
actions: [ actions: [
IconButton(onPressed: () {}, IconButton(onPressed: () {
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Funcionalidad a implementar'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('CLOSE'),
),
],
);
},
);
},
icon: Icon(Icons.settings_outlined)) icon: Icon(Icons.settings_outlined))
], ],
), ),
body: _construirCuerpo(context), body: _construirCuerpo(context),
floatingActionButton: contruirFBAs(context), floatingActionButton: Padding(
padding: const EdgeInsets.all(16.0),
child: ConVertexFabBar()
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
); );
} }
...@@ -42,30 +59,4 @@ class PaginaPrincipal extends StatelessWidget { ...@@ -42,30 +59,4 @@ class PaginaPrincipal extends StatelessWidget {
) )
); );
} }
Widget contruirFBAs(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
/*FloatingActionButton.extended(
onPressed: () {},
icon: Icon(
Icons.label_important_outline,
size: 30.0,
),
label: Text(
'Convertir',
style: Theme.of(context).textTheme.bodyLarge,
textScaler: TextScaler.linear(1.2),
)
),*/
ConvertirExpandableFab(),
AgregarArchivoExpandableFab()
],
),
);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment