Bạn có một thẻ màu, bọc InkWell bên ngoài nhưng hiệu ứng chạm không hiện. Hoặc thẻ trông bo góc còn ripple lại không bị cắt theo góc ấy. Trước khi đổi màu splash, hãy kiểm tra Material nào đang nhận nét mực và lớp nền có che nó hay không.
Bài đối chiếu API Flutter hiện hành ngày 07/11/2026. Dart được rà thủ công theo InkWell, Ink và Material.clipBehavior; chưa chạy SDK, build app hay thử nhấn trên thiết bị. Các dấu hiệu quan sát bên dưới là checklist cho demo, không phải kết quả hình ảnh đã thu được.
Nhìn lớp vẽ thay vì chỉ nhìn thứ tự widget
InkWell cần một Material tổ tiên để vẽ phản hồi mực. Một lớp đồ họa đục nằm giữa Material và InkWell có thể che phản hồi ấy. Ink là một lựa chọn để vẽ decoration lên cùng Material, để hiệu ứng mực có thể nằm phía trên decoration.
Việc cắt ink cũng liên quan Material nhận nét vẽ. Chỉ đặt borderRadius ở một lớp con không tự chứng minh toàn bộ nội dung hay nét mực của tổ tiên đã được clip. Xác định lớp chịu trách nhiệm cắt trước khi thêm nhiều ClipRRect vào cây.
1. Demo một thẻ có nền và góc cố định
Dùng đoạn sau trong lib/main.dart của project Flutter đã tạo. Bài không yêu cầu ảnh hoặc package ngoài:
import 'package:flutter/material.dart';
void main() => runApp(const MaterialApp(home: InkCardDemo()));
class InkCardDemo extends StatefulWidget {
const InkCardDemo({super.key});
@override
State<InkCardDemo> createState() => _InkCardDemoState();
}
class _InkCardDemoState extends State<InkCardDemo> {
int _taps = 0;
@override
Widget build(BuildContext context) {
final radius = BorderRadius.circular(20);
return Scaffold(
appBar: AppBar(title: const Text('Thẻ có phản hồi chạm')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Material(
borderRadius: radius,
clipBehavior: Clip.antiAlias,
child: Ink(
color: const Color(0xffdbeafe),
child: InkWell(
borderRadius: radius,
onTap: () => setState(() => _taps += 1),
child: const Padding(
padding: EdgeInsets.all(24),
child: Text('Chạm vào thẻ này'),
),
),
),
),
const SizedBox(height: 16),
Text('Số lần nhấn: $_taps'),
],
),
),
);
}
}
Material có borderRadius và clipBehavior rõ ràng. Ink cung cấp màu nền, InkWell xử lý nhấn, còn Padding tạo vùng nội dung của thẻ. Cùng một radius được truyền cho hai lớp liên quan để người đọc dễ thấy ý định thiết kế.
Mẫu không đặt Container màu đục giữa Material và InkWell. Nếu màn hình thật có ảnh hoặc CustomPaint, cần xem lại cấu trúc lớp vẽ; cây đơn giản này chưa kiểm tra mọi dạng nội dung trang trí.
2. Kiểm tra phản hồi và hành động riêng nhau
Nhấn giữa thẻ để quan sát phản hồi chạm và kiểm tra bộ đếm tăng. Tiếp theo nhấn gần góc để kiểm tra vùng mực có nằm trong hình bo góc mong muốn. Không chỉ nhìn bộ đếm rồi kết luận phần clip cũng đúng.
Giữ thẻ có kích thước ổn định trong lúc kiểm tra. Tài liệu InkWell nêu giới hạn khi Material đổi kích thước lúc splash đang lan; demo không có animation thay kích thước để tránh trộn hai câu hỏi ấy.
Thử thay đổi có kiểm soát
Trong bản demo riêng, thử đổi màu nền để xem phản hồi còn đủ tương phản hay không. Nếu thay Ink bằng một lớp trang trí khác, kiểm tra lại phản hồi ở cùng vị trí chạm. Đây là cách phân biệt vấn đề lớp che với vấn đề chọn màu splash.
Không dựa vào một ảnh chụp đứng yên để đánh giá toàn bộ chuyển động. Quan sát trực tiếp hoặc dùng widget test phù hợp với cấu hình theme của project. Bài chưa có phép đo frame, kiểm tra golden hay kết luận về chi phí Clip.antiAlias.
Lỗi thường gặp và giới hạn
Material.clipBehavior mặc định không cắt. Một thẻ có radius đẹp ở lớp trang trí vẫn cần xác định chính sách clip nếu nội dung và mực phải bị giới hạn theo hình ấy. Đọc cây widget từ Material đang vẽ ink xuống đến nội dung, thay vì chỉ sửa widget gần onTap nhất.
InkWell không thay cho việc chọn component phù hợp với hành động. Khi màn hình cần một nút chuẩn với semantics và trạng thái disabled theo hệ thiết kế, xem component button tương ứng và kiểm tra accessibility. Bộ đếm trong demo chỉ giúp xác nhận callback nhấn, chưa chứng minh khả năng sử dụng bằng bàn phím hoặc screen reader.
Giữ ba trách nhiệm rõ trong thẻ tùy biến: nơi vẽ nền, nơi vẽ phản hồi và nơi cắt hình. Sau khi hiểu chúng trên ví dụ nhỏ, mới ghép ảnh, theme và trạng thái khác của sản phẩm.

