Как создать полукруглое меню с динамическим радиусом c - PullRequest
0 голосов
/ 21 июня 2020

Помогите, я пытаюсь создать такое полукруглое меню, изображение того, что я хочу здесь

Но я не знаю, как разместить виджеты поверх большего белого line ... Я пробовал использовать следующий код. Пожалуйста, используйте виджет в качестве домашнего виджета в вашем main.dart и посмотрите результат. Я использовал пакет font_awesome_flutter в пабе пакетов для значков: -

изображение того, как оно сейчас здесь

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:vector_math/vector_math.dart' show radians, Vector3;
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class Homewidgettoslack extends StatefulWidget {
  Homewidgettoslack({
    Key key,
  }) : super(key: key);

  @override
  _HomewidgettoslackState createState() => _HomewidgettoslackState();
}

class _HomewidgettoslackState extends State<Homewidgettoslack> with TickerProviderStateMixin {
  Animation<double> rotation;
  Animation<double> translation;
  Animation<double> menuscale;
  AnimationController menuController;

  @override
  void initState() {
    super.initState();
    menuController =
        AnimationController(duration: Duration(milliseconds: 900), vsync: this);
    rotation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(
        parent: menuController,
        curve: Interval(
          0.0,
          0.7,
          curve: Curves.decelerate,
        ),
      ),
    );
    translation = Tween<double>(
      begin: 0.0,
      end: 100.0,
    ).animate(
      CurvedAnimation(parent: menuController, curve: Curves.elasticOut),
    );

    menuscale = Tween<double>(
      begin: 1.5,
      end: 0.0,
    ).animate(
      CurvedAnimation(parent: menuController, curve: Curves.fastOutSlowIn),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blueGrey,
      child: Scaffold(
        backgroundColor: Colors.transparent,
        body: Stack(
          children: <Widget>[
            Positioned(
              left: -27,
              right: -27,
              top: 57,
              bottom: 57,
              child: Container(
                height: MediaQuery.of(context).size.height,
                width: MediaQuery.of(context).size.width,
                child: CustomPaint(
                  painter: CurvedblacklinePainter(),
                ),
              ),
            ),
            Container(
              height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
              child: CustomPaint(
                painter: CurvedblacklinePainter(),
              ),
            ),
            Container(
              height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
              child: AnimatedBuilder(
                animation: menuController,
                builder: (context, widget) {
                  return Transform.rotate(
                    angle: radians(rotation.value),
                    child:
                        Stack(alignment: Alignment.center, children: <Widget>[
                      _buildButton(0,
                          color: Colors.red, icon: FontAwesomeIcons.thumbtack),
                      _buildButton(45,
                          color: Colors.green, icon: FontAwesomeIcons.sprayCan),
                      _buildButton(90,
                          color: Colors.orange, icon: FontAwesomeIcons.fire),
                      _buildButton(270,
                          color: Colors.pink, icon: FontAwesomeIcons.car),
                      _buildButton(315,
                          color: Colors.yellow, icon: FontAwesomeIcons.bolt),
                      Transform.scale(
                        scale: menuscale.value - 1,
                        child: FloatingActionButton(
                            child: Icon(FontAwesomeIcons.timesCircle),
                            onPressed: _close,
                            backgroundColor: Colors.red),
                      ),
                      Transform.scale(
                        scale: menuscale.value,
                        child: FloatingActionButton(
                            child: Icon(
                              FontAwesomeIcons.solidDotCircle,
                              color: Colors.red,
                            ),
                            onPressed: _open),
                      )
                    ]),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  _buildButton(double angle, {Color color, IconData icon}) {
    final double rad = radians(angle);
    return Transform(
        transform: Matrix4.identity()
          ..translate(
              (translation.value) * cos(rad), (translation.value) * sin(rad)),
        child: FloatingActionButton(
            child: Icon(icon),
            backgroundColor: color,
            onPressed: _close,
            elevation: 0));
  }

  _open() {
    print('OPEN CLICKED');
    menuController.forward();
  }

  _close() {
    print('CLOSE CLICKED');
    menuController.reverse();
  }
}

class CurvedblacklinePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = Colors.white
      ..strokeWidth = 1.8
      ..style = PaintingStyle.stroke;

    Path path = Path();
    path.moveTo(0, 0);

    var secondEndPoint = Offset(0, size.height);
    path.arcToPoint(secondEndPoint,
        radius: Radius.circular((size.width / 2)),
        clockwise: true,
        largeArc: false);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

1 Ответ

1 голос
/ 21 июня 2020

Я улучшил ваш код и исправил его, как показано ниже,

, пожалуйста, замените мой код своим кодом

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:vector_math/vector_math.dart' show radians, Vector3;

class Homewidgettoslack extends StatefulWidget {
  Homewidgettoslack({
    Key key,
  }) : super(key: key);

  @override
  _HomewidgettoslackState createState() => _HomewidgettoslackState();
}

class _HomewidgettoslackState extends State<Homewidgettoslack>
    with TickerProviderStateMixin {
  Animation<double> rotation;
  Animation<double> translationY;
  Animation<double> translationX;
  Animation<double> menuscale;
  AnimationController menuController;

  double _menuIconSize;

  @override
  void initState() {
    super.initState();
    menuController =
        AnimationController(duration: Duration(milliseconds: 900), vsync: this);
    rotation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(
        parent: menuController,
        curve: Interval(
          0.0,
          0.7,
          curve: Curves.decelerate,
        ),
      ),
    );

    menuscale = Tween<double>(
      begin: 1.5,
      end: 0.0,
    ).animate(
      CurvedAnimation(parent: menuController, curve: Curves.fastOutSlowIn),
    );
  }

  @override
  Widget build(BuildContext context) {
    ScreenUtil.init(width: 360, height: 640, allowFontScaling: false);
    _menuIconSize = ScreenUtil().setWidth(60);
    double _bigCurveHeight = ScreenUtil().setHeight(520);
    double _bigCurveWidth = ScreenUtil().setWidth(250);

    translationY = Tween<double>(
      begin: 0.0,
      end: ((_bigCurveHeight / 2) - (_menuIconSize / 2)),
    ).animate(
      CurvedAnimation(parent: menuController, curve: Curves.elasticOut),
    );

    translationX = Tween<double>(
      begin: 0.0,
      end: (_bigCurveWidth - (_menuIconSize / 2)),
    ).animate(
      CurvedAnimation(parent: menuController, curve: Curves.elasticOut),
    );

    return Container(
      color: Colors.blueGrey,
      child: Scaffold(
        backgroundColor: Colors.transparent,
        body: Align(
          alignment: Alignment.centerLeft,
          child: Stack(
            alignment: Alignment.centerLeft,
            children: <Widget>[
              Container(
                height: _bigCurveHeight,
                width: _bigCurveWidth,
                child: CustomPaint(
                  painter: CurvedblacklinePainter(strokeWidth: 2),
                ),
              ),
              Container(
                height: ScreenUtil().setHeight(350),
                width: ScreenUtil().setWidth(130),
                child: CustomPaint(
                  painter: CurvedblacklinePainter(
                      strokeWidth: ScreenUtil().setWidth(60)),
                ),
              ),
              Container(
                child: AnimatedBuilder(
                  animation: menuController,
                  builder: (context, widget) {
                    return Transform.rotate(
                      angle: radians(rotation.value),
                      child:
                          Stack(alignment: Alignment.center, children: <Widget>[
                        _buildButton(0,
                            color: Colors.red,
                            icon: FontAwesomeIcons.thumbtack),
                        _buildButton(45,
                            color: Colors.green,
                            icon: FontAwesomeIcons.sprayCan),
                        _buildButton(90,
                            color: Colors.orange, icon: FontAwesomeIcons.fire),
                        _buildButton(270,
                            color: Colors.pink, icon: FontAwesomeIcons.car),
                        _buildButton(315,
                            color: Colors.yellow, icon: FontAwesomeIcons.bolt),
                        Transform.scale(
                          scale: menuscale.value - 1,
                          child: FloatingActionButton(
                              child: Icon(FontAwesomeIcons.timesCircle),
                              onPressed: _close,
                              backgroundColor: Colors.red),
                        ),
                        Transform.scale(
                          scale: menuscale.value,
                          child: FloatingActionButton(
                              child: Icon(
                                FontAwesomeIcons.solidDotCircle,
                                color: Colors.red,
                              ),
                              onPressed: _open),
                        )
                      ]),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  _buildButton(double angle, {Color color, IconData icon}) {
    final double rad = radians(angle);
    return Transform(
        transform: Matrix4.identity()
          ..translate(
              (translationX.value) * cos(rad), (translationY.value) * sin(rad)),
        child: FloatingActionButton(
            child: Icon(icon),
            backgroundColor: color,
            onPressed: _close,
            elevation: 0));
  }

  _open() {
    print('OPEN CLICKED');
    menuController.forward();
  }

  _close() {
    print('CLOSE CLICKED');
    menuController.reverse();
  }
}

class CurvedblacklinePainter extends CustomPainter {
  final double strokeWidth;

  CurvedblacklinePainter({@required this.strokeWidth});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = Colors.white
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke;

    canvas.drawOval(
        Rect.fromCenter(
            center: Offset(-size.width / 2, size.height / 2),
            width: size.width * 3,
            height: size.height),
        paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

и добавьте зависимость в ваш pubspe c .yaml :

dev_dependencies:
  flutter_test:
    sdk: flutter
  font_awesome_flutter: ^8.8.1
  flutter_screenutil: ^2.1.0

скриншот результата:

image
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...