How do I render a widget based on a condition in flutter? - flutter

Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(MyApp.title),
centerTitle: true,
),
body: (()=>{
if(!list){
return Register();
}
else{
return Homepage();
}
})
);
My application fetches a list from local storage on init afterwards the next page to be rendered depends on whether the list is empty or not. Is there a way to determine which widget to render base on a condition?

Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(MyApp.title),
centerTitle: true,
),
body: list.isEmpty ? Register() : Homepage()
);

Related

I am getting an error while writing a ternary operator under a Column widget. Can this actually be done and how do i fix it?

I have an array that has an image URL and normal string as its content. I want to display an image or Text widget based on which value is being read. I have used this to make that work:
Widget build(BuildContext context) {
final usrMap = {"tom", 'tom.png', "taommy"};
return MaterialApp(
title: 'Flutter Tutorial',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Text Widget Tutorial'),
),
body: Column(
children: [
for( var prop in usrMap){
prop.contains(".com")? Text(prop) : Text("not .png")
},
]
),
),
);
}
I am getting this error
The element type 'Set' can't be assigned to the list type 'Widget'
How do I fix this?
use like this.
Widget build(BuildContext context) {
final usrMap = {
"tom",
'tom.png',
"taommy",
"sheikh.com",
};
return MaterialApp(
title: 'Flutter Tutorial',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Text Widget Tutorial'),
),
body: Column(children: [
...usrMap.map((e) {
if (e.contains(".com"))
return Text("prop");
else
return Text("not .png");
}).toList(),
]),
),
);
}

How to change appbar when listened to Bloc, I dont want to bloc builder on the scaffold, instead I want BlocBuidler on the AppBar?

Scaffold(
// extendBodyBehindAppBar: true,
// extendBody: true,
appBar: AppBar(
centerTitle: false,
brightness: Brightness.light,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
),
onPressed: () {
Navigator.pop(context);
}),
title: const Text(
'Go back',
),
elevation: 0,
backgroundColor: Colors.transparent,
),
.
.
.
bottomNavigationBar: BottomNavigationWidget()
)//Scaffold;
Simply, I want to change my app bar when the bottom navigation item is changed.. I am unable to wrap AppBar with the BlocBuilder<>, How can I achieve this?
Inside Scaffold widget you can use
appBar: PreferredSize(
child: CustomAppBar(),
preferredSize: Size.fromHeight(56),
),
And create another function or class as CustomAppBar which returns AppBar
return AppBar(
title: Text(
text ?? "Default Text",
),
);
And pass the text as parameter and if it is null you can set some default text for it.
The best solution is to wrap your AppBar with a BlocBuilder and wrap your BlocBuilder with Preferred Size. credit: jurej1 on GitHub.
appBar: PreferredSize(
preferredSize: const Size.fromHeight(56),
child: BlocBuilder<TurfBloc, TurfState>(
builder: (context, state) {
return AppBar(
centerTitle: true,
title: Text(state.text),
backgroundColor: state.color,
);
},
),
),
You can't, as Scaffold appBar property accept widgets that extend PreferredSizeWidget class. Wrap Scaffold with BlocBuilder and depending on Bloc state just change AppBar properties:
return BlocBuilder<YourBloc, YourState>(
builder: (context, state) => Scaffold(
appBar: AppBar(
title: state is Selected1 ? Text('Title1') : Text('TitleElse'),
elevation: state is Selected1 ? 0 : 1
)
)
);
Eventually create new widget that extend PreferredSizeWidget:
class MyAppBar extends StatelessWidget with PreferredSizeWidget {
#override
Widget build(BuildContext context) {
return BlocBuilder<YourBloc, YourState>(
builder: (context, state) {
if(state is Selected1) {
return AppBar(...);
} else if (state is Selected2) {
return AppBar(...);
} else {
return AppBar(...);
}
}
);
}
#override
Size get preferredSize => Size(appbarwidth, appbarheight);
}
and use it, but be sure you have BlocProvider<YourBloc> above Scaffold:
return Scaffold(appBar: MyAppBar());

How to show either a drawer or a bottomNavigationBar

I have a global variable that is true if using Android. The code below doesn't work. How can I decide what widget to display depending on the platform:
rmoMenu is a custom widget that returns a Drawer widget
rmoBottomNavigationBar is a custom widget that returns a BottomNavigationBar widget
#override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
appBar: rmoAppBar(subText: 'My Shifts'),
if (globals.gblIsAndroid == true) then {
drawer: rmoMenu()
} else {
bottomNavigationBar: rmoBottomNavigationBar(),
},
body: ...
You can use the ternary operator:
Scaffold(
appBar: rmoAppBar(subText: 'My Shifts'),
drawer: globals.gblIsAndroid ? rmoMenu() : null,
bottomNavigationBar: !globals.gblIsAndroid ? rmoBottomNavigationBar() : null,

How to put AppBar just under status bar?

I want to put AppBar just under status bar, but I couldn't, what can I do?
I tried primary:true, or SafeArea, my code as below:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("ホーム"),
),
body: Center(child: Text("ホーム")),
);
}
}
I also tried code from answer, but same result.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("ホーム"),
),
body: Center(child: Text("ホーム")),
));
}
}
You should try the SafeArea. But you must wrap the entire Scaffold inside the SafeArea.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("ホーム"),
),
body: Center(child: Text("ホーム")),
)
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
var sbHeight = MediaQuery.of(context).padding.top;
return Container(
margin: EdgeInsets.only(top: sbHeight),
child: Scaffold(
appBar: AppBar(
title: Text("Title"),
centerTitle: true,
),
body: Center(child: Text(sbHeight.toString())),
),
);
}
}
You can use more about SafeArea here: SafeArea

How can i make transparent appBar in flutter [duplicate]

This question already has answers here:
How can we change appbar background color in flutter
(11 answers)
Closed 2 years ago.
Now I want to make transparent appBar
So I looked for a way, but the examples put appBar on top of the image, but I want to put appBar on top of the widget, not on the image.
I want to know the way to make transparent appBar on top of the widget not image.
Here is my code
// main.dart
void main() => runApp(Main());
class Main extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SideBarLayout(),
);
}
}
// SideBarLayout.dart
class SideBarLayout extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
....
],
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Help'),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(30),
),
),
),
body: Stack(
children: <Widget>[
Consumer<MenuItem>(
builder: (BuildContext context, MenuItem value, Widget child){
if(value.menuType == MenuType.pomodoro) { return Pomodoro(); }
else if (value.menuType == MenuType.calendar) { return MonthTable(); }
else if (value.menuType == MenuType.todoList) { return TodoList(); }
else if (value.menuType == MenuType.settings) { return SettingView(); }}),
SideBar(),
],
),
),
);
}
}
I would set the backgroundColor of your AppBar to Colors.transparent and elevation to zero as well as setting extendBodyBehindAppBar: true, at your Scaffold.
Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
...
),
body: ...,
)
The AppBar uses the primary color of the Theme object of your MaterialApp.
You can also change the backgroundColor property and set it to Colors.transparent.
Check the first answer!