RectRevealButton class
Botón animado con efecto reveal rectangular que alterna entre dos estados.
Genera una transición rectangular que se expande desde un punto (click, izquierda o derecha) hasta cubrir el área del botón, creando una transición suave entre dos contenidos y dos esquemas de color.
Ideal para: toggles horizontales, switches deslizantes, botones de activación/desactivación, y cualquier control que requiera feedback visual direccional.
Cómo funciona
- El fondo alterna entre
selectedBackgroundColoryunselectedBackgroundColor. - El reveal dibuja un rectángulo del color correspondiente al estado destino.
- El contenido alterna entre
selectedChild(seleccionado) yunselectedChild(no seleccionado). - La dirección puede ser desde el click, desde la izquierda o desde la derecha.
Anatomía del efecto
Estado inicial: NO SELECCIONADO
┌─────────────────────┐
│ unselectedChild │ ← Fondo: unselectedBackgroundColor
└─────────────────────┘
Al tocar (fromClick):
┌─────────────────────┐
│ ▌████████▐ │ ← Rectángulo expandiéndose (selectedRippleColor)
└─────────────────────┘
Al tocar (fromLeft):
┌─────────────────────┐
│███████ │ ← Rectángulo desde izquierda
└─────────────────────┘
Estado final: SELECCIONADO
┌─────────────────────┐
│ selectedChild │ ← Fondo: selectedBackgroundColor
└─────────────────────┘
Buenas prácticas
- Usa colores contrastantes entre fondo y reveal para maximizar el impacto visual.
- Asegúrate de que
selectedChildyunselectedChildsean visualmente distintos. - Para esquinas suaves, incrementa
borderRadius(mínimo 2.0). - Si controlas el estado externamente, usa
isSelectedy actualízalo consetState. - Usa
RevealDirection.fromLeftofromRightpara indicar dirección de activación/desactivación.
Ejemplos
Ejemplo básico (toggle ON/OFF)
RectRevealButton(
selectedChild: const Text(
'ON',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
unselectedChild: const Text(
'OFF',
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
selectedBackgroundColor: Colors.black,
unselectedBackgroundColor: Colors.white,
selectedRippleColor: Colors.black,
unselectedRippleColor: Colors.white,
onPressed: () => debugPrint('¡Alternado!'),
)
Ejemplo con iconos y dirección desde la izquierda
RectRevealButton(
selectedChild: const Icon(Icons.favorite, color: Colors.white),
unselectedChild: const Icon(Icons.favorite_border, color: Colors.red),
selectedBackgroundColor: Colors.red,
unselectedBackgroundColor: Colors.grey.shade100,
selectedRippleColor: Colors.red,
unselectedRippleColor: Colors.grey.shade300,
revealDirection: RevealDirection.fromLeft,
height: 56,
width: 56,
borderRadius: 28,
onPressed: () => print('Favorito alternado'),
)
Ejemplo con control externo
class MyToggle extends StatefulWidget {
const MyToggle({super.key});
@override
State<MyToggle> createState() => _MyToggleState();
}
class _MyToggleState extends State<MyToggle> {
bool _isActive = false;
@override
Widget build(BuildContext context) {
return RectRevealButton(
isSelected: _isActive,
selectedChild: const Text('Activo'),
unselectedChild: const Text('Inactivo'),
selectedBackgroundColor: Colors.blue,
unselectedBackgroundColor: Colors.grey.shade200,
selectedRippleColor: Colors.blue,
unselectedRippleColor: Colors.grey,
revealDirection: RevealDirection.fromLeft,
onPressed: () => setState(() => _isActive = !_isActive),
);
}
}
Ejemplo con borde decorativo y dirección desde la derecha
RectRevealButton(
selectedChild: const Text(
'Premium',
style: TextStyle(color: Colors.amber, fontWeight: FontWeight.bold),
),
unselectedChild: const Text('Básico'),
selectedBackgroundColor: Colors.black,
unselectedBackgroundColor: Colors.white,
selectedRippleColor: Colors.amber,
unselectedRippleColor: Colors.black,
revealDirection: RevealDirection.fromRight,
border: Border.all(color: Colors.amber, width: 2),
borderRadius: 16,
height: 56,
onPressed: () => print('Plan cambiado'),
)
Notas técnicas
- El cursor se establece automáticamente a
clicken plataformas desktop. - El reveal puede expanderse desde: el punto de tap, la izquierda o la derecha.
animationDurationcontrola la velocidad de la expansión rectangular.- El widget es completamente responsivo y se adapta al tamaño disponible.
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- RectRevealButton
Constructors
- RectRevealButton({Key? key, required Widget selectedChild, Widget? unselectedChild, required VoidCallback onPressed, Color? selectedBackgroundColor, Color? unselectedBackgroundColor, Color? selectedRippleColor, Color? unselectedRippleColor, double width = double.infinity, double height = 48, double? borderRadius, Duration? animationDuration, bool? isSelected, BoxBorder? border, EdgeInsetsGeometry padding = const EdgeInsets.symmetric(horizontal: 16), AlignmentGeometry alignment = Alignment.center, RevealDirection revealDirection = RevealDirection.fromClick, @Deprecated('Use selectedChild instead. Will be removed in v2.0.0') Widget? widgetA, @Deprecated('Use unselectedChild instead. Will be removed in v2.0.0') Widget? widgetB, @Deprecated('Use selectedBackgroundColor instead. Will be removed in v2.0.0') Color? backgroundColorA, @Deprecated('Use unselectedBackgroundColor instead. Will be removed in v2.0.0') Color? backgroundColorB, @Deprecated('Use selectedRippleColor instead. Will be removed in v2.0.0') Color? rippleColorA, @Deprecated('Use unselectedRippleColor instead. Will be removed in v2.0.0') Color? rippleColorB, @Deprecated('Use borderRadius instead. Will be removed in v2.0.0') double? radius, @Deprecated('Use animationDuration instead. Will be removed in v2.0.0') Duration? duration, @Deprecated('Use isSelected instead. Will be removed in v2.0.0') bool? selected})
-
Crea un RectRevealButton con efecto de reveal rectangular.
const
Properties
- alignment → AlignmentGeometry
-
Alineación del contenido dentro del botón.
final
- animationDuration → Duration
-
Duración de la animación del efecto reveal.
final
- border → BoxBorder?
-
Borde decorativo opcional aplicado al contorno del botón.
final
- borderRadius → double
-
Radio de redondeo de las esquinas del botón.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- height → double
-
Alto del botón en píxeles lógicos.
final
- isSelected → bool?
-
Controla el estado del botón externamente (opcional).
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- onPressed → VoidCallback
-
Callback ejecutado al presionar el botón, antes de cambiar el estado.
final
- padding → EdgeInsetsGeometry
-
Espaciado interno entre el borde del botón y su contenido.
final
- revealDirection → RevealDirection
-
Dirección desde donde se expande el efecto reveal.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- selectedBackgroundColor → Color
-
Color de fondo cuando el botón está seleccionado.
final
- selectedChild → Widget
-
Widget mostrado cuando el botón está en estado seleccionado.
final
- selectedRippleColor → Color
-
Color del rectángulo de reveal al transicionar hacia el estado seleccionado.
final
- unselectedBackgroundColor → Color
-
Color de fondo cuando el botón está no seleccionado.
final
- unselectedChild → Widget?
-
Widget mostrado cuando el botón está en estado no seleccionado.
final
- unselectedRippleColor → Color
-
Color del rectángulo de reveal al transicionar hacia el estado no seleccionado.
final
- width → double
-
Ancho del botón en píxeles lógicos.
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< RectRevealButton> -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited