Thư viện Flutter FFloat: Hướng dẫn triển khai lớp phủ linh hoạt

Giới thiệu tổng quan

FFloat là một thư viện widget Flutter mã nguồn mở, chuyên biệt cho việc xây dựng các lớp phủ (overlay) có độ kiểm soát cao và khả năng tùy biến mạnh mẽ. Không chỉ hỗ trợ định vị chính xác theo nhiều chiến lược — như căn lề tương đối, bám vào cạnh, hoặc gắn theo tọa độ tuyệt đối — thư viện còn tích hợp sẵn các thuộc tính thị giác nâng cao: bo góc đa dạng, viền tùy chỉnh, hiệu ứng đổ bóng mượt mà, và nền gradient động.

Cài đặt và khởi tạo nhanh

Thêm phụ thuộc vào pubspec.yaml:

dependencies:
  ffloat: ^1.2.3

Sau đó chạy lệnh:

flutter pub get

Ví dụ cơ bản

Dưới đây là cách triển khai một lớp phủ đơn giản, xuất hiện khi người dùng tương tác với nút điều khiển:

import 'package:flutter/material.dart';
import 'package:ffloat/ffloat.dart';

void main() => runApp(const OverlayDemoApp());

class OverlayDemoApp extends StatelessWidget {
  const OverlayDemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('FFloat – Lớp phủ thông minh')),
        body: const Center(
          child: PositionedOverlay(),
        ),
      ),
    );
  }
}

class PositionedOverlay extends StatelessWidget {
  const PositionedOverlay({super.key});

  @override
  Widget build(BuildContext context) {
    return FFloat(
      anchor: ElevatedButton(
        onPressed: () {},
        style: ElevatedButton.styleFrom(backgroundColor: Colors.deepPurple),
        child: const Text('Mở lớp phủ'),
      ),
      builder: (dismiss) => Container(
        width: 240,
        padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
        decoration: BoxDecoration(
          color: Colors.indigo,
          borderRadius: BorderRadius.circular(10),
          boxShadow: [
            BoxShadow(color: Colors.black26, blurRadius: 8, offset: const Offset(0, 2)),
          ],
        ),
        child: const Center(
          child: Text(
            'Lớp phủ được bật',
            style: TextStyle(color: Colors.white, fontSize: 15),
          ),
        ),
      ),
      alignment: Alignment.topRight,
      margin: const EdgeInsets.only(top: 8, right: 8),
      corner: const CornerRadius.all(10),
      autoDismissDuration: const Duration(milliseconds: 2500),
    );
  }
}

Các tùy chọn cấu hình then chốt

  • builder: Hàm trả về nội dung lớp phủ; nhận tham số callback dismiss để đóng thủ công.
  • anchor: Widget làm điểm neo — vị trí lớp phủ sẽ được tính toán dựa trên nó.
  • alignment: Xác định hướng căn chỉnh tương đối giữa lớp phủ và điểm neo (ví dụ: Alignment.bottomLeft).
  • margin: Khoảng cách bù trừ từ biên của điểm neo đến lớp phủ.
  • corner: Kiểm soát bán kính bo góc chi tiết cho từng góc riêng biệt.
  • autoDismissDuration: Thời gian tự động ẩn sau khi hiển thị — hữu ích cho thông báo tạm thời.

Tình huống ứng dụng thực tế

Menu ngữ cảnh nổi: Kết hợp với InkWell hoặc GestureDetector để kích hoạt menu dọc khi nhấn giữ:

FFloat(
  anchor: const InkWell(child: Icon(Icons.more_vert)),
  builder: (_) => Material(
    elevation: 4,
    borderRadius: BorderRadius.circular(6),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: const [
        ListTile(title: Text('Chỉnh sửa'), leading: Icon(Icons.edit)),
        ListTile(title: Text('Xóa'), leading: Icon(Icons.delete), textColor: Colors.red),
      ],
    ),
  ),
  alignment: Alignment.topRight,
  margin: const EdgeInsets.only(top: 4, right: 4),
)

Thông báo trạng thái ngắn hạn: Hiển thị phản hồi tức thì sau hành động người dùng:

FFloat(
  anchor: ElevatedButton.icon(
    icon: const Icon(Icons.save),
    label: const Text('Lưu'),
    onPressed: () {
      // Gọi API hoặc xử lý logic...
      // Sau đó hiển thị thông báo
    },
  ),
  builder: (_) => const Padding(
    padding: EdgeInsets.all(12.0),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(Icons.check_circle, color: Colors.green),
        SizedBox(width: 8),
        Text('Đã lưu thành công', style: TextStyle(color: Colors.green)),
      ],
    ),
  ),
  alignment: Alignment.center,
  autoDismissDuration: const Duration(seconds: 1.8),
)

Thẻ: Flutter ffloat overlay UI-Component widget-library

Đăng vào ngày 2 tháng 9 lúc 07:10