Get users First Letter of First Name in Flutter with Firebase? - firebase

I have got the user's first name fine, but I'm wondering how I can create an icon using the user's first letter in their name. See attached the UI.
See code below.
User Profile UI
User Profile Page Screen
BlocBuilder(
cubit: BlocProvider.of<UserBloc>(context),
builder: (context, User user) {
return Text(
(user == null || user.firstName == null)
? 'Welcome'
: '${user.firstName}',
style: TextStyle(
fontFamily: 'Helvetica Neue',
fontSize: 25,
color: const Color(0xff3a4759),
),
textAlign: TextAlign.left,
);
}),
Please note "UserBloc" is not relevant to the question so I haven't included it in this post.

The below code for a Stateless widget will create an Icon according to the UI you showed for reference.
It takes in the parameters:
firstName - The name of the person as String.
backgroundColor- The background colour for the circle enclosing the first letter.
textColor- The colour for the first letter
class NameIcon extends StatelessWidget {
final String firstName;
final Color backgroundColor;
final Color textColor;
const NameIcon(
{Key key, #required this.firstName, this.backgroundColor= Colors.white, this.textColor= Colors.black,})
: super(key: key);
String get firstLetter => this.firstName.substring(0, 1).toUpperCase();
#override
Widget build(BuildContext context) {
return FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: this.backgroundColor,
border: Border.all(color: Colors.black, width: 0.5),
),
padding: EdgeInsets.all(8.0),
child: Text(this.firstLetter, style: TextStyle(color: this.textColor)),
),
);
}
}
The widget will automatically fit the size and height of the parent widget or a Container, if you want to specify the values explicitly then remove the FittedBox widget and then specify the height and width of the container.
OutPut:
Whole Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: Center(
child: Container(
height: 150.0,
width: 300.0,
child: NameIcon(
firstName: 'Hello',
),
),
),
);
}
}
class NameIcon extends StatelessWidget {
final String firstName;
final Color backgroundColor;
final Color textColor;
const NameIcon(
{Key key, #required this.firstName, this.backgroundColor= Colors.white, this.textColor= Colors.black,})
: super(key: key);
String get firstLetter => this.firstName.substring(0, 1).toUpperCase();
#override
Widget build(BuildContext context) {
return FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: this.backgroundColor,
border: Border.all(color: Colors.black, width: 0.5),
),
padding: EdgeInsets.all(8.0),
child: Text(this.firstLetter, style: TextStyle(color: this.textColor)),
),
);
}
}

FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.yellow,
border: Border.all(color: Colors.black, width: 0.5),
),
padding: EdgeInsets.all(8.0),
child: BlocBuilder(
cubit: BlocProvider.of<UserBloc>(context),
builder: (context, User user) {
return Text(
(user == null || user.firstName == null)
? 'Welcome'
: '${user.firstName[0].toUpperCase()}',
style: TextStyle(
fontFamily: 'Helvetica Neue',
fontWeight: FontWeight.bold,
fontSize: 25,
color: const Color(0xff3a4759),
),
textAlign: TextAlign.left,
);
}),
),
),

Related

TextField input won't print to console?

I'm trying to use a custom TextField widget in my AddNoteScreen. I don't know why it's not printing the TextField input or how to get it to work. I thought having the TextEditingController was all it needed.. I'm new.. sorry to post so much code I don't know how else to explain.
Here is my custom widget:
class MyWidget extends StatefulWidget {
final Widget textFields;
MyWidget(
{required this.textFields});
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
TextEditingController notesController = TextEditingController();
List<TextField> textFields = [];
#override
void initState() {
super.initState();
textFields.add(_buildTextField());
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Colors.white,
),
height: 300,
alignment: Alignment.centerLeft,
child: ListView(
children: textFields,
),
);
}
TextField _buildTextField() {
return TextField(
style: TextStyle(
color: Colors.black,
fontSize: 18,
),
decoration: InputDecoration(
prefix: Icon(
Icons.circle,
size: 10,
color: Colors.black,
),
prefixIconConstraints: BoxConstraints(
minWidth: 20,
minHeight: 10,
maxHeight: 10,
maxWidth: 20,
),
),
autofocus: true,
onSubmitted: (_) {
setState(() {
textFields.add(_buildTextField());
notesController.text + ' ';
});
}
);
}
}
My AddNoteScreen:
class AddNoteScreen extends StatefulWidget {
User user;
AddNoteScreen({
required this.user,
});
#override
State<AddNoteScreen> createState() => _AddNoteScreenState();
}
class _AddNoteScreenState extends State<AddNoteScreen> {
TextEditingController notesController = TextEditingController();
FirebaseFirestore firestore = FirebaseFirestore.instance;
bool loading = false;
#override
void initState(){
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor:Color (0xFF162242),
elevation: 0,
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
notesController.text = '';
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(children: [
Container(
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10),),
color: Colors.white,
),
child: MyWidget(
textFields: TextField(
style: TextStyle (color: Color(0xFF192A4F),fontSize: 18,),
textCapitalization: TextCapitalization.sentences,
controller: notesController,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
),
),
),
SizedBox(height: 50,),
loading ? Center (child: CircularProgressIndicator(),) : Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
onPressed: ()async{
if (
notesController.text.isEmpty)
{
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("All feilds are required")));
} else {
setState(() {
loading = true;
});
await FirestoreService().insertNote(notesController.text,
widget.user.uid);
CollectionReference notes = firestore.collection('notes');
QuerySnapshot allResults = await notes.get();
allResults.docs.forEach((DocumentSnapshot result) {
print(result.data());
});
setState(() {
loading = false;
});
Navigator.pop(context);
}
}, child: Text("Add Note", style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Color (0xFF162242)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
//color:Color (0xFF162242)
//ElevatedButton.styleFrom(primary: Color (0xFF162242),),
),
),
]),),
),
),
);
My FirestoreService page:
class FirestoreService{
FirebaseFirestore firestore = FirebaseFirestore.instance;
Future insertNote(String notes, String userId)async{
try{
await firestore.collection('notes').add({
"notes":notes,
"userId":userId
});
} catch(e){
}
}
}
And my NoteModel Screen:
class NoteModelEdit {
String id;
String notes;
String userId;
NoteModelEdit({
required this.id,
required this.notes,
required this.userId
});
factory NoteModelEdit.fromJson(DocumentSnapshot snapshot){
return NoteModelEdit(
id: snapshot.id,
notes: snapshot['notes'],
userId: snapshot['userId']
);
}
}
Any help is appreciated!
I believe you are storing an empty note, which is the reason why the result from the database is empty.
This line:
if (notesController.text.isNotEmpty) // show error message
should become this:
if (notesController.text.isEmpty) // show error message
Also, this should probably change, too:
// This does nothing:
new TextEditingController().clear();
// To clear the controller:
notesController.text = '';
UPDATE
Change your code as follows to test if something
gets written into the database. Once this works, figure out how to use MyWidget correctly, as there are issues in there, too.
// OLD CODE
child: MyWidget(
textFields: TextField(
style: TextStyle (color: Color(0xFF192A4F),fontSize: 18,),
textCapitalization: TextCapitalization.sentences,
controller: notesController,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
),
),
// NEW CODE
child: TextField(
style: TextStyle (color: Color(0xFF192A4F),fontSize: 18,),
textCapitalization: TextCapitalization.sentences,
controller: notesController,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
),
I suggest to always only change small parts of code and ensure that your code works at each small step. Do not make too many changes at once.

Edit User Profile Page and Profile Picture. Using Real-Time Database flutter

I am trying to pull user data from my UserProfileBrowse Data model and display it on my user profile edit page. Including the image. I also want to update the data into my real-time Database.
THIS IS MY DATA MODEL
class UserProfileBrowse {
String userId;
int age;
String name;
String email;
String imageUrl;
UserProfileBrowse(
this.userId,
this.age,
this.name,
this.email,
this.imageUrl,
);
Map<dynamic, dynamic> toJson() => <dynamic, dynamic>{
'userId': userId,
'age': age,
'name': name,
'email': email,
'imageUrl' : imageUrl,
};
}
THIS IS MY USER PROFILE EDIT PAGE
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth.dart';
import 'home.dart';
import 'settings.dart';
import 'package:shadow_app_project/data_models/user_profile_browse.dart';
import 'package:shadow_app_project/image_selection/user_edit_image.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
class SettingsUI extends StatelessWidget {
const SettingsUI({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: "Setting UI",
home: EditProfilePage(),
);
}
}
class EditProfilePage extends StatefulWidget {
const EditProfilePage({Key? key}) : super(key: key);
#override
_EditProfilePageState createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
String currentUser = (Auth().auth.currentUser as User).email.toString();
TextEditingController displayNameController = TextEditingController();
TextEditingController ageController = TextEditingController();
bool isLoading = false;
User? user;
UserProfileBrowse? userModel;
String? imageUrl;
final refDatabase = FirebaseDatabase.instance;
bool showPassword = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 1,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => const SettingsPage()));
},
),
actions: [
IconButton(
icon: const Icon(
Icons.settings,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => const SettingsPage()));
},
),
],
),
body: Container(
padding: const EdgeInsets.only(left: 16, top: 25, right: 16),
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: ListView(
children: [
const Text(
"Edit Profile",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
const SizedBox(
height: 15,
),
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Theme.of(context).scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 10,
color: Colors.black.withOpacity(0.1),
offset: const Offset(0, 10))
],
shape: BoxShape.circle,
image: const DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://images.pexels.com/photos/3307758/pexels-photo-3307758.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250",
))),
),
const SizedBox(
height: 35,
),
TextField(
decoration: const InputDecoration(
labelText: "Name",
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
hintText: 'Input Name',
),
controller: displayNameController,
keyboardType: TextInputType.name,
),
TextField(
decoration: const InputDecoration(
labelText: "Age",
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
hintText: 'Input Age',
),
controller: ageController,
//
keyboardType: TextInputType.number,
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Email: ", style: TextStyle(fontSize: 20),),
),
const SizedBox(
height: 35,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () {},
child: const Text("CANCEL",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.black)),
),
TextButton(
onPressed: () {
FirebaseDatabase.instance.ref()
.child('useProfileBrowse')
.child(user!.uid)
.update({
'name': displayNameController.text //yes I know.
});
FirebaseDatabase.instance.ref()
.child('useProfileBrowse')
.child(user!.uid)
.update({
'age': ageController.text //yes I know.
});
},
child: const Text(
"SAVE",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
)
],
),
),
),
);
}
}
I am thinking to use a StreamBuilder in my body: with stream: FirebaseDatabase.instance.ref().child('userProfileBrowse').child(user!.uid).onValue,
Any idea how can I display User profile Imageurl, name, and age from my real-time Database
And also edit the information using stream builder or any other method
I have just coded the UI for my profile edit page. I just want someone to help me retrieve data from my data model class and display it on my user edit page. A single line to display just a name from my data model will help a lot to understand how retrieving data works. I have already saved data(imageUrl, name, age) into my data models during the signup process. Just want to display it
full example with StreamProvider :
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Person {
Person({required this.name, required this.initialAge});
final String name;
final int initialAge;
Stream<String> get age async* {
var i = initialAge;
while (i < 85) {
await Future.delayed(const Duration(seconds: 1), () {
i++;
});
yield i.toString();
}
}
}
void main() {
runApp(
StreamProvider<String>(
create: (_) => Person(name: 'Yohan', initialAge: 25).age,
initialData: 25.toString(),
catchError: (_, error) => error.toString(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Future Provider"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Consumer<String>(
builder: (context, String age, child) {
return Column(
children: <Widget>[
const Text("Watch Yohan Age..."),
const Text("name: Yohan"),
Text("age: $age"),
],
);
},
),
),
),
);
}
}
You already started to use the Provider as a state management, so I'd recommend using StreamProvider like this:
StreamProvider<String>(
create: (_) => Profile(name: 'Yohan', initialImageURL: ''),
initialData: ''.toString(),
catchError: (_, error) => error.toString(),
child: child(),
builder: (context) {
// Pretend this is loading data and reporting the percent loaded.
},
),
)
or you can just notify the UI every time you have got a change from the firebase using ChangeNotifier,
for examples, visit Docs

Flutter : starting the app with welcome page

I'm new to flutter and in my new project I've created a welcome screen that have 2 buttons either login or sign up , I'm using a Wrapper for the authentication and a toggle to navigate between login and sign up ... every thing works fine , but once the app lunches it shows the login screen not the welcome screen !
here is my wrapper class
class wrapper extends StatelessWidget {
const wrapper({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final userModel = Provider.of<UserModel?>(context);
// either home or login page
if(userModel == null){
return const Authenticate();
}else{
return const Home();
}
}
}
and here is my main
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 StreamProvider<UserModel?>.value(
initialData: null,
value: Authentication().onAuthStateChanged,
builder: (context, snapshot) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Auth',
theme: ThemeData(
primaryColor: kPrimaryColor,
scaffoldBackgroundColor: Colors.white,
textTheme: GoogleFonts.nunitoTextTheme(),
),
home: wrapper(),
);
}
);
}
}
the authenticate class :
class Authenticate extends StatefulWidget {
const Authenticate({Key? key}) : super(key: key);
#override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
bool showSignIn = true ;
void toggleView() {
setState(() {
showSignIn = !showSignIn;
});
}
#override
Widget build(BuildContext context) {
if(showSignIn){
return LoginScreen(toggleView : toggleView);
}else{
return SignUpScreen(toggleView : toggleView);
}
}
}
welcome screen :
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const Scaffold(
body: Body(),
);
}
}
Body :
class Body extends StatelessWidget {
const Body({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
height: size.height,
width: double.infinity,
color: Color(0xFFA9D7CC),
child:Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: size.width,height: 70),
SvgPicture.asset(
"assets/images/recycle.svg" ,
width:441.4,
height: 294 ,
),
const Padding(
padding: EdgeInsets.fromLTRB(20, 40, 7, 0),
child:
Text("lets make saving the planet easy !",
style: TextStyle(
fontSize: 48 ,
fontWeight: FontWeight.bold,
color: Colors.white
),
),
),
const Padding(
padding: EdgeInsets.fromLTRB(27, 10, 110, 0),
child:
Text("start recycling and earn some money ",
style: TextStyle(
fontSize: 20 ,
fontWeight: FontWeight.normal,
color: Colors.white
),
),
),
SizedBox(width: size.width,height: 70),
// login button
SizedBox(
width: 297,
height: 71,
child: ElevatedButton(
style:ElevatedButton.styleFrom(
primary: kPrimaryPopColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40)
)
) ,
onPressed: (){},
child: const Text("login",
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold
),)),
),
//sign up button
SizedBox(
height: 70,
child: TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
),
onPressed: () {},
child: const Text('sign up',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),),
),
)
],
),
);
}
}
Your code in not full. Try to debug
https://docs.flutter.dev/development/tools/devtools/debugger
It seems to me, that here is true
if(userModel == null){
return const Authenticate();

Flutter bottom Navigator gesture detector not working

I made a custom bottom navigator with icons being a separate widget, the custom navigator bar is present at the bottom of the pageview. On swipe, the pages change so do the color of the icons but I can't change the pages by clicking on the icons also logout button is not working. This is the code for the custom bottom navigator with the separate widget for items within the bottom custom navigation bar
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart'as firebase_auth;
import 'package:flutter_fashion/main.dart';
class CustomBottomNavigator extends StatefulWidget {
final int tab;
final Function(int) tabPressed;
const CustomBottomNavigator({Key? key, required this.tab, required this.tabPressed}) : super(key: key);
#override
_CustomBottomNavigatorState createState() => _CustomBottomNavigatorState();
}
class _CustomBottomNavigatorState extends State<CustomBottomNavigator> {
int _selectedTab=0;
#override
Widget build(BuildContext context) {
_selectedTab=widget.tab;
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12), topRight: Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
spreadRadius: 1.0,
blurRadius: 30.0)
]),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CustomBottomNavigatorItem(
icon: Icons.home_outlined,
selected: _selectedTab==0?true:false,
onPressed: () {
widget.tabPressed(0);
},
),
CustomBottomNavigatorItem(
icon: Icons.code_rounded,
selected: _selectedTab==1?true:false,
onPressed: () {
widget.tabPressed(1);
},
),
CustomBottomNavigatorItem(
icon: Icons.bookmark_border_rounded,
selected: _selectedTab==2?true:false,
onPressed: () {
widget.tabPressed(2);
},
),
CustomBottomNavigatorItem(
icon: Icons.logout_rounded,
selected: _selectedTab==3?true:false,
onPressed: () {
firebase_auth.FirebaseAuth.instance.signOut();
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (builder) => MyApp()),
(route) => false);
},
),
],
),
);
}
}
class CustomBottomNavigatorItem extends StatelessWidget {
final IconData icon;
final bool selected;
final Function onPressed;
CustomBottomNavigatorItem(
{required this.icon, required this.selected, required this.onPressed,});
#override
Widget build(BuildContext context) {
bool _selected = selected;
return GestureDetector(
onTap: () => onPressed,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 28),
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: _selected
? Theme.of(context).accentColor
: Colors.transparent,
width: 2.0))),
child: Icon(
icon,
size: 24,
color: _selected ? Theme.of(context).accentColor : Colors.black,
),
),
);
}
}
The onPressed isn't called. The parentheses are missing. Either use:
onTap: () => onPressed(),
or
onTap: onPressed,

How can I use a appear in another widget?

Im trying to use a appbar widget in another widget so my code is more clear. But the question is how can I do this ?
Heres my app bar widget :
class thisappbar extends StatelessWidget {
thisappbar(this.isMe, this.username, {this.key});
final Key key;
final bool isMe;
String username;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
flexibleSpace: SafeArea(
child: Container(
padding: EdgeInsets.only(right: 16),
child: Row(
children: <Widget>[
IconButton(
onPressed: (){
Navigator.pop(context);
},
----------
And heres the way I wanna use it :
class ChatScreen extends StatelessWidget {
static const route = '/messages';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(thisappbar(),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(child: Messages()),
NewMessage(),
],
)),
);
}
}
Hope anyone can help thanks!
This is how my methods look now first the app bar widget after editing some changes from user #Steve Nosse :
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
CustomAppBar({this.key, this.isMe, this.username}) : super(key: key);
final Key key;
final bool isMe;
String username;
#override
Widget build(BuildContext context) {
/// Build you AppBar widget here
return Scaffold(
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
flexibleSpace: SafeArea(
child: Container(
padding: EdgeInsets.only(right: 16),
child: Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back, color: Colors.black,),
),
SizedBox(width: 2,),
CircleAvatar(
backgroundImage: NetworkImage(
'https://randomuser.me/api/portraits/men/5.jpg'),
maxRadius: 20,
),
SizedBox(width: 12,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
username, style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600),),
SizedBox(height: 6,),
Text("Online", style: TextStyle(
color: Colors.grey.shade600, fontSize: 13),),
],
),
),
Icon(Icons.settings, color: Colors.black54,),
],
),
),
),
),
);
}
#override
Size get preferredSize => Size.fromHeight(56);
}
And heres where I use the appbar widget:
class ChatScreen extends StatelessWidget {
static const route = '/messages';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(),
body: Container(
child: Column(
children: <Widget>[
Expanded(child: Messages()),
NewMessage(),
],
)),
);
}
}
And this is the error :
======== Exception caught by widgets library =======================================================
The following assertion was thrown building CustomAppBar(dirty):
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 378 pos 10: 'data != null'
The relevant error-causing widget was:
CustomAppBar file:///Users/name/StudioProjects/project/lib/seitenleiste/nachrichten.dart:390:15
When the exception was thrown, this was the stack:
#2 new Text (package:flutter/src/widgets/text.dart:378:10)
#3 CustomAppBar.build (package:project/seitenleiste/nachrichten.dart:357:23)
#4 StatelessElement.build (package:flutter/src/widgets/framework.dart:4646:28)
#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4572:15)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4265:5)
...
You can try this:
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
CustomAppBar({this.key, this.isMe, this.username}) : super(key: key);
final Key key;
final bool isMe;
String username;
#override
Widget build(BuildContext context) {
/// Build you AppBar widget here
return Container();
}
#override
Size get preferredSize => Size.fromHeight(56);
}
Your CustomAppBar, as any other class, can by designed to take parameters from the outside to build itself.
The fact that it implements the PreferredSizeWidget allows us to easily use it as a parameter for the appBar attribute of the Scaffold widget.

Resources