I am trying to set up a very simple ListView that from the top to the bottom of the screen, but right now I don't see any thing on the screen but a green background.
class _HomeScreenState extends State<HomeScreen> {
List wishlists = [Wishlist("Test1"), Wishlist("Yeet")];
#override
Widget build(BuildContext context) {
return Container(
color: Colors.lightGreen,
child: SizedBox(
height: 400,
child: new ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return new WishlistListWidget(
wishlist: wishlists[index],
);
},
itemCount: wishlists.length,
),
),
);
}
}
Wishlist is a simple Class and this is my WishlistListWidget:
class WishlistListWidget extends StatelessWidget {
final Wishlist wishlist;
const WishlistListWidget({Key key, this.wishlist}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Container(
height: 150.0,
color: Colors.transparent,
child: new Container(
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(40.0),
bottomLeft: const Radius.circular(40.0),
)),
),
),
],
),
);
}
}
What am I missing here?
You're missing the Text widget in WishlistListWidget class.
class WishlistListWidget extends StatelessWidget {
final Wishlist wishlist; // this value is not being used here
const WishlistListWidget({Key key, this.wishlist}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Container(
height: 150.0,
color: Colors.transparent,
child: new Container(
child: Text(wishlist.someProperty), // this one, it should be wishlist.someProperty
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(40.0),
bottomLeft: const Radius.circular(40.0),
),
),
),
),
],
),
);
}
}
Related
hi this is the first time i use a toggle button i try to make the toggle button to call a class container, there are 2 button
when "folmulir" button is true it called class container 1
when "List data" button is true it called class container 2.
should i make the container in the void so i return it?
import 'package:flutter/material.dart';
final List<bool> _selecteddatamaster = <bool>[
true,
false,
];
class TestbayToggle extends StatefulWidget {
const TestbayToggle({Key? key}) : super(key: key);
#override
TestbayToogleState createState() => TestbayToogleState();
}
class TestbayToogleState extends State<TestbayToggle> {
List<bool> isSelected = [true, false];
List<Widget> datamaster = const <Widget>[
Text('Folmulir'),
Text('List Data'),
];
#override
Widget build(BuildContext context) {
return Container(
width: 1000,
height: 50,
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(8), topRight: Radius.circular(8))),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 50,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8), topRight: Radius.circular(8)),
),
child: ToggleButtons(
onPressed: (int index) {
setState(() {
for (int i = 0; i < _selecteddatamaster.length; i++) {
_selecteddatamaster[i] = i == index;
if (index == 0) {
}
}
});
},
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(8), topRight: Radius.circular(8)),
selectedColor: Colors.black,
fillColor: Colors.white,
renderBorder: false,
color: Colors.white,
constraints: const BoxConstraints(
minHeight: 40.0,
minWidth: 100.0,
),
isSelected: _selecteddatamaster,
children: datamaster ,
),
)
]),
);
}
}
class Container1 extends StatefulWidget {
const Container1({Key? key}) : super(key: key);
#override
State<Container1> createState() => _Container1State();
}
class _Container1State extends State<Container1> {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: Container(
width: 1000,
height: 500,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [Text("test1")],
),
),
),
);
}
}
class Container2 extends StatelessWidget {
const Container2({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: Container(
width: 1000,
height: 500,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [Text("test2")],
),
),
),
);
}
}
I think the Visibility widget will serve your case better. Here's an example to demonstrate:
bool isSelected = true; // true by default, becuase first ToggleButton is activated
Visibility(
child: Container(), // display container of choice
visible: isSelected // will display child if true
);
Screenshot of a mobile app ui design.
Play with this widget and follow flutter.dev/development/ui/layout
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(title: _title, home: SampleW());
}
}
class SampleW extends StatelessWidget {
const SampleW({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
body: LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
child: Column(
children: [
Container(
height: constraints.maxHeight * .4,
alignment: Alignment.center,
child: CircleAvatar(
radius: constraints.maxWidth * .2,
backgroundColor: Colors.amber,
),
),
Container(
height: constraints.maxHeight, // will get by column
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
)),
)
],
),
),
),
);
}
}
This will give you
You can use like this:
Scaffold (
backgroundColor: Colors.red,
body: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: MediaQuery.of(context).size.height * 0.6,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(12),topRight: Radius.circular(12)),
),
),
)
)
this is the code:
class DocClinVisi extends StatelessWidget {
const DocClinVisi({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){},
child: Container(
padding: const EdgeInsets.all(20.0),
height: 110,
width: 110,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Image.asset('imagens/frame-1.png'),
),
);
}
}
There are several ways to show text "outside" the button.
If you need to "float" text outside the container you can use Stack:
class DocClinVisi extends StatelessWidget {
const DocClinVisi({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Stack(
clipBehavior: Clip.none,
children: [
Container(
padding: const EdgeInsets.all(20.0),
height: 110,
width: 110,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
const Positioned(
bottom: -20,
left: 0,
right: 0,
child: Text('Hello World', textAlign: TextAlign.center),
),
],
),
);
}
}
Note that this method could overlap the text with other widgets in some cases.
If you need to make the text part of the widget so it will not overlap, you could replace Stack for a Column:
class DocClinVisi extends StatelessWidget {
const DocClinVisi({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Column(
children: [
Container(
padding: const EdgeInsets.all(20.0),
height: 110,
width: 110,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
const Text('Hello World', textAlign: TextAlign.center),
],
),
);
}
}
Just wrap your container with column, then set text below the container, you can see and copy paste code below:
class DocClinVisi extends StatelessWidget {
const DocClinVisi({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){},
child: Column( // add column
children: [
Container(
padding: const EdgeInsets.all(20.0),
height: 110,
width: 110,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Image.asset('imagens/frame-1.png'),
),
Text('My Button'), // then add the text
]
),
);
}
}
I am designing a simple screen. I want to acheive this
How can I remove the topLeft border. I try to using border side to show only one side border but it showing error not able to change the another then uniform. Did i remove the app bar then stack the widget. Kindly tell me which thing I am doing wrong.
My Code is
import 'package:flutter/material.dart';
class SendScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final GlobalKey<ScaffoldState> _scaffoldKey =
new GlobalKey<ScaffoldState>();
return Scaffold(
drawer: Drawer(),
key: _scaffoldKey,
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
leading: IconButton(
icon: Icon(Icons.access_alarm),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
}),
actions: [
Container(
width: 50,
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
image: const DecorationImage(
image: NetworkImage(
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
fit: BoxFit.cover,
),
border: Border.all(
color: Colors.black,
// width: 8,
),
borderRadius: BorderRadius.circular(12),
),
),
SizedBox(
width: 20,
)
],
shape: ContinuousRectangleBorder(
borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(80),
),
),
title: Text('Sliver AppBar'),
),
),
body: Column(
children: [
Container(
height: 80,
decoration: BoxDecoration(
border: Border.all(
color: Colors.red[500],
),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(80),
),
),
child: Row(
children: [],
),
)
],
),
);
}
}
This is a known "issue". The problem is that once you assign a border radius, you don't know where the border starts and where it ends. Therefore flutter can't assign a border color to only certain border.
The only trick which works for you situation of everything I tried is to stack 2 container, the one on the back acting to do the border.
Here is the implementation:
import 'package:flutter/material.dart';
main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SendScreen(),
),
);
}
}
class SendScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
return Scaffold(
drawer: Drawer(),
key: _scaffoldKey,
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
leading: IconButton(
icon: Icon(Icons.access_alarm),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
}),
actions: [
Container(
width: 50,
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
image: const DecorationImage(
image: NetworkImage(
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
fit: BoxFit.cover,
),
border: Border.all(
color: Colors.black,
// width: 8,
),
borderRadius: BorderRadius.circular(12),
),
),
SizedBox(
width: 20,
)
],
shape: ContinuousRectangleBorder(
borderRadius: BorderRadius.only(
// bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(80),
),
),
title: Text('Sliver AppBar'),
),
),
body: CustomRectangle(
borderSize: 20,
borderColor: Colors.grey[300],
height: 80.0,
borderRadius: 80.0,
child: Container(
color: Colors.red,
),
),
);
}
}
class CustomRectangle extends StatelessWidget {
final Widget child;
final double height;
final double borderSize;
final double borderRadius;
final Color borderColor;
const CustomRectangle({
Key key,
#required this.height,
#required this.borderSize,
#required this.borderRadius,
#required this.child,
#required this.borderColor,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(bottomRight: Radius.circular(borderRadius)),
child: Container(
height: height + borderSize,
decoration: BoxDecoration(
color: borderColor,
),
),
),
ClipRRect(
borderRadius: BorderRadius.only(bottomRight: Radius.circular(borderRadius)),
child: Container(
height: height,
child: child,
),
),
],
);
}
}
Look at CustomRectangle it is my custom widget which solve your problem. You can expand from there.
I am trying to create something like the attached image. I got this far ...
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
),
),
child: ButtonTheme(
child: ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () => print('hi'),
child: Text('Referals'),
color: Color(0xff2FBBF0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(15.0),
topLeft: Radius.circular(15.0)),
),
),
RaisedButton(
onPressed: () => print('hii'),
child: Text('Stats'),
color: Color(0xff2FBBF0),
),
RaisedButton(
onPressed: () => print('hiii'),
child: Text('Edit Profile'),
color: Color(0xff2FBBF0),
// color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(15.0),
topRight: Radius.circular(15.0)),
),
),
],
),
),
),
),
But I don't really feel like it will look like the image.
I would also like the button group to be at the top of the Container. Now they're in the absolute center. Just like they would be if wrapped in a Center widget.
Here's the complete code. I have just used Container and Row because I find it more suitable and easy to achieve without any headache. :P
If you want with RaisedButton, figure it out.
Source:
import 'package:flutter/material.dart';
class Demo extends StatefulWidget {
#override
_DemoState createState() => new _DemoState();
}
class _DemoState extends State<Demo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("DEMO")),
body: Padding( // used padding just for demo purpose to separate from the appbar and the main content
padding: EdgeInsets.all(10),
child: Container(
alignment: Alignment.topCenter,
child: Container(
height: 60,
padding: EdgeInsets.all(3.5),
width: MediaQuery.of(context).size.width * 0.9,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(15)),
),
child: Row(
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
topLeft: Radius.circular(12))),
child: Text("Referrals",
style: TextStyle(
color: Colors.blue,
fontSize: 17,
)),
))),
Expanded(
child: InkWell(
onTap: () {},
child: Container(
alignment: Alignment.center,
child: Text("Stats",
style: TextStyle(
color: Colors.white, fontSize: 17)),
))),
Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Container(color: Colors.white, width: 2)),
Expanded(
child: InkWell(
onTap: () {},
child: Container(
alignment: Alignment.center,
child: Text("Edit Profile",
style: TextStyle(
color: Colors.white, fontSize: 17)),
)))
],
)),
)));
}
}
Output Screenshot:
Check my ButtonGroup widget that I created
import 'package:flutter/material.dart';
class ButtonGroup extends StatelessWidget {
static const double _radius = 10.0;
static const double _outerPadding = 2.0;
final int current;
final List<String> titles;
final ValueChanged<int> onTab;
final Color color;
final Color secondaryColor;
const ButtonGroup({
Key key,
this.titles,
this.onTab,
int current,
Color color,
Color secondaryColor,
}) : assert(titles != null),
current = current ?? 0,
color = color ?? Colors.blue,
secondaryColor = secondaryColor ?? Colors.white,
super(key: key);
#override
Widget build(BuildContext context) {
return Material(
color: color,
borderRadius: BorderRadius.circular(_radius),
child: Padding(
padding: const EdgeInsets.all(_outerPadding),
child: ClipRRect(
borderRadius: BorderRadius.circular(_radius - _outerPadding),
child: IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.min,
children: _buttonList(),
),
),
),
),
);
}
List<Widget> _buttonList() {
final buttons = <Widget>[];
for (int i = 0; i < titles.length; i++) {
buttons.add(_button(titles[i], i));
buttons.add(
VerticalDivider(
width: 1.0,
color: (i == current || i + 1 == current) ? color : secondaryColor,
thickness: 1.5,
indent: 5.0,
endIndent: 5.0,
),
);
}
buttons.removeLast();
return buttons;
}
Widget _button(String title, int index) {
if (index == this.current)
return _activeButton(title);
else
return _inActiveButton(title, index);
}
Widget _activeButton(String title) => FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
disabledColor: secondaryColor,
disabledTextColor: color,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
child: Text(title),
onPressed: null,
);
Widget _inActiveButton(String title, int index) => FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: Colors.transparent,
textColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
child: Text(title),
onPressed: () {
if (onTab != null) onTab(index);
},
);
}
You can use it like this
ButtonGroup(
titles: ["Button1", "Button2", "Button3"],
current: index,
color: Colors.blue,
secondaryColor: Colors.white,
onTab: (selected) {
setState(() {
index = selected;
});
},
)
Example:
import 'package:flutter/material.dart';
import 'package:flutter_app_test2/btn_grp.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MainPage(),
);
}
}
class MainPage extends StatefulWidget {
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int current = 0;
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ButtonGroup(
titles: ["Button1", "Button2", "Button3", "Button3"],
current: current,
onTab: (selected) {
print(selected);
setState(() {
current = selected;
});
},
),
),
);
}
}
try adding following in all RaisedButton widgets:
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
and buttonPadding: EdgeInsets.all(1), in ButtonBar
Source: https://api.flutter.dev/flutter/material/MaterialTapTargetSize-class.html