Chuyển đến nội dung chính

Bài đăng

Hiển thị các bài đăng có nhãn Layout

Slivers that scroll without jank

Slivers give precise control over when layout work happens during scroll. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence CustomScrollView, SliverList.builder, and avoiding layout thrash. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model builder constructors keep off-screen children unbuilt. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case ...

Slivers, properly: the protocol behind every Flutter scroll effect

Most Flutter developers meet slivers the way you meet a pothole: something in a design calls for a header that shrinks as you scroll, the search turns up SliverAppBar , it is pasted in, it works, and the mental model stops there. Then the next design needs a header that sticks per section , or a grid that becomes a list halfway down, and the pasted answer has nothing to say. The thing worth understanding is that a sliver is not a special widget. It is a different layout protocol , running inside the same framework. Ordinary widgets ask “how big may I be?” and answer “this big.” Slivers ask a much richer question — “how much of the viewport is left, how far have I been scrolled past, how much of me is visible?” — and give a much richer answer. Once you can read those two objects, every scroll effect in the framework becomes a small variation on a theme. Box layout versus sliver layout Regular Flutter layout is the box protocol: a parent passes down BoxConstraints (min/max width and ...

Khi ghép widget không còn đủ: tự viết RenderObject

Bạn hẳn từng gặp tình huống này. Thiết kế là một feed masonry hai cột: các card cao thấp khác nhau, mỗi card mới rơi vào cột nào đang ngắn nhất, thỉnh thoảng chen một banner chiếm trọn chiều ngang. Bạn thử Wrap — mỗi hàng lấy chiều cao của child cao nhất, thế là hở khoảng trắng. Bạn thử hai Column trong một Row rồi tự chia danh sách — nhưng không thể chia đúng nếu chưa biết mỗi card render ra cao bao nhiêu, mà điều đó chỉ biết được sau khi layout. Bạn thử Stack với Positioned , và bây giờ bạn cần chiều cao của từng card dưới dạng con số, ngay trong build, trước khi có gì được đo. Cái bẫy nằm ở chỗ tất cả đều là câu trả lời kiểu ghép widget cho một bài toán đo đạc . Row, Column, Stack, Wrap bản thân chúng là các render object với thuật toán layout cố định. Lồng chúng vào nhau không tạo ra thuật toán mới; nó chỉ tạo ra một cây cao hơn chạy đúng ba thuật toán cũ. Khi hình dạng bạn cần thực sự là một thuật toán khác — một quyết định đặt vị trí phụ thuộc vào kích thước đã đo của các s...