godzillabeast
godzillabeast

Reputation: 175

How to add button on top of image in flutter?

I'm trying to load image from network and display it fully along with button on top of the image. To achieve this I looked up on various solution and found that this can be done using Stack widget. My implementation is as below

    class DisplayImage extends StatefulWidget {
  final String text;
  DisplayImage({required this.text}) ;

  @override
  State<DisplayImage> createState() => _DisplayImageState();
}

class _DisplayImageState extends State<DisplayImage> {
  
  @override
  initState() {
    // TODO: implement initState
    _asyncMethod();
    super.initState();

  }
  _asyncMethod() async {
    Image.network(widget.text);
        setState(() {
      dataLoaded = true;
    });
  }
  bool dataLoaded = false;
  @override
  Widget build(BuildContext context) {
    if (dataLoaded){
      return Scaffold(
        backgroundColor: Colors.lightBlueAccent,
        appBar: AppBar(title: Text("Selfie BGchanger"),centerTitle: true,
      ),
      body: Center(child: Stack(
        children: [Image.network(
                 widget.text,
                 fit: BoxFit.fill,
                 loadingBuilder: (BuildContext context, Widget child,
                     ImageChunkEvent? loadingProgress) {
                   if (loadingProgress == null) return child;
                   return Center(
                     child: CircularProgressIndicator(
                       value: loadingProgress.expectedTotalBytes != null
                           ? loadingProgress.cumulativeBytesLoaded /
                               loadingProgress.expectedTotalBytes!
                           : null,
                     ),
                   );
                 },
               ),
      
        const SizedBox(height: 50,),
           Align(
             alignment: Alignment(0, .2),
             child: ElevatedButton(child: const Text('Save',style: TextStyle(fontWeight: FontWeight.normal)),style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder(
                         borderRadius: BorderRadius.circular(25),
                       ),
               primary: Colors.black,
               // padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
               textStyle: TextStyle(
               fontSize: 30,
               fontWeight: FontWeight.bold)),
             onPressed: () async{
             String url = widget.text;
             var imageId = await ImageDownloader.downloadImage(url);
             if(imageId == null)
             {return;}
               //  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Saved to gallery!')));
                Fluttertoast.showToast(msg: "Image saved to Gallery");
             },
             ),
           ),
      ],),
      ),
      );
    } else {
      return CircularProgressIndicator(backgroundColor: Colors.cyan,strokeWidth: 5,);
    }
    
  }
}

with this I get image is as below image1

save button is on top but what I'm trying to get is as below

Expected:

image2

full sized image with save button on bottom center

I tried using boxfit.cover with height and width as infinit as below

fit: BoxFit.cover,
    // height: double.infinity,
    // width: double.infinity,

I got display error

How can I fix this to get expected image ? any help or suggestion on this will be highly appreciated

update: based on answer suggestion I modified code as above and get output as below image3

Upvotes: 1

Views: 2448

Answers (1)

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63799

Wrap your ElevatedButton widget with Positioned/Align widget.

Align(
  alignment: Alignment(0, .2), //adjust based on your need
  child: ElevatedButton(

Also you find more about Stack , Align widget.

body: Stack(
  children: <Widget>[
    Positioned.fill(
        child: Image.network(
      "",
      fit: BoxFit.cover,
    )),
    Align(
      alignment: Alignment(0, .2), // change .2 based on your need
      child: ElevatedButton(
        onPressed: () async {
          await showDatePicker(
            context: context,
            initialEntryMode: DatePickerEntryMode.inputOnly,
            initialDate: DateTime.now(),
            firstDate: DateTime.now().subtract(Duration(days: 33)),
            lastDate: DateTime.now().add(Duration(days: 33)),
          );
        },
        child: Text("Dialog"),
      ),
    ),
  ],
),

Upvotes: 2

Related Questions