agent_floating_button.dart 2.95 KB
import 'package:flutter/material.dart';
import 'package:one_key/pages/agent/agent_chat_page.dart';
import 'package:one_key/res/colors.dart';

/// 全屏可拖拽的 AI 经营助手悬浮按钮。
class AgentFloatingButton extends StatefulWidget {
  const AgentFloatingButton({Key? key, this.bottomInset = 116})
      : super(key: key);

  /// 底部预留高度,避免按钮被底部导航栏盖住。
  final double bottomInset;

  @override
  State<AgentFloatingButton> createState() => _AgentFloatingButtonState();
}

class _AgentFloatingButtonState extends State<AgentFloatingButton> {
  static const double _size = 62;

  late double _left;
  late double _top;
  bool _initialized = false;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (_initialized) return;
    final Size screen = MediaQuery.of(context).size;
    _left = screen.width - _size - 16;
    _top = screen.height * 0.62;
    _initialized = true;
  }

  void _onPanUpdate(DragUpdateDetails details) {
    final Size screen = MediaQuery.of(context).size;
    final double topInset = MediaQuery.of(context).padding.top;
    setState(() {
      _left = (_left + details.delta.dx)
          .clamp(0.0, screen.width - _size)
          .toDouble();
      _top = (_top + details.delta.dy)
          .clamp(topInset + 8, screen.height - _size - widget.bottomInset)
          .toDouble();
    });
  }

  void _openChat() {
    Navigator.of(context).push(
      MaterialPageRoute(builder: (_) => const AgentChatPage()),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: _left,
      top: _top,
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: _openChat,
        onPanUpdate: _onPanUpdate,
        child: Container(
          width: _size,
          height: _size,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            gradient: const LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [MyColours.color_199095, MyColours.color_2bb5b7],
            ),
            boxShadow: [
              BoxShadow(
                color: MyColours.color_199095.withValues(alpha: 0.34),
                blurRadius: 16,
                offset: const Offset(0, 6),
              ),
            ],
          ),
          alignment: Alignment.center,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(
                Icons.auto_awesome,
                color: Colors.white,
                size: 22,
              ),
              const SizedBox(height: 1),
              Text(
                'AI',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 12,
                  fontWeight: FontWeight.w700,
                  letterSpacing: 0.5,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}