|
- import 'package:chat/utils/screen.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/foundation.dart';
-
- class GZXDropdownMenuController extends ChangeNotifier {
- double dropDownHearderHeight;
-
- int menuIndex = 0;
-
- bool isShow = false;
-
- void show(int index) {
- isShow = true;
- menuIndex = index;
- notifyListeners();
- }
-
- void hide() {
- isShow = false;
- notifyListeners();
- }
- }
-
- typedef OnItemTap<T> = void Function(T value);
-
- class GZXDropDownHeader extends StatefulWidget {
- final Color color;
- final double borderWidth;
- final Color borderColor;
- final TextStyle style;
- final TextStyle dropDownStyle;
- final double iconSize;
- final Color iconColor;
- final Color iconDropDownColor;
-
- // final List<String> menuStrings;
- final double height;
- final double dividerHeight;
- final Color dividerColor;
- final GZXDropdownMenuController controller;
- final OnItemTap onItemTap;
- final List<GZXDropDownHeaderItem> items;
- final GlobalKey stackKey;
-
- GZXDropDownHeader({
- Key key,
- @required this.items,
- @required this.controller,
- @required this.stackKey,
- this.style = const TextStyle(color: Color(0xFF666666), fontSize: 13),
- this.dropDownStyle,
- this.height = 40,
- this.iconColor = const Color(0xFFafada7),
- this.iconDropDownColor,
- this.iconSize = 20,
- this.borderWidth = 0,
- this.borderColor = const Color(0xFFeeede6),
- this.dividerHeight = 20,
- this.dividerColor = const Color(0xFFeeede6),
- this.onItemTap,
- this.color = Colors.white,
- }) : super(key: key);
-
- @override
- _GZXDropDownHeaderState createState() => _GZXDropDownHeaderState();
- }
-
- class _GZXDropDownHeaderState extends State<GZXDropDownHeader>
- with SingleTickerProviderStateMixin {
- bool _isShowDropDownItemWidget = false;
-
- int _menuCount;
- GlobalKey _keyDropDownHearder = GlobalKey();
-
- @override
- void initState() {
-
- super.initState();
-
- widget.controller.addListener(_onController);
- }
-
- _onController() {
- // print(widget.controller.menuIndex);
- }
-
- @override
- Widget build(BuildContext context) {
- // print('_GZXDropDownHeaderState.build');
-
- _menuCount = widget.items.length;
-
- var gridView = GridView.count(
- physics: new NeverScrollableScrollPhysics(),
- crossAxisCount: _menuCount,
- childAspectRatio: (Screen.width / _menuCount) / widget.height,
- children: widget.items.map<Widget>((item) {
- return _menu(item);
- }).toList(),
- );
-
- return Container(
- key: _keyDropDownHearder,
- height: widget.height,
- margin: EdgeInsets.zero,
- padding: EdgeInsets.symmetric(horizontal: 10),
- decoration: BoxDecoration(
- border:
- Border.all(color: widget.borderColor, width: widget.borderWidth),
- ),
- child: gridView,
- );
- }
-
- dispose() {
- super.dispose();
- }
-
- _menu(GZXDropDownHeaderItem item) {
- int index = widget.items.indexOf(item);
- int menuIndex = widget.controller.menuIndex;
- _isShowDropDownItemWidget = index == menuIndex && widget.controller.isShow;
-
- return GestureDetector(
- onTap: () {
- final RenderBox overlay =
- widget.stackKey.currentContext.findRenderObject();
-
- final RenderBox dropDownItemRenderBox =
- _keyDropDownHearder.currentContext.findRenderObject();
-
- var position =
- dropDownItemRenderBox.localToGlobal(Offset.zero, ancestor: overlay);
- // print("POSITION : $position ");
- var size = dropDownItemRenderBox.size;
- // print("SIZE : $size");
-
- widget.controller.dropDownHearderHeight = size.height + position.dy;
-
- if (widget.controller.isShow) {
- widget.controller.hide();
- } else {
- widget.controller.show(index);
- }
- if (widget.onItemTap != null) {
- widget.onItemTap(index);
- }
- setState(() {});
- },
- child: Container(
- color: widget.color,
- width: Screen.width/3-20,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Expanded(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Flexible(
- child: Text(
- item.title, textScaleFactor: 1.0,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: _isShowDropDownItemWidget
- ? widget.dropDownStyle
- ??TextStyle(color: Theme.of(context).primaryColor, fontSize: 13)
- : widget.style,
- )),
- Icon(
- !_isShowDropDownItemWidget
- ? item.iconData ?? Icons.arrow_drop_down
- : item.iconData ?? Icons.arrow_drop_up,
- color: _isShowDropDownItemWidget
- ? widget.iconDropDownColor ?? Theme.of(context).primaryColor
- : widget.iconColor,
- size: item.iconSize ?? widget.iconSize,
- ),
- ],
- ),
- )
- ],
- )),
- );
- }
- }
-
- class GZXDropDownHeaderItem {
- final String title;
- final IconData iconData;
- final double iconSize;
-
- GZXDropDownHeaderItem(
- this.title, {
- this.iconData,
- this.iconSize,
- });
- }
-
- class GZXDropdownMenuBuilder {
- final Widget dropDownWidget;
- final double dropDownHeight;
- final callback;
-
- GZXDropdownMenuBuilder(
- {@required this.dropDownWidget,
- @required this.dropDownHeight,
- @required this.callback});
- }
-
- class GZXDropDownMenu extends StatefulWidget {
- final GZXDropdownMenuController controller;
- final List<GZXDropdownMenuBuilder> menus;
- final int animationMilliseconds;
-
- const GZXDropDownMenu(
- {Key key,
- @required this.controller,
- @required this.menus,
- this.animationMilliseconds = 100})
- : super(key: key);
-
- @override
- _GZXDropDownMenuState createState() => _GZXDropDownMenuState();
- }
-
- class _GZXDropDownMenuState extends State<GZXDropDownMenu>
- with SingleTickerProviderStateMixin {
- bool _isShowDropDownItemWidget = false;
- bool _isShowMask = false;
- bool _isControllerDisposed = false;
- Animation<double> _animation;
- AnimationController _controller;
-
- @override
- void initState() {
-
- super.initState();
-
- widget.controller.addListener(_onController);
- _controller = new AnimationController(
- duration: Duration(milliseconds: widget.animationMilliseconds),
- vsync: this);
- }
-
- _onController() {
- // print('_GZXDropDownMenuState._onController ${widget.controller.menuIndex}');
-
- _showDropDownItemWidget();
- }
-
- @override
- Widget build(BuildContext context) {
- // print('_GZXDropDownMenuState.build');
- _controller.duration = Duration(milliseconds: widget.animationMilliseconds);
- return _buildDropDownWidget();
- }
-
- dispose() {
- _controller.dispose();
- _isControllerDisposed = true;
- super.dispose();
- }
-
- _showDropDownItemWidget() {
- int menuIndex = widget.controller.menuIndex;
- if (menuIndex >= widget.menus.length || widget.menus[menuIndex] == null) {
- return;
- }
-
- _isShowDropDownItemWidget = !_isShowDropDownItemWidget;
- _isShowMask = !_isShowMask;
-
- _animation =
- new Tween(begin: 0.0, end: widget.menus[menuIndex].dropDownHeight)
- .animate(_controller)
- ..addListener(() {
- //这行如果不写,没有动画效果
- setState(() {});
- });
-
- if (_isControllerDisposed) return;
-
- if (_animation.status == AnimationStatus.completed) {
- _controller.reverse();
- } else {
- _controller.forward();
- }
- }
-
- _hideDropDownItemWidget() {
- _isShowDropDownItemWidget = !_isShowDropDownItemWidget;
- _isShowMask = !_isShowMask;
- _controller.reverse();
- widget.controller.isShow = false;
- }
-
- Widget _mask(callback) {
- if (_isShowMask) {
- return GestureDetector(
- onTap: () {
- print('到mask了');
- _hideDropDownItemWidget();
- if (callback != null) callback();
- },
- child: Container(
- width: MediaQuery.of(context).size.width,
- height: MediaQuery.of(context).size.height * 2,
- color: Color.fromRGBO(0, 0, 0, 0.1),
- ),
- );
- } else {
- return Container(
- height: 0,
- );
- }
- }
-
- Widget _buildDropDownWidget() {
- int menuIndex = widget.controller.menuIndex;
-
- return Positioned(
- width: MediaQuery.of(context).size.width,
- top: widget.controller.dropDownHearderHeight,
- left: 0,
- child: Column(
- children: <Widget>[
- Container(
- color: Colors.white,
- width: MediaQuery.of(context).size.width,
- height: _animation == null ? 0 : _animation.value,
- child: widget.menus[menuIndex].dropDownWidget,
- ),
- _mask(widget.menus[menuIndex].callback)
- ],
- ));
- }
- }
|