Adaptive layout in different sized devices

0

When using Flutter, the UI gets offset if testing on different sized devices. As you can see in the two images I posted, the first one is tested on iPhone 8 Plus, and the button is hidden under the banner ad. But in the iPhone 11 Pro max size, the button is positioned where I want it. How do I maintain adaptive layout for UI?

enter image description here

enter image description here

import 'dart:math' as math;
//import 'dart:io';

import 'package:flutter/material.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'package:climatecountdown/urls.dart';

const String testDevice = 'Mobile_id';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CountDownTimer(),
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        iconTheme: IconThemeData(
          color: Colors.white,
        ),
        accentColor: Colors.red,
      ),
    );
  }
}

class CountDownTimer extends StatefulWidget {
  @override
  _CountDownTimerState createState() => _CountDownTimerState();
}

class _CountDownTimerState extends State<CountDownTimer>
    with TickerProviderStateMixin {

  AnimationController controller;


  static const MobileAdTargetingInfo targetingInfo = MobileAdTargetingInfo(
    nonPersonalizedAds: true,
  );

  BannerAd _bannerAd;

  BannerAd createBannerAd(){
    return BannerAd(
        adUnitId: 'ca-app-pub-1136501702308862/4514755428',
        size: AdSize.banner,
        targetingInfo: targetingInfo,
        listener: (MobileAdEvent event){
          print("BannerAd $event");
        }
    );
  }

  var timeLeft = DateTime.now().difference(DateTime.utc(2031, 1, 1)).inDays;
  var timeRemaining = DateTime.utc(2031, 1, 1).difference(DateTime.now()).inDays;


  String get timerString {
    Duration duration = controller.duration * controller.value;
    return '${duration.inDays}';
  }

  @override
  void initState() {
    FirebaseAdMob.instance.initialize(
      appId: 'APPID',
    );
    _bannerAd = createBannerAd()..load()..show();
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: Duration(days: timeRemaining),
    );
  }

  @override
  void dispose(){
    _bannerAd.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    ThemeData themeData = Theme.of(context);
    return Scaffold(
      backgroundColor: Colors.white10,
      body: AnimatedBuilder(
          animation: controller,
          builder: (context, child) {
            controller.reverse(
                from: controller.value == 0.0
                    ? 1.0
                    : controller.value);
            return Stack(
              children: <Widget>[
                Align(
                  alignment: Alignment.bottomCenter,
                  child: Container(
                    decoration: const BoxDecoration(
                      gradient: LinearGradient(
                          colors: <Color>[
                            Color(0xFF47B82C),
                            Color(0xFF00C231),
                            Color(0xFF47B82C),
                          ]
                      ),
                    ),
                    height:
                    controller.value * MediaQuery.of(context).size.height,
                  ),
                ),
                Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Expanded(
                        child: Align(
                          alignment: FractionalOffset.center,
                          child: AspectRatio(
                            aspectRatio: 1.0,
                            child: Stack(
                              children: <Widget>[
                                Positioned.fill(
                                  child: CustomPaint(
                                      painter: CustomTimerPainter(
                                        animation: controller,
                                        backgroundColor: Colors.white,
                                        color: themeData.indicatorColor,
                                      )),
                                ),
                                Align(
                                  alignment: FractionalOffset.center,
                                  child: Column(
                                    mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                    crossAxisAlignment:
                                    CrossAxisAlignment.center,
                                    children: <Widget>[
                                      Text(
                                        "Test Text 1",
                                        style: TextStyle(
                                            fontSize: 20.0,
                                            color: Colors.white),
                                      ),
                                      Text(
                                        timerString,
                                        style: TextStyle(
                                            fontSize: 112.0,
                                            color: Colors.white),
                                      ),
                                      Text(
                                        "Test Text 2",
                                        style: TextStyle(fontSize: 20.0,
                                          color: Colors.white,
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
                new Positioned(
                left: 50,
                  right: 50,
                bottom: 120,
                child: new Container(
                  padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
                  alignment: Alignment.bottomCenter,
                  child: new RaisedButton(
                    color: Colors.white,
                    onPressed: (){
                      Navigator.of(context).push(MaterialPageRoute(
                          builder: (BuildContext context) => URLView(
                            websiteName: "Google",
                            websiteURL: "https://google.com",
                          )));
                    },
                    child: Container(
                      decoration: const BoxDecoration(
                        gradient: LinearGradient(
                          colors: <Color>[
                            Color(0xFFFFFFFF),
                            Color(0xFFFFFFFF),
                            Color(0xFFFFFFFF),
                          ],
                        ),
                      ),
                      padding: const EdgeInsets.all(10.0),
                      child: const Text("Test Buttom",
                          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold,)
                      ),
                    ),
                  ),
                ),
                ),
              ],
            );
          }),
    );
  }
}
class CustomTimerPainter extends CustomPainter {

  CustomTimerPainter({
    this.animation,
    this.backgroundColor,
    this.color,
  }) : super(repaint: animation);

  final Animation<double> animation;
  final Color backgroundColor, color;

  @override
  void paint(Canvas canvas, Size size) {

    Paint paint = Paint()
      ..color = backgroundColor
      ..strokeWidth = 10.0
      ..strokeCap = StrokeCap.butt
      ..style = PaintingStyle.stroke;

    canvas.drawCircle(size.center(Offset.zero), size.width / 2.0, paint);
    paint.color = color;
    double progress = (1.0 - animation.value) * 2 * math.pi;
    canvas.drawArc(Offset.zero & size, math.pi * 1.5, -progress, false, paint);
  }

  @override
  bool shouldRepaint(CustomTimerPainter old) {
    return animation.value != old.animation.value ||
        color != old.color ||
        backgroundColor != old.backgroundColor;
  }
}
flutter
dart
flutter-layout
asked on Stack Overflow Jan 24, 2020 by Jdosaj0606 • edited Jan 24, 2020 by Ballu

2 Answers

1

try using the Column widget with the Center widget istead of Stack and avoid using Positioned for this case

answered on Stack Overflow Jan 24, 2020 by Omar F AlQataberi
0

Use the following flutter package https://pub.dev/packages/flutter_screenutil

answered on Stack Overflow Jan 24, 2020 by Xihuny

User contributions licensed under CC BY-SA 3.0