aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter AnimatedOpacity: opacity bằng 0 chưa tự chặn thao tác chạm

Suong Nguyen by Suong Nguyen
10/11/2026
in Flutter
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Một nút đã fade đến mức không còn nhìn thấy nhưng vùng của nó vẫn có thể nhận chạm. Nếu chỉ thay opacity, bạn mới thay phần hiển thị. Quy tắc xác định widget có được chọn làm đích nhận sự kiện hay không là một phần khác của giao diện.

Bài đối chiếu Flutter API ngày 10/11/2026. Ví dụ Material được rà theo tài liệu và cấu trúc widget; chưa chạy Flutter SDK, build, widget test, animation trên thiết bị hoặc trình đọc màn hình. Khi đưa vào dự án, cần thực hiện các ca kiểm tra dưới đây trên phiên bản SDK đang dùng.

Một trạng thái, ba trách nhiệm

AnimatedOpacity tự chuyển độ trong suốt khi giá trị opacity đổi, nhưng opacity 0 không ngăn hit testing của các widget con. IgnorePointer giải quyết phần nhận sự kiện con trỏ khi ignoring bằng true.

Nếu giao diện thật sự muốn phần đã ẩn không xuất hiện trong cây semantics, có thể cấu hình riêng bằng ExcludeSemantics. Không mặc định việc bỏ chạm cũng đã loại toàn bộ mô tả cho công cụ hỗ trợ tiếp cận. Trong ví dụ, cả ba lựa chọn cùng dựa vào biến hidden để đọc được chính sách ở một nơi.

Một nút ẩn và một nút điều khiển ở bên ngoài

Thử code sau trong lib/main.dart của dự án Material:

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: FadeDemo()));

class FadeDemo extends StatefulWidget {
  const FadeDemo({super.key});
  @override
  State<FadeDemo> createState() => _FadeDemoState();
}

class _FadeDemoState extends State<FadeDemo> {
  bool hidden = false;
  int presses = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Fade và tương tác')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(
              onPressed: () => setState(() => hidden = !hidden),
              child: Text(hidden ? 'Hiện nút' : 'Ẩn nút'),
            ),
            const SizedBox(height: 24),
            ExcludeSemantics(
              excluding: hidden,
              child: IgnorePointer(
                ignoring: hidden,
                child: AnimatedOpacity(
                  opacity: hidden ? 0 : 1,
                  duration: const Duration(milliseconds: 200),
                  child: ElevatedButton(
                    onPressed: () => setState(() => presses += 1),
                    child: const Text('Nút đang fade'),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 24),
            Text('Số lần nhận nhấn: $presses'),
          ],
        ),
      ),
    );
  }
}

Nút điều khiển nằm ngoài vùng bị ẩn, nên người thử còn đường bật nó trở lại. Bộ đếm cũng ở bên ngoài để quan sát thao tác có được nhận hay không. Thời lượng 200 ms chỉ là cấu hình minh họa, không phải kết quả tối ưu animation đã đo.

Chặn ngay khi state đổi hay chờ fade kết thúc?

Khi hidden thành true, IgnorePointer bắt đầu bỏ qua con trỏ ngay theo state, trong khi opacity có thể còn đang chuyển dần. Khi hiện lại, ignoring trở về false ngay. Đây là chính sách của demo: không đợi mốc kết thúc animation để quyết định khả năng chạm.

Nếu sản phẩm yêu cầu chỉ cho thao tác sau khi fade-in xong, cần một trạng thái tương tác hoặc quy trình đồng bộ khác. Đừng mô tả snippet này như đã triển khai chính sách ấy. Việc vẽ và việc nhận sự kiện có thể cần những mốc chuyển khác nhau, nên hãy ghi yêu cầu trước khi thêm callback animation.

Giữ chỗ khác với bỏ widget khỏi layout

Demo giữ widget trong cây để làm fade. Vì vậy, khi nút không nhìn thấy, vùng bố cục của nó vẫn còn trong cấu trúc này. IgnorePointer không có nhiệm vụ thu gọn khoảng trống. Nếu mục tiêu là các phần bên dưới dịch lên, bạn cần thiết kế thêm cách chuyển bố cục, thay vì chỉ đổi độ trong suốt.

Tài liệu cũng nhắc chi phí vẽ của opacity animation. Bài không có profile để khẳng định ảnh hưởng trên thiết bị cụ thể. Đừng thêm nhiều lớp opacity hoặc mở rộng demo thành một hiệu ứng phức tạp rồi dùng ví dụ này làm bằng chứng hiệu năng đã đạt.

Kế hoạch kiểm tra

Khi nút đang hiện, bấm vài lần và xem bộ đếm tăng. Chuyển sang ẩn rồi thử chạm tại vị trí cũ, cả trong lúc fade-out lẫn sau khi hoàn tất; bộ đếm không nên tăng theo chính sách demo. Hiện lại và kiểm tra thao tác có thể nhận trở lại.

Tiếp theo, kiểm tra semantics bằng công cụ của nền tảng để xác nhận phần hidden được loại theo ExcludeSemantics. Thử thao tác bàn phím và focus nếu ứng dụng hỗ trợ chúng; IgnorePointer không phải lời cam kết xử lý mọi cơ chế focus. Các bước này cần được thực hiện thực tế, chưa được bài báo cáo là đã chạy.

Tách ba trách nhiệm giúp một hiệu ứng biến mất có hành vi rõ ràng. Đặt cùng state cho chúng khi yêu cầu đồng bộ, và chỉ tách mốc chuyển khi thiết kế tương tác thật sự cần điều đó.

Nguồn tham khảo

  • Flutter: AnimatedOpacity
  • Flutter: IgnorePointer
  • Flutter: ExcludeSemantics

Tags: AnimatedOpacityFlutterTương tác UI
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter DropdownButton: value cần khớp đúng một item, không phải một nhãn

by Suong Nguyen
09/11/2026
0

Dùng ID ổn định làm value của DropdownButton để hai mục có cùng nhãn vẫn được chọn đúng, kèm cách rà lựa chọn đã hết tồn tại.

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter TextField: readOnly khác enabled như thế nào với nút suffix?

by Suong Nguyen
08/11/2026
0

Chọn trạng thái TextField khi cần ngăn sửa nội dung, vẫn cho chọn chữ hoặc giữ nút suffix hoạt động, kèm màn hình kiểm tra hai trường.

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter InkWell: đặt nền và clip ở Material để thấy ripple đúng góc

by Suong Nguyen
07/11/2026
0

Dựng một thẻ tương tác với Material, Ink và InkWell, rồi kiểm tra vị trí vẽ ripple cùng vùng cắt bo góc.

Minh họa phát triển ứng dụng mobile đa nền tảng với Flutter

Flutter CheckboxListTile: value và selected không tự đồng bộ

by Suong Nguyen
06/11/2026
0

Cập nhật giá trị checkbox trong state, phân biệt selected của cả tile và khóa tương tác bằng onChanged null.

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native Text selectable: cho người dùng chọn và sao chép mã hiển thị
  • Phỏng vấn JavaScript: object mặc định của tham số được tạo khi nào?
  • Android runOnUiThread và Handler.post: chạy ngay hay đưa vào hàng đợi?

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply