简体   繁体   中英

Flutter Container Overlay Widget

I want to get an image like the one below with Flutter. How should I provide this? I can provide this with container border, but I want to put a wigdet instead of border. For example, I want to wrap a circle widget with a Circleprogress bar. progress should grow as widget grows

在此处输入图片说明

Stack(
  children: [
    Container(
      padding: EdgeInsets.all(20),
      decoration: BoxDecoration(
          color: context.themeCopyExtensions.backgroundColor,
          shape: BoxShape.circle,
          border: Border.all(width: 5),
          boxShadow: [
            BoxShadow(
                color: context.themeCopyExtensions.backgroundColor,
                blurRadius: 10)
          ]),
      child: ImagesHelper.imagesHelper.getAssetImage(imageName: "logo"),
    ),
  ],
);

I implemented using 'Stack' widget and 'CircularProgressIndicator'. (Need to adjust each widget size)

在此处输入图片说明

/// Flutter code sample for CircularProgressIndicator

// This example shows a [CircularProgressIndicator] with a changing value.

import 'package:flutter/material.dart';

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

/// This is the main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
/// AnimationControllers can be created with `vsync: this` because of TickerProviderStateMixin.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with TickerProviderStateMixin {
  AnimationController controller;

  @override
  void initState() {
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 5),
    )..addListener(() {
        setState(() {});
      });
    controller.repeat(reverse: true);
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Container(
              width: 300,
              child: Stack(
                alignment: Alignment.center,
                children: <Widget>[
                  CircularProgressIndicator(
                    value: controller.value,
                    strokeWidth: 5,
                    semanticsLabel: 'Linear progress indicator',
                  ),
                  Container(
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: Color(0xFF431CEE),
                    ),
                    child: Icon(
                      Icons.audiotrack,
                      color: Colors.white,
                      size: 35,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I think I would use the FloatingActionButton to do this. You can put it anywhere in the widget tree and achieve your intended goal with much less effort than creating custom painter. It will always sit on top of your whole stack of pages using its built in overlay functionality. If you also don't want it to be clickable, you can always set the onPressed to null . One possible example is:

FloatingActionButton(
  onPressed: () {},
  child: Container(
    padding: EdgeInsets.all(20),
    decoration: BoxDecoration(
      color: context.themeCopyExtensions.backgroundColor,
        shape: BoxShape.circle,
        border: Border.all(width: 5),
        boxShadow: [
          BoxShadow(
            color: context.themeCopyExtensions.backgroundColor,
            blurRadius: 10,
          )
        ],
        image: DecorationImage(
          image: ImagesHelper.imagesHelper.getAssetImage(imageName: "logo"),
          fit: BoxFit.cover,
        )),
  ),
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM