How to achieve this dual-curved layout on Flutter? double.infinity for height and width. Never mind about the Text and color, any color will do. Thank you :)
You can use a Column with two Flexible widgets, both of them containing a Stack as a child, and two Container widgets in each. This way the containers will be on top of each other, and one of them can have a decoration with rounded corners:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(body: MyWidget()),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(children: [
Flexible(
flex: 1,
child: Stack(children: [
Container(
color: Colors.blue,
),
Container(
decoration: const BoxDecoration(
borderRadius:
BorderRadius.only(bottomRight: Radius.circular(100)),
color: Colors.yellow,
))
])),
Flexible(
flex: 3,
child: Stack(children: [
Container(
color: Colors.yellow,
),
Container(
decoration: const BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(topLeft: Radius.circular(100)),
))
]),
)
]);
}
}
The result will be like this:
Thank you for your answer #Peter Koltai you answered perfectly correct. Thank you
Related
I'm making an app for my nephew for my own learning too. One screen uses a package to generate random colours for me. There are 3 containers in a row each generating a random colour through a function getRandomColor() which generates 3 colours from a list. I later reference the index of the list to fill the container colours.
I have a text widget at the top of a column which contains a variable randomChosenColor which needs to display one of the colours from the list contained in getRandomColor(). I will use the math package to generate a random number between 1-3 which would fetch index 0-2 in getRandomColor(). I later plan on adding a gesture detecture to the containers to detect if the correct container is tapped if it equals the variable randomChosenColor.
Full code below. I'm new to flutter and this is my basic means of putting it together - please advise if there is a more efficient/cleaner method.
import 'package:flutter/material.dart';
import 'package:random_color/random_color.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
//
List<Color> getRandomColor() {
return [
RandomColor().randomColor(),
RandomColor().randomColor(),
RandomColor().randomColor()
];
}
String randomChosenColor = ;
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Choose the colour $randomChosenColor',
style: const TextStyle(fontSize: 40),
textAlign: TextAlign.center,
),
const SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
height: 100,
width: 100,
color: getRandomColor()[0],
),
Container(
height: 100,
width: 100,
color: getRandomColor()[1],
),
Container(
height: 100,
width: 100,
color: getRandomColor()[2],
),
],
),
],
),
),
);
}
}
You can use getColorNameFromColor(yourColor).getName method to get the name. This is provided by random_color package.
I am using List instead of method.
randomChosenColor =
getColorNameFromColor(yourColor).getName;
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final randomColor = RandomColor();
late List<Color> getRandomColor = [
randomColor.randomColor(),
randomColor.randomColor(),
randomColor.randomColor()
];
String? randomChosenColor;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Choose the colour $randomChosenColor',
style: const TextStyle(fontSize: 40),
textAlign: TextAlign.center,
),
const SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
for (int i = 0; i < getRandomColor.length; i++)
GestureDetector(
onTap: () {
randomChosenColor =
getColorNameFromColor(getRandomColor[i]).getName;
setState(() {});
},
child: Container(
height: 100,
width: 100,
color: getRandomColor[i],
),
),
],
),
],
),
),
);
}
}
How to change the current index tabbar.
I have three tabbar with images when I click index 0 the height will
change to big like focus.
I have tried several ways but it didn't work.
when I select it will work only one index
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
toolbarHeight: 100,
bottom: TabBar(
indicator: BoxDecoration(
border: Border.all(width: 1, color: Colors.deepOrange),
borderRadius: BorderRadius.circular(10),
color: Colors.transparent),
tabs: [
Card(
child: Image(
image: AssetImage("assets/box.png"),
),
),
Card(
child: Image(image: AssetImage("assets/box.png")),
),
Card(
child: Image(image: AssetImage("assets/box.png")),
),
]),
),
body: TabBarView(
children: [
AmazonBox(),
AmazonGift(),
AmazonSave(),
],
)),
));
}
}
If you want to give the active tab icon a bigger size than the other icons, you have to create your own TabController first. Then add a listener to that TabController to update your Widget with setState() every time the tab index changes. Compare the tab icon index with the current index of the TabController to decide whether to display a big or small tab icon.
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
late final _tabController = TabController(length: 3, vsync: this)
..animation?.addListener(() => setState(() {}));
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
toolbarHeight: 100,
bottom: TabBar(
controller: _tabController,
indicator: BoxDecoration(
border: Border.all(width: 1, color: Colors.deepOrange),
borderRadius: BorderRadius.circular(10),
color: Colors.transparent),
tabs: [
SizedBox(
width: _tabController.index == 0 ? 100 : 50,
height: _tabController.index == 0 ? 100 : 50,
child: const Image(
image: AssetImage("assets/box.png"),
),
),
SizedBox(
width: _tabController.index == 1 ? 100 : 50,
height: _tabController.index == 1 ? 100 : 50,
child: const Image(image: AssetImage("assets/box.png")),
),
SizedBox(
width: _tabController.index == 2 ? 100 : 50,
height: _tabController.index == 2 ? 100 : 50,
child: const Image(image: AssetImage("assets/box.png")),
),
]),
),
body: TabBarView(
children: const [
AmazonBox(),
AmazonGift(),
AmazonSave(),
],
)),
));
}
}
I want to create a line without any shadow and gradient.
I try to create a simple Container with color, as below:
https://dartpad.dev/?id=72468c06f2cab2d4025c0842828f3907
return Container(
height: 200,
width: 100,
color: Colors.white,
child: Center(
child: Container(
height: 3,
color: Colors.red,
),
),
);
But I got the result as this:
After zooming in, we see that it contains a gradient to the background color:
What should I do to create a completely pure line, without any shadows or gradients?
I've tried the clipBehavior property and all 4 values have the same result.
you can use container's clipBehavior property to achieve this as described in this official documentation.
https://api.flutter.dev/flutter/dart-ui/Clip.html
you can use following properties.
hardEdge, which is a little faster, but with lower fidelity.
antiAliasWithSaveLayer, which is much slower, but can avoid the
bleeding edges if there's no other way.
Paint.isAntiAlias, which is the anti-aliasing switch for general draw operations.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: const Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 200,
width: 100,
color: Colors.white,
child: Center(
child: Container(
clipBehavior: Clip.hardEdge, //<-- this property
height: 3,
decoration: BoxDecoration(
color: Colors.red,
),
),
),
);
}
}
Output:
working: https://ibb.co/PZR1XkF
I created a GridView with crossAxisCount: 3. The problem is that if the totalWidth of the GridView is not dividable by 3, the background will shine through the GridView resulting in like the background colored lines visible on the GridView. Is there a way to avoid it?
Note: Problem does not appear on mobile
Code for Reproduction:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
width: 301,
child: GridView.count(
crossAxisCount: 3,
children: [
for (int i = 0; i < 12; i++)
Container(
color: Colors.black,
),
],
),
),
),
);
}
}
This can be removed using border.
Container(
decoration: BoxDecoration(
color: Colors.black,
border: Border.all(
color: Colors.black,
),
),
),
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
var responsive = MediaQuery.of(context).size; // add this line
return Scaffold(
body: SizedBox(
width: responsive.width, // add this line
height: responsive.height, // add this line
child: GridView.count(
crossAxisCount: 3,
children: [
for (int i = 0; i < 12; i++)
Container( // change content to view borders og grid
decoration: BoxDecoration( // add this line
border: Border.all( // add this line
color: Colors.white, // add this line
width: 1, // add this line
), // add this line
color: Colors.black, // add this line
), // add this line
),
],
),
),
);
}
}
The result will be as this:
or you can just put value border width = 0.0
SizedBox(
width: 301,
child: GridView.count(
crossAxisCount: 3,
children: [
for (int i = 0; i < 12; i++)
Container(
decoration: BoxDecoration(
color: Colors.black,
border: Border.all(
width: 0.0,
),
),
),
],
),
),
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,
)),
),
)