Yuri Lopes
Yuri Lopes

Reputation: 1

Resize container height according to font size of device

I have a listView and all elements should have the same height with a fixed width. Is there a way of resize the height according with the font size that the user choose at your phone?

This is how it's looks like with a phone small font size

Small font size

And if I increase the font size of phone to a bigger one, the text is cutted because of the fixed height of the container.

bigger font size

How can I do an auto resize to the height of the container for the text not be cuted? I can't let the text occups as much space as it's need because all elements in list need to have same height.

It's the code so far.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late double screenSize;

  List<dynamic> products = [
    {
      'title': 'Item 1',
      'title_complement': ' Lorem ipsum dolor sit amet',
      'subtitle':
          'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in metus turpis.',
      'price': '100',
    },
    {
      'title': 'Item 2',
      'title_complement': ' Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum',
      'subtitle': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
      'price': '1000',
    },
    {
      'title': 'Item 3',
      'title_complement':
          ' Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
      'subtitle': 'Lorem ipsum dolor sit amet.',
      'price': '10',
    }
  ];

  Widget _productImage() {
    return Padding(
      padding: EdgeInsets.only(top: 24),
      child: Container(
        height: 205,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              height: 44,
              decoration: BoxDecoration(borderRadius: BorderRadius.circular(2)),
              margin: EdgeInsets.all(8),
              padding: EdgeInsets.symmetric(vertical: 4, horizontal: 5),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [],
              ),
            ),
          ],
        ),
        decoration: BoxDecoration(
          shape: BoxShape.rectangle,
          borderRadius: BorderRadius.all(Radius.circular(4)),
        ),
      ),
    );
  }

  Widget _price(BuildContext context, Map<String, dynamic> product) {
    return Container(
      height: 17,
      alignment: Alignment.centerRight,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          Text(
            product['price'],
            style: TextStyle(
              color: Colors.black,
              fontSize: 14,
              fontFamily: "Proxima Nova, Bold",
            ),
          ),
        ],
      ),
    );
  }

  Widget _buyButtom(BuildContext context, Map<String, dynamic> product) {
    return Padding(
      padding: EdgeInsets.only(bottom: 12),
      child: InkWell(
        onTap: () {},
        child: Container(
          height: 32,
          decoration: BoxDecoration(
            color: Colors.black,
            borderRadius: BorderRadius.all(Radius.circular(4)),
          ),
          child: Center(
            child: Text(
              "Button",
              style: TextStyle(
                fontSize: 14,
                fontFamily: "Proxima Nova, Regular",
                color: Colors.white,
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _priceRow(BuildContext context, Map<String, dynamic> product) {
    return Container(
      margin: EdgeInsets.fromLTRB(0, 16, 0, 16),
      child: Row(
        children: [
          Flexible(
            child: _price(context, product),
          )
        ],
      ),
    );
  }

  Widget _title(Map<String, dynamic> product) {
    return Container(
      height: 60,
      alignment: Alignment.topLeft,
      margin: EdgeInsets.only(top: 12),
      child: Text(
        product['title'] + product['title_complement'],
        maxLines: 3,
        overflow: TextOverflow.ellipsis,
        style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 14,
          fontFamily: "Proxima Nova, Condensed",
        ),
      ),
    );
  }

  Widget _subtitle(Map<String, dynamic> product) {
    return Container(
      height: 68,
      alignment: Alignment.topLeft,
      margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
      child: Card(
        elevation: 0,
        color: Colors.transparent,
        child: Text(
          product['subtitle'],
          maxLines: 3,
          overflow: TextOverflow.ellipsis,
          style: TextStyle(
            color: Color(0xff666666),
            fontSize: 14,
            fontFamily: "Proxima Nova",
          ),
        ),
      ),
    );
  }

  Widget body(Map<String, dynamic> product) {
    return GestureDetector(
      onTap: () {},
      child: Container(
        width: (screenSize - 47) / 2,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _productImage(),
            _title(product),
            _subtitle(product),
            _priceRow(context, product),
            _buyButtom(context, product)
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    screenSize = MediaQuery.of(context).size.width;
    double sliderHeight = 470;

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Padding(
        padding: EdgeInsets.symmetric(horizontal: 0, vertical: 20),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    "Items".toUpperCase(),
                    style: TextStyle(
                      fontSize: 20,
                      fontFamily: "Proxima Nova, Medium",
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
            ),
            Container(
              height: sliderHeight,
              child: ListView(
                scrollDirection: Axis.horizontal,
                children: List<Widget>.generate(
                  products.length,
                  (index) => Padding(
                    padding: EdgeInsets.only(left: 10),
                    child: body(
                      products[index],
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Upvotes: 0

Views: 26

Answers (1)

Mkhytar Mkhoian
Mkhytar Mkhoian

Reputation: 66

I would recommend you check ConstrainedBox (https://api.flutter.dev/flutter/widgets/ConstrainedBox-class.html)

With that widget, you can make a min-height constraint and at the same time be able to expand widget height based on content size.

Upvotes: 0

Related Questions