flutter cannot acces a method of another class using static access - flutter

title basically explains the error method i'm recieving. sorry for the huge code, but i'm basically just trying to make a call to onboarding to flip the page when a user touches the "next" text. (onTap:() => _OnboardingState.jumpForward())"
how can i do this?
i've tried using streams (i'm pretty bad with it) and maybe a solution would be bloc related. idk. i'm sure it's a pretty easy fix
import 'package:flutter/material.dart';
import '../../styling/canvas.dart';
import '../../styling/theme.dart';
import 'dart:async';
class Onboarding extends StatefulWidget {
#override
_OnboardingState createState() => _OnboardingState();
}
class _OnboardingState extends State<Onboarding> {
PageController onboardingController;
void jumpForward() async {
onboardingController.nextPage(
curve: Curves.easeIn,
duration: Duration(milliseconds: 200)
);
}
#override
Widget build(BuildContext context) {
return PageView(
controller: onboardingController,
pageSnapping: true,
children: <Widget>[
OnboardingPage(viewModel:pages[0]),
OnboardingPage(viewModel:pages[1]),
OnboardingPage(viewModel:pages[2]),
]
);
}
// jumpTo() {
// hello.jump
// }
}
class PageViewModel{
PageViewModel({
this.title,
this.description,
this.id,
});
final String title;
final String description;
final int id;
}
final pages = [
PageViewModel(
title: "Trade smart",
description:
"Filter stocks by metrics like short interest and short interest change.",
id: 1,
),
PageViewModel(
title: "Connect",
description:
"Filter stocks by metrics like short interest and short interest change.",
id: 2,
),
PageViewModel(
title: "Get an edge",
description:
"View legal insider trades filed with the SEC, made by top executives.",
id: 3,
),
];
class OnboardingPage extends StatelessWidget {
OnboardingPage({this.viewModel});
final PageViewModel viewModel;
#override
Widget build(BuildContext context) {
double _height = MediaQuery.of(context).size.height;
double _width = MediaQuery.of(context).size.width;
final double _circleHeight = .022 * _height;
return Scaffold(
body: Container(
color: lightTheme.backgroundColor,
height: _height,
width: _width,
child: Padding(
padding: EdgeInsets.fromLTRB(0.0, .1 * _height, 0.0, .1 * _height),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(
.044 * _width, 0.0, .044 * _width, .022 * _height),
child: Container(
//illustration
decoration:
returnCanvasStyle(), //todo: change color to theme bloc
width: _width,
height: .433 * _height,
),
),
Padding(
padding:
EdgeInsets.fromLTRB(.044 * _width, 0.0, .044 * _width, 0.0),
child: Container(
decoration: returnCanvasStyle(),
width: _width,
height: .344 * _height, //todo: change height
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(0.022 * _width,
0.022 * _height, 0.022 * _width, 0.0),
child: Text(
viewModel.title,
style: lightTheme.primaryTextTheme.display1,
textAlign: TextAlign.center,
),
),
Padding(
padding: EdgeInsets.fromLTRB(0.044 * _width,
0.022 * _height, 0.044 * _width, 0.033 * _height),
child: Text(
viewModel.description,
style: lightTheme.primaryTextTheme.body1,
softWrap: true,
textAlign: TextAlign.center,
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(
0.0, 0.0, .066 * _width, 0.0),
child: Container(
width: _circleHeight,
height: _circleHeight,
//color: Colors.red,
decoration: BoxDecoration(
border: Border.all(
color: lightTheme.primaryColor,
width: .0055 * _height,
),
borderRadius: BorderRadius.all(
Radius.circular(_circleHeight)),
color: lightTheme.primaryColor),
),
),
Padding(
padding: EdgeInsets.fromLTRB(
0.0, 0.0, .066 * _width, 0.0),
child: Container(
width: _circleHeight,
height: _circleHeight,
//color: Colors.red,
decoration: BoxDecoration(
border: Border.all(
color: lightTheme.primaryColor,
width: .0055 * _height,
),
borderRadius: BorderRadius.all(
Radius.circular(_circleHeight)),
color: Colors.transparent),
),
),
Padding(
padding: EdgeInsets.fromLTRB(
0.0, 0.0, .0944 * _width, 0.0),
child: Container(
width: _circleHeight,
height: _circleHeight,
//color: Colors.red,
decoration: BoxDecoration(
border: Border.all(
color: lightTheme.primaryColor,
width: .0055 * _height,
),
borderRadius: BorderRadius.all(
Radius.circular(_circleHeight)),
color: Colors.transparent),
),
),
Padding(
padding: EdgeInsets.fromLTRB(
0.0, 0.0, .119 * _width, 0.0),
child: GestureDetector(
onTap:() => _OnboardingState.jumpForward(),
child: Text(
"NEXT",
style: lightTheme.primaryTextTheme.button,
)),)
],
)
],
),
),
)
],
),
),
),
);
}
}

If you want to do it that way just use a callback for your State method. You are trying to access a non-static method in a static way, plus, you're doing it wrong because even if the method was static, you wouldn't be accessing the active State and controller.
So, by using a callback, you want to pass it on the constructor of your class
class OnboardingPage extends StatelessWidget {
OnboardingPage({this.viewModel, this.onNextPressed});
final PageViewModel viewModel;
final VoidCallback onNextPressed;
(...)
Call it on your NEXT tap
GestureDetector(
onTap:() => onNextPressed(),
child: Text(
"NEXT",
style: lightTheme.primaryTextTheme.button,
)
)
And then passing the reference when adding the OnboardingPage to your widget tree in your build method
OnboardingPage(viewModel:pages[0],onNextPressed: jumpForward)

Related

flutter SizeTransition cause container border radius to not work properly

I'm using SizeTransition to animate the width of a container.
This container is supposed to have rounded corners.
The problem is that the rounded corners only work when the sizeTransition is completed. If it is not completed, they remain square (as is shown in the gif below).
My code:
class DemoPage extends StatefulWidget {
const DemoPage({Key? key}) : super(key: key);
#override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
#override
void initState() {
super.initState();
_controller =
AnimationController(duration: const Duration(seconds: 5), vsync: this);
}
#override
void dispose() {
super.dispose();
_controller.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
constraints: const BoxConstraints.expand(),
color: Colors.black,
child: Center(
child: Column(
children: [
const SizedBox(height: 100),
Stack(
alignment: Alignment.centerLeft,
children: [
Container(
width: 300,
height: 20,
decoration: BoxDecoration(
color: const Color(0XFFC41D3D).withOpacity(0.5),
borderRadius:
const BorderRadius.all(Radius.circular(15))),
),
SizeTransition(
axis: Axis.horizontal,
sizeFactor: Tween(begin: 0.0, end: 1.0)
.chain(CurveTween(curve: const Interval(0.0, 0.4)))
.animate(_controller),
/// the container whose border radius is not working as expected
child: Container(
width: 300,
height: 20,
decoration: BoxDecoration(
color: const Color(0XFFC41D3D),
borderRadius: BorderRadius.circular(15.0)),
),
),
],
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_controller.repeat();
},
child: const Icon(Icons.play_arrow),
),
);
}
}
What should I do to solve the problem?
You can Wrap your stack widget and change its clipBehavior,Try this:
Container(
color: Colors.black,
constraints: const BoxConstraints.expand(),
child: Center(
child: Column(
children: [
const SizedBox(height: 100),
Container( // add this.
clipBehavior: Clip.antiAlias,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(15.0)),
child: Stack(
alignment: Alignment.centerLeft,
children: [
Container(
width: 300,
height: 20,
decoration: BoxDecoration(
color: const Color(0XFFC41D3D).withOpacity(0.5),
borderRadius:
const BorderRadius.all(Radius.circular(15))),
),
SizeTransition(
axis: Axis.horizontal,
sizeFactor: Tween(begin: 0.0, end: 1.0)
.chain(CurveTween(curve: const Interval(0.0, 0.4)))
.animate(_controller),
/// the container whose border radius is not working as expected
child: Container(
width: 300,
height: 20,
decoration: BoxDecoration(
color: const Color(0XFFC41D3D),
borderRadius: BorderRadius.circular(15.0)),
),
),
],
),
),
],
),
),
)
You can just wrap SizeTransition with ClipRRect which provide more realistic shape.
ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: SizeTransition(

How to create responsive screen for every device in flutter?

I have a screen as attached. Stack position is not responsive for low resolution device. So how can I create this screen to fix in any device?
home_Screen.dart
// ignore_for_file: prefer_const_constructors_in_immutables
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:thitsarparami/ui/home/components/menu.dart';
import '../../helper/constants.dart';
import '../../helper/enum.dart';
import '../chanting/chanting_catalog_screen.dart';
import '../monk/monk_screen.dart';
import '../radio/radio_screen.dart';
import '../youtube/video_screen.dart';
import 'components/monk_carousel.dart';
import 'components/myanmar_calender.dart';
class HomeScreen extends StatefulWidget {
static const routeName = '/home';
final BuildContext? menuScreenContext;
final Function? onScreenHideButtonPressed;
final bool hideStatus;
const HomeScreen(
{Key? key,
this.menuScreenContext,
this.onScreenHideButtonPressed,
this.hideStatus = false})
: super(key: key);
#override
HomeState createState() => HomeState();
}
class HomeState extends State<HomeScreen> {
final _itemsView = GlobalKey();
double _stackHeight = 0;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
RenderBox stackRB =
_itemsView.currentContext?.findRenderObject() as RenderBox;
setState(() {
_stackHeight = stackRB.size.height;
});
});
}
#override
Widget build(BuildContext context) {
final double screenHeight = MediaQuery.of(context).size.height;
final double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: SingleChildScrollView(
child: Stack(
children: [
Positioned(
top: 0,
left: 0,
right: 0,
height: screenHeight * 0.7,
child: Container(
padding: const EdgeInsets.only(
top: 30, left: 0, right: 0, bottom: 10),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context).primaryColorDark,
Theme.of(context).primaryColor,
Theme.of(context).primaryColorLight,
],
stops: const [
0.0,
0.5,
0.7,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Container(
width: screenWidth * 0.70,
//height: screenHeight * 0.20,
//color: Colors.black,
padding: const EdgeInsets.only(
top: 10, left: 10, right: 0, bottom: 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
kHomeTitle1,
style: Theme.of(context).textTheme.headline1,
),
Text(
kHomeTitle2,
style: Theme.of(context).textTheme.headline2,
),
Text(
kHomeTitle3,
style: Theme.of(context).textTheme.headline3,
),
],
),
),
),
Container(
width: screenWidth * 0.30,
height: screenHeight * 0.15,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/buddha.png"),
fit: BoxFit.contain),
),
),
],
),
Container(
height: screenHeight * 0.15,
padding: const EdgeInsets.only(
top: 0, left: 20, right: 20, bottom: 10),
child: const MyanmarCalender(),
),
],
),
),
),
Positioned(
left: 0,
right: 0,
top: screenHeight * 0.30,
key: _itemsView,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).backgroundColor,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(70),
),
),
child: Column(
children: [
const SizedBox(
height: 10,
),
Row(
children: [
MenuButton(
screenWidth: screenWidth,
iconData: Icons.music_video,
screen: const MonkScreen(
title: kMenuMp3,
screenMode: MonkScreenMode.song,
albumType: AlbumType.dhamatalk,
),
title: kMenuMp3,
),
MenuButton(
screenWidth: screenWidth,
iconData: Icons.play_lesson_rounded,
screen: const MonkScreen(
title: kMenuLecture,
screenMode: MonkScreenMode.lecture,
albumType: AlbumType.lecture,
),
title: kMenuLecture,
),
],
),
Row(
children: [
MenuButtonWithImageIcon(
screenWidth: screenWidth,
assetImage:
const AssetImage('assets/images/book.jpeg'),
screen: const MonkScreen(
title: kMenuEbook,
screenMode: MonkScreenMode.book,
albumType: AlbumType.ebook,
),
title: kMenuEbook,
),
MenuButtonWithImageIcon(
screenWidth: screenWidth,
assetImage:
const AssetImage('assets/images/prayer.png'),
screen: const ChantingCatalogScreen(),
title: kMenuChantig,
),
],
),
Row(
children: [
MenuButton(
screenWidth: screenWidth,
iconData: Icons.video_camera_front_outlined,
screen: const VideoScreen(),
title: kLiveStreaming,
withNavBar: false,
),
MenuButton(
screenWidth: screenWidth,
iconData: Icons.radio,
screen: const RadioScreen(),
title: kOnlineRadio,
),
],
),
const SizedBox(
height: 10,
),
const AutoSizeText(
kLatestDhama,
style: TextStyle(
fontSize: 18,
),
),
const SizedBox(
height: 10,
),
const MonkCarousel(),
],
),
),
),
Container(
height: _stackHeight + (screenHeight * 0.45),
),
],
),
),
);
}
}
iPhone 13 pro max vs iPhone 8
You can use the mediaQuery class which is a built-in component in Flutter to get the user's specifications - height and width etc - and then define some terms to suit their design size
for example:
Container(
width: mediaQuery.of(context).size.width * 0.5,
height: 150,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/buddha.png"),
fit: BoxFit.contain),
In this example we told the container width to take 50% of the screen width on any devise, you can use it wherever you want. you can read more about it in the official docs: https://api.flutter.dev/flutter/widgets/MediaQuery-class.html
You can create static class for size
class AppSize{
static double width=MediaQuery.of(context).size.width;
static double height=MediaQuery.of(context).size.height;
}
if you want use like that
Container(
width: AppSize.width * 0.1 ,
height: AppSize.height * 0.6 ,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/buddha.png"),
fit: BoxFit.contain),

Flutter skeleton view shimmer view

I'm trying to achieve the skeleton view as shown in the attachment but couldn't get it exactly like shown, i have tried Shimmer package, the problem is gradient or mask width is more. Kindly help with sample for to achieve the same.
Used the shimmer: ^2.0.0
My ListView
return Padding(
padding: const EdgeInsets.only(top: 16),
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return ShimmerItem();
},
itemCount: 10,
),
);
ShimmerItem Widget:
class ShimmerItem extends StatelessWidget {
const ShimmerItem({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.only(left: 16, right: 16, bottom: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
color: Theme.of(context).cardTheme.color,
child: Container(
margin: EdgeInsets.only(left: 16, bottom: 8, top: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 32.0),
child: ShimmerWidget.rectangular(
height: 16,
width: MediaQuery.of(context).size.width * 0.9,
)),
Padding(
padding: const EdgeInsets.only(right: 32.0, top: 8),
child: ShimmerWidget.rectangular(
height: 16,
width: MediaQuery.of(context).size.width * 0.6,
),
),
Padding(
padding: const EdgeInsets.only(top: 16, bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
ShimmerWidget.rectangular(
height: 16,
width: MediaQuery.of(context).size.width * 0.4,
),
SizedBox(
width: 10,
),
ShimmerWidget.rectangular(
height: 16,
width: MediaQuery.of(context).size.width * 0.4,
),
],
),
),
],
),
),
);
}
}
ShimmerWidget Class:
class ShimmerWidget extends StatelessWidget {
final double width;
final double height;
final ShapeBorder shapeBorder;
const ShimmerWidget.rectangular(
{this.width = double.infinity, required this.height})
: this.shapeBorder = const RoundedRectangleBorder();
const ShimmerWidget.circular(
{this.width = double.infinity,
required this.height,
this.shapeBorder = const CircleBorder()});
#override
Widget build(BuildContext context) => Shimmer.fromColors(
baseColor:
ColorHelper.colorWithTransparency(AppColors.shimmer_bg_color,
100),
highlightColor:
ColorHelper.colorWithTransparency(AppColors.shimmer_color_dark,
20),
period: Duration(milliseconds: 1500),
child: Container(
width: width,
height: height,
decoration: ShapeDecoration(
color: AppColors.shimmer_bg_color,
shape: shapeBorder,
),
),
);
}
We can use LayoutBuilder for measurement, which is depending on parent size and perfect for this case.
To struct the same UI, I am just constructing the ShimmerItem widget, rest of widget will be same.
To get rounded border I am using ClipRRect with providing borderRadius.
Padding to control the sounded spacing and SizedBox to provide space on Column's children.
Used Row's mainAxisAlignment: MainAxisAlignment.spaceBetween,to separate last two shimmer widgets.
Resource about layout-basics.
class ShimmerItem extends StatelessWidget {
const ShimmerItem({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final _border = BorderRadius.circular(12);
final double _bHeight = 24;
return LayoutBuilder(
builder: (context, constraints) => Padding(
padding: const EdgeInsets.all(12.0), //outside the card
child: Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: Colors.grey,
),
padding: const EdgeInsets.all(8), // inner padding
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//* top large two
ClipRRect(
borderRadius: _border,
child: ShimmerWidget.rectangular(
height: _bHeight,
width: constraints.maxWidth,
),
),
const SizedBox(height: 8),
ClipRRect(
borderRadius: _border,
child: ShimmerWidget.rectangular(
height: _bHeight * .75,
width: constraints.maxWidth,
),
),
const SizedBox(height: 8),
//3rd row
ClipRRect(
borderRadius: _border,
child: ShimmerWidget.rectangular(
height: _bHeight * .75,
width: constraints.maxWidth * 0.6,
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClipRRect(
borderRadius: _border,
child: ShimmerWidget.rectangular(
height: _bHeight,
width: constraints.maxWidth * 0.4,
),
),
ClipRRect(
borderRadius: _border,
child: ShimmerWidget.rectangular(
height: _bHeight,
width: constraints.maxWidth * 0.4,
),
),
],
),
],
),
),
),
);
}
}
I am using demo color.
You need wrap all your child inside 1 bigger Shimmer wrapper to do that, not Shimmer on every small retangle.
I have project code for this in my laptop but im working afar, sorry.

Designing a Flutter button with image and text

If I just throw together an image and some text in a rounded-corner rectangle, the user will not know that they can "click here". But I don't have to bake my own solution. InkWell covers this scenario, complete with a nice shadow.
I am positioning
a custom clickable icon using the
InkWell
class, itself requiring to be inside an
Ink
instance.
import 'package:flutter/material.dart';
const boat_url = ('https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/'
'Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG/'
'182px-Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG');
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Image',
home: Scaffold(
backgroundColor: Colors.grey,
body: MyImage(),
)));
}
class MyImage extends StatelessWidget {
MyImage({Key key,});
#override
Widget build(BuildContext context) {
Size sz = MediaQuery.of(context).size * 0.4;
double border = 4;
return Stack(children: [
Positioned(
top: 100,
left: 100,
width: sz.width,
height: sz.height,
child: Material(
child: Ink(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
new BoxShadow(
color: Colors.red,
blurRadius: 10.0,
offset: new Offset(30.0, 20.0),
),
],
border: Border.all(
color: Colors.blue,
width: border,
),
borderRadius: BorderRadius.circular(40),
),
child: InkWell(
onTap: (){/*..*/},
child: Column(
children: [
Container(
height: 4 * (sz.height - 2 * border) / 5,
alignment: Alignment.center,
child: Image.network(boat_url),
),
Container(
height: (sz.height - 2 * border) / 5,
child: FittedBox(
clipBehavior: Clip.antiAlias,
alignment: Alignment.centerLeft,
fit: BoxFit.fitHeight,
child: Text('A long descriptive sentence')),
)
],
)),
),
)),
]);
}
}
1- I'm not actually using Colors.white, and the Scaffold itself has
backgroundColor: Colors.grey. Where is the white background coming from?
2- When we talk of a "shadow", I'm expecting the shadow to be behind
the ink/inkwell object. Why does the shadow appear in front?
Related: 1
That white color is from the Material widget, to remove that you can use type param.
Material(
type: MaterialType.transparency,
child: Container(),
);
Here is code to achieve the custom button
Video link
Scaffold(
backgroundColor: Colors.blueGrey,
body: SafeArea(
child: Container(
decoration: BoxDecoration(
color: Colors.green.shade200,
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(5),
boxShadow: [
BoxShadow(
blurRadius: 5,
spreadRadius: 2,
color: Colors.black26,
)
]),
margin: const EdgeInsets.all(20),
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () {},
splashColor: Colors.black26,
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Image.asset(
'assets/images/marked_tyre_base.png',
fit: BoxFit.cover,
width: 80,
height: 80,
),
const SizedBox(
height: 10,
),
Text(
'Tyre 1',
style: TextStyle(color: Colors.white),
)
]),
),
),
),
),
),
),
);
Screenshot:
Create a class, ImageTextButton:
class ImageTextButton extends StatelessWidget {
final VoidCallback onPressed;
final ImageProvider image;
final double imageHeight;
final double radius;
final Widget text;
ImageTextButton({
#required this.onPressed,
#required this.image,
this.imageHeight = 200,
this.radius = 28,
#required this.text,
});
#override
Widget build(BuildContext context) {
return Card(
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(radius)),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: onPressed,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Ink.image(
image: image,
height: imageHeight,
fit: BoxFit.cover,
),
SizedBox(height: 6),
text,
SizedBox(height: 6),
],
),
),
);
}
}
Usage:
ImageTextButton(
onPressed: () {},
image: AssetImage('chocolate_image'),
text: Text('Chocolate'),
)

How to clip one container over another in flutter?

I want to build a reusable card widget, it will have an image and text with some custom design layout. I tried everything I could, but wasn't able to achieve the desired result. Any help would be much appreciated.
This is what I want to do
I'm stuck here
This is my code
class ReusabelCard extends StatelessWidget {
ReusabelCard(
{this.cardChild, #required this.assetImagePath, #required this.cardText});
final Widget cardChild;
final String assetImagePath;
final String cardText;
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.35,
width: MediaQuery.of(context).size.width * 0.5,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(MediaQuery.of(context).size.width * 0.5 * 0.28),
),
child: Stack(
children: [
LayoutBuilder(
builder: (context, contraint) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
Icons.trip_origin,
size: contraint.biggest.width,
color: Colors.grey[300],
),
Container(
height: MediaQuery.of(context).size.height*0.05,
width: MediaQuery.of(context).size.width,
color: Colors.green,
),
],
);
},
),
],
)
);
}
}
Use ClipRRect to do it:
ClipRRect(
borderRadius: BorderRadius.circular(50.0), //clipping the whole widget
child: Container(
height: MediaQuery.of(context).size.height * 0.4, //I adjusted here for responsiveness problems on my device
width: MediaQuery.of(context).size.width * 0.5,
color: Colors.white,
child: LayoutBuilder(
builder: (context, constraint) {
return Stack(
children: [
Center(
child: Icon(
Icons.trip_origin,
size: constraint.biggest.width,
color: Colors.grey[300],
),
),
Positioned(
right: 0,
left: 0,
top: 20.0,
child: Icon(
Icons.sports_volleyball_rounded, //just to represent the ball
size: constraint.biggest.width * 0.5,
),
),
Positioned(
bottom: 0.0,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.1,
width: constraint.biggest.width,
color: Colors.yellow[700],
child: Text(
'Sports',
style: Theme.of(context)
.textTheme
.headline3
.copyWith(color: Colors.white),
),
),
),
],
);
},
),
),
);