How do I automatically scale images in flutter to fit every resolution without overflow and scrolling?

Viewed 10154

I'm new and my English is pretty bad. Please answer easy to understand... I already tried using the AspectRatio Widget but it, combined with a Center widget, moved my buttons in the center. Apart from that it worked but the buttons really need to stick to the side. This is my code so far:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main.dart';
import 'contentData.dart';
import 'package:swipedetector/swipedetector.dart';

AppBrain contentData = AppBrain();

class SwipePage extends StatefulWidget {
  SwipePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _SwipePage createState() => _SwipePage();
}

class _SwipePage extends State<SwipePage> {
  @override
  Widget build(BuildContext context) {
    return SwipeDetector(
      swipeConfiguration: SwipeConfiguration(
          horizontalSwipeMaxHeightThreshold: 80.0,
          horizontalSwipeMinDisplacement: 30.0,
          horizontalSwipeMinVelocity: 150.0),
      onSwipeLeft: () {
        Navigator.of(context).push(
          toInformationPage(),
        );
      },
      child: Scaffold(
        backgroundColor: Colors.white,
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.only(top: 20, bottom: 20),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Container(
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(20),
                        topRight: Radius.circular(20),
                        bottomLeft: Radius.circular(20),
                        bottomRight: Radius.circular(20)),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.5),
                        spreadRadius: 5,
                        blurRadius: 7,
                        offset: Offset(0, 3), // changes position of shadow
                      ),
                    ],
                  ),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(20),
                    child: Image.asset(
                      AppBrain().getImageAdress(),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 20.0, bottom: 20),
                  child: Divider(
                    color: Colors.grey,
                    height: 20,
                    thickness: 2,
                    indent: 120,
                    endIndent: 120,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(bottom: 20),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: <Widget>[
                      Container(
                        decoration: BoxDecoration(
                          color: buttonColor,
                          borderRadius: BorderRadius.only(
                            topRight: Radius.circular(50),
                            bottomRight: Radius.circular(50),
                          ),
                        ),
                        child: MaterialButton(
                          height: 60,
                          onPressed: () {},
                          textColor: red,
                          child: Icon(
                            Icons.close,
                            size: 45,
                          ),
                        ),
                      ),
                      Container(
                        width: 120,
                      ),
                      Container(
                        decoration: BoxDecoration(
                          color: buttonColor,
                          borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(50),
                            bottomLeft: Radius.circular(50),
                          ),
                        ),
                        child: MaterialButton(
                          height: 60,
                          onPressed: () {
                            Navigator.of(context).push(
                              toInformationPage(),
                            );
                          },
                          textColor: green,
                          child: Icon(
                            Icons.check,
                            size: 45,
                          ),
                        ),
                      ),
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

This is what it looks like now: https://imgur.com/a/2kgpJ6A This is what it should look like across all aspect-ratios and resolutions (the image should just scale down..): https://imgur.com/FBNlpDa

3 Answers

Looking at your code you have at least two different problems.

  1. Setting the correct image fit - You can use BoxFit.contain in Image.asset(fit: boxFit.contain, .... ) to make sure it is resized to be contained inside it's parent.
  2. You have a Column and want the first child to take all the available width. Hence you should nest it inside Expanded widget.

ie. structurally something like:

Column(
  children: [
    Expanded(
      // your image goes here which will take as much height as possible.
      child: Image.asset('asset', fit: BoxFit.contain),
    ),
    Container(
      // your button bar which takes up the rest of the height
      child: MaterialButton( ... ),
    ),
  ],
);

I left out quite a bit, but i hope you get the gist.

I think I fixed it myself with the help of Herbert, thanks :). I wrapped the Container containing my image in an Expanded widget and set a flex value of 3. This is my new code:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main.dart';
import 'contentData.dart';
import 'package:swipedetector/swipedetector.dart';

AppBrain contentData = AppBrain();

class SwipePage extends StatefulWidget {
  SwipePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _SwipePage createState() => _SwipePage();
}

class _SwipePage extends State<SwipePage> {
  @override
  Widget build(BuildContext context) {
    return SwipeDetector(
      swipeConfiguration: SwipeConfiguration(
          horizontalSwipeMaxHeightThreshold: 80.0,
          horizontalSwipeMinDisplacement: 30.0,
          horizontalSwipeMinVelocity: 150.0),
      onSwipeLeft: () {
        Navigator.of(context).push(
          toInformationPage(),
        );
      },
      child: Scaffold(
        backgroundColor: Colors.white,
        body: SafeArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Expanded(
                flex: 4,
                child: Container(
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(20),
                        topRight: Radius.circular(20),
                        bottomLeft: Radius.circular(20),
                        bottomRight: Radius.circular(20)),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.5),
                        spreadRadius: 5,
                        blurRadius: 7,
                        offset: Offset(0, 3), // changes position of shadow
                      ),
                    ],
                  ),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(20),
                    child: Image.asset(
                      AppBrain().getImageAdress(),
                      fit: BoxFit.contain,
                    ),
                  ),
                  margin: EdgeInsets.fromLTRB(25, 25, 25, 0),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(
                  top: 20.0,
                ),
                child: Divider(
                  color: Colors.grey,
                  height: 20,
                  thickness: 2,
                  indent: 120,
                  endIndent: 120,
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(bottom: 25),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    Container(
                      decoration: BoxDecoration(
                        color: buttonColor,
                        borderRadius: BorderRadius.only(
                          topRight: Radius.circular(50),
                          bottomRight: Radius.circular(50),
                        ),
                      ),
                      child: MaterialButton(
                        height: 60,
                        onPressed: () {},
                        textColor: red,
                        child: Icon(
                          Icons.close,
                          size: 45,
                        ),
                      ),
                    ),
                    Container(
                      width: 120,
                    ),
                    Container(
                      decoration: BoxDecoration(
                        color: buttonColor,
                        borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(50),
                          bottomLeft: Radius.circular(50),
                        ),
                      ),
                      child: MaterialButton(
                        height: 60,
                        onPressed: () {
                          Navigator.of(context).push(
                            toInformationPage(),
                          );
                        },
                        textColor: green,
                        child: Icon(
                          Icons.check,
                          size: 45,
                        ),
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

You can try using FittedBox widget too.

Related