double.INFINITY là một khái niệm quan trọng trong Flutter, được sử dụng để xác định kích thước tối đa không giới hạn cho các widget. Hiểu và áp dụng đúng double.INFINITY sẽ giúp bạn tạo ra layout linh hoạt, responsive và tối ưu hiệu suất cho ứng dụng của mình. Bài viết này sẽ hướng dẫn chi tiết các trường hợp sử dụng phổ biến cùng với các best practices khi làm việc với double.INFINITY.

HƯỚNG DẪN SỬ DỤNG double.INFINITY TRONG FLUTTER

1. Khái niệm double.INFINITY

double.INFINITY là một giá trị đặc biệt trong Dart/Flutter đại diện cho vô cùng. Nó lớn hơn bất kỳ số hữu hạn nào.

void main() {
  print(double.INFINITY > 999999999); // true
  print(double.INFINITY == double.INFINITY); // true
  print(double.INFINITY + 1 == double.INFINITY); // true
}

2. Sử dụng trong Widget Sizing

a. Container và SizedBox

Container(
  width: double.infinity,  // Chiều rộng tối đa có thể
  height: 100,
  color: Colors.blue,
  child: Text('Full width container'),
)

b. Trong ListView và Column

ListView(
  children: [
    Container(
      constraints: BoxConstraints(
        maxWidth: double.infinity,
        minHeight: 50,
      ),
      color: Colors.red,
    ),
  ],
)

3. Sử dụng trong Constraints

a. Flexible Constraints

ConstrainedBox(
  constraints: BoxConstraints(
    maxWidth: double.infinity,
    maxHeight: double.infinity,
  ),
  child: Container(
    color: Colors.green,
  ),
)

b. CustomScrollView và SliverFillRemaining

CustomScrollView(
  slivers: [
    SliverFillRemaining(
      hasScrollBody: false,
      child: Container(
        constraints: BoxConstraints.expand(
          width: double.infinity,
          height: double.infinity,
        ),
      ),
    ),
  ],
)

4. Trường hợp nên sử dụng

a. Responsive Design

class ResponsiveWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        return Container(
          width: constraints.maxWidth == double.infinity 
              ? MediaQuery.of(context).size.width 
              : constraints.maxWidth,
          child: Text('Responsive content'),
        );
      },
    );
  }
}

b. Wrap Content

Wrap(
  children: [
    Container(
      constraints: BoxConstraints(
        maxWidth: double.infinity,
      ),
      child: Text('This text can wrap to multiple lines if needed'),
    ),
  ],
)

5. Tối ưu hiệu suất

a. Tránh lạm dụng

// KHÔNG NÊN
Container(
  width: double.infinity,
  height: double.infinity,
  child: SingleChildScrollView(
    child: Column(
      children: List.generate(1000, (index) => Container()),
    ),
  ),
)

// NÊN
LayoutBuilder(
  builder: (context, constraints) {
    return Container(
      width: constraints.maxWidth,
      height: constraints.maxHeight,
      child: ListView.builder(
        itemCount: 1000,
        itemBuilder: (context, index) => Container(),
      ),
    );
  },
)

6. Các trường hợp đặc biệt

a. AnimatedContainer

AnimatedContainer(
  duration: Duration(milliseconds: 300),
  width: isExpanded ? double.infinity : 200,
  height: 100,
  color: Colors.blue,
)

b. MediaQuery

class ResponsiveScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;

    return Container(
      width: screenWidth == double.infinity 
          ? 600 
          : screenWidth * 0.9,
      child: Card(
        child: Text('Responsive card'),
      ),
    );
  }
}

7. Debug và xử lý lỗi

void debugConstraints(BoxConstraints constraints) {
  if (constraints.maxWidth == double.infinity &&
      constraints.maxHeight == double.infinity) {
    print('Warning: Unbounded constraints detected');
  }
}

class DebugContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        debugConstraints(constraints);
        return Container();
      },
    );
  }
}