Related
I am getting a grey screen on two pages in my app, I m facing this problem only in release mode when I installed it from TestFlight. there is no error in debug mode, and it works fine also when I run it in release mode from android studio.
this is my code on two screens:
First screen:
ViewModelBuilder<TraineeCoachViewModel>.nonReactive(
builder: (context, model, child) => Layout(
title: coachFullName,
body:
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(Assets.rightBackground),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.2), BlendMode.dstATop),
),
),
child:
SingleChildScrollView(
child: Column(
children: [
FutureBuilder(
future: model.getCoachModel,
initialData: null,
builder: (BuildContext context,
AsyncSnapshot<CoachModel?> snapshot) {
if (!snapshot.hasData || snapshot.data == null) {
return const Loading();
}
final CoachModel coachmodel = snapshot.data!;
final List<String> additionalPhotos = coachmodel.album ?? [];
final String profilePhoto = coachmodel.profilePhoto ?? "";
final List<String?> imagesToSlide = [
profilePhoto,
...additionalPhotos
];
final _slideImageItemwidth =
MediaQuery.of(context).size.width / 2;
final _slideImageItemHeight =
MediaQuery.of(context).size.width / 2.5;
return
SingleChildScrollView(
padding: const EdgeInsets.all(10.0),
child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
height: _slideImageItemwidth,
width: _slideImageItemHeight,
decoration: BoxDecoration(
border: Border.all(
color: Colors.yellowAccent,
width: 1.0,
)),
child: PageView.builder(
itemCount: imagesToSlide.length,
itemBuilder: (_, index) {
final String? image = imagesToSlide[index];
return Hero(
tag: index.toString() + "S",
child: GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
fullscreenDialog: true,
builder: (BuildContext
context) =>
HeroPhoto(
imageUrl: image,
tag:
index.toString() +
"S"))),
child: CardItemProfilePhoto(
iconSize: 50,
imageUrl: image,
withBorderDecoration: false,
size: Size(_slideImageItemwidth,
_slideImageItemwidth),
),
));
}),
),
),
verticalSpaceMedium,
additionalPhotos.isNotEmpty
? GridView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: additionalPhotos.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
childAspectRatio: 0.7,
mainAxisSpacing: 5.0,
crossAxisSpacing: 5.0),
itemBuilder: (_, index) {
return Hero(
tag: "${index + 1}",
child: GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
fullscreenDialog: true,
builder: (BuildContext context) =>
HeroPhoto(
imageUrl:
additionalPhotos[
index],
tag: "${index + 1}"),
)),
child: LayoutBuilder(
builder: (BuildContext context,
BoxConstraints constraints) {
return CardItemProfilePhoto(
iconSize: 20,
imageUrl: additionalPhotos[index],
size: constraints.biggest,
);
},
),
),
);
})
: Container(),
coachmodel.bio != null
? verticalSpaceMediumS
: Container(),
coachmodel.bio != null
? AppText.headingTwo(
localizations.bio + ":",
)
: Container(),
verticalSpaceNormal,
Text(
coachmodel.bio ?? "",
style: captionStyle,
),
coachmodel.bio != null
? verticalSpaceMediumS
: Container(),
StreamBuilder(
stream: model.coursesStream,
builder: (BuildContext context,
AsyncSnapshot<List<CourseModel>> snapshot) {
if (!snapshot.hasData || snapshot.data == null) {
return const Loading(
showBackgroundColor: false,
);
}
final courses = snapshot.data
?.where((element) =>
element.isSameType(courseType))
.toList();
if (model.isBusy) {
WidgetsBinding.instance!
.addPostFrameCallback((timeStamp) {
model.setBusy(false);
});
}
return ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: courses!.length,
itemBuilder: (_, index) {
final courseModel = courses[index];
bool found = false;
if (courses[index].traineesIn != null &&
model.userId != '') {
found = courses[index]
.traineesIn!
.contains(model.userId);
}
///Subscription button
return SizedBox(
height: screenHeightPercentage(context,
percentage: 0.10),
width: double.infinity,
child: SubscriptionItemShaped(
params: getParams(courseModel,
model, localizations,
traineeIdFound: found,
context: context)));
});
},
),
]),
);
},
),
],
),
),
),
resizeToAvoidBottomInset: true,
),
viewModelBuilder: () => getIt<TraineeCoachViewModel>()
..coachId = coachID
..coachName = coachFullName
..init(),
);
Second screen:
ViewModelBuilder<NotificationsViewModel>.nonReactive(
builder: (context, model, child) {
return Layout(
title: localizations.subs_detail,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(Assets.rightBackground),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.2), BlendMode.dstATop),
),
),
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
top: screenHeightPercentage(context, percentage: 0.03)),
child: Column(
children: [
FutureBuilder<TraineeModel?>(
future: model.getTraineeModel(subsModel.traineeId!),
initialData: null,
builder: (BuildContext context,
AsyncSnapshot<TraineeModel?> snapshot) {
if (!snapshot.hasData || snapshot.data == null) {
return const Loading();
}
final TraineeModel userModel = snapshot.data!;
return Padding(
padding: EdgeInsets.only(
left: screenWidthPercentage(context,
percentage: 0.05)),
child: Column(
children: [
Text(localizations.trainee_detail.toUpperCase(),
style:
heading1Style.copyWith(fontSize: 20)),
verticalSpaceMedium,
CircularProfilePhoto(
imageurl: userModel.profilePhoto,
iconSize: 30,
height: screenHeightPercentage(context,
percentage: 0.17),
width: screenHeightPercentage(context,
percentage: 0.17),
),
verticalSpaceMedium,
Padding(
padding: langauge.appLocal.languageCode ==
'ar'
? EdgeInsets.only(
left: screenWidthPercentage(context,
percentage: 0.20),
right: screenWidthPercentage(context,
percentage: 0.2),
)
: EdgeInsets.only(
left: screenWidthPercentage(context,
percentage: 0.23),
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Text(
userModel.fullName!.toUpperCase(),
style: heading1Style.copyWith(
fontSize: 15,
color: kcWhiteColor),
),
verticalSpaceMedium,
Text(
userModel.gender.toUpperCase(),
style: heading1Style.copyWith(
fontSize: 15,
color: kcWhiteColor),
),
],
),
Column(
children: [
userModel.height != null
? verticalSpaceMedium
: Container(),
// userModel.height != null ?
Container(
margin: EdgeInsets.only(
right: screenWidthPercentage(
context,
percentage: 0.25)),
child: Text(
userModel.height != null
? '${userModel.height!.toString()} ${localizations.cm}'
: '0.0 ${localizations.cm}',
style: heading1Style.copyWith(
fontSize: 15,
color: kcWhiteColor),
),
),
//: Container(),
verticalSpaceMedium,
Container(
margin: EdgeInsets.only(
right: screenWidthPercentage(
context,
percentage: 0.25)),
child: Text(
userModel.weight != null
? '${userModel.weight!.toString()} ${localizations.kg}'
: '0.0 ${localizations.kg}',
style: heading1Style.copyWith(
fontSize: 15,
color: kcWhiteColor),
),
)
],
)
],
),
),
],
),
);
}),
verticalSpaceMedium,
Container(
height: 1,
color: kcWhiteColor,
margin: EdgeInsets.symmetric(horizontal: 30),
),
verticalSpaceMedium,
Text(localizations.course_detail.toUpperCase(),
style: heading1Style.copyWith(fontSize: 20)),
verticalSpaceMedium,
Text(subsModel.courseName!.toUpperCase(),
style: heading1Style.copyWith(
fontSize: 25, color: kcWhiteColor)),
verticalSpaceMedium,
Text(
'${subsModel.coursePrice} ${localizations.currency_code}',
style: heading1Style.copyWith(
fontSize: 25, color: kcWhiteColor)),
StreamBuilder<SubscriptionModel>(
stream: model.getSubscription(subsModel.id!),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Loading(
showBackgroundColor: false,
);
}
return Container(
margin: EdgeInsets.only(
top: screenHeightPercentage(context,
percentage: 0.1)),
child: snapshot.data!.subscriptionStatus.value ==
SUBSCRIPTION_STATUS
.WAITING_PAYMENT.value ||
snapshot.data!.subscriptionStatus.value ==
SUBSCRIPTION_STATUS.REJECTED.value ||
snapshot.data!.subscriptionStatus.value ==
SUBSCRIPTION_STATUS.BLOCKED.value
? StatusText(
status: snapshot
.data!.subscriptionStatus.value,
subscriptionModel: snapshot.data!,
localizations: localizations,
notificationsViewModel: model,
)
: Row(
children: [
Expanded(
child: ButtonWidget(
subscriptionModel: snapshot.data!,
localizations: localizations,
notificationsViewModel: model,
text: localizations.accept
.toUpperCase(),
color: Colors.green,
onPressed: () {
model.accept(snapshot.data!);
},
),
),
// ),
Expanded(
child: ButtonWidget(
subscriptionModel: snapshot.data!,
localizations: localizations,
notificationsViewModel: model,
text: localizations.chat_status
.toUpperCase(),
color: Colors.blueGrey,
onPressed: () {
model.chat(snapshot.data!);
},
),
),
Expanded(
child: ButtonWidget(
subscriptionModel: snapshot.data!,
localizations: localizations,
notificationsViewModel: model,
color: Colors.redAccent,
onPressed: () {
model.reject(
snapshot.data!, context);
},
text: localizations.reject
.toUpperCase(),
),
),
Expanded(
child: ButtonWidget(
subscriptionModel: snapshot.data!,
localizations: localizations,
notificationsViewModel: model,
color: Colors.red,
onPressed: () {
model.block(
snapshot.data!, context);
},
text: localizations.block
.toUpperCase(),
),
),
],
));
})
],
),
),
),
),
);
},
viewModelBuilder: () => getIt<NotificationsViewModel>()..init(),
);
I have been testing it on various devices, and I got the same problem.
As mentioned by #Amina Bekir, the issue was that they had two copies of the project, so Android Studio had the new copy while Xcode has the old one.
Then the old code was uploaded to TestFlight making this behavior to appear.
My application does not get the alignment problem in the examples I will show below while running on android devices. When I want to run it on my iOS device, I have the following alignment problem.
Problematic alignment starts here. My app experiences a completely symmetrical change when I choose the Persian or Arabic language and some emojis are aligned properly while others appear distorted.
My Code :
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: ortaMavi,
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.arrow_back_ios,
size: 20,
color: Colors.white,
)),
title: Center(child: Text(titleHolder)),
actions: <Widget>[
Center(
child: Container(
margin: EdgeInsets.all(15),
child: Text(
flagHolder,
style: TextStyle(fontSize: 25),
)),
)
],
),
body: SafeArea(
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 5),
itemCount: countries.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
EasyLocalizationProvider.of(context)
.data
.changeLocale(langs[index]);
setState(() {
titleHolder = countries[index];
flagHolder = flags[index];
selectedLangIndex = index;
});
},
child: Container(
decoration: BoxDecoration(
color:
selectedLangIndex != null && selectedLangIndex == index
? ortaMavi.withOpacity(0.2)
: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.lightBlueAccent.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 3,
offset: Offset(0, 3), // changes position of shadow
),
],
),
height: 50,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'${countries[index]}',
style: TextStyle(
fontSize: 20,
color: selectedLangIndex != null &&
selectedLangIndex == index
? Colors.white
: Colors.black),
),
Text(
flags[index],
style: TextStyle(fontSize: 25),
)
],
),
),
),
);
}),
),
);
}
You can put the flags String inside a SizedBox
SizedBox(
width: 200.0,
height: 200.0,
child:Text(
flags[index],
),
)
My code:
```flutter
Widget _buildActionForTask(TaskInfo task) {
if (task.status == DownloadTaskStatus.undefined) {
return new RawMaterialButton(
onPressed: () {
_requestDownload(task); /*download button*/
},
child: new Icon(
Icons.file_download,
size: 30,
),
shape: new CircleBorder(),
constraints: new BoxConstraints(minHeight: 32.0, minWidth: 32.0),
);
} else if (task.status == DownloadTaskStatus.running) {
/*there is my stuck*/
return new RawMaterialButton(
onPressed: () {
_pauseDownload(task); /*pause button*/
},
child: new Icon(
Icons.pause,
size: 30,
color: Colors.white,
),
shape: new CircleBorder(),
constraints: new BoxConstraints(minHeight: 32.0, minWidth: 32.0),
);
} else if (task.status == DownloadTaskStatus.paused) {
return new RawMaterialButton(
onPressed: () {
_resumeDownload(task); /*resume button*/
},
child: new Icon(
Icons.play_arrow,
size: 30,
color: Colors.green,
),
shape: new CircleBorder(),
constraints: new BoxConstraints(minHeight: 32.0, minWidth: 32.0),
);
}
Here is my appbar:
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Image ${this.widget.index}"),
Builder(
builder: (context) => _isLoading
? Center(
child: CircularProgressIndicator(),
)
: _permissionReady
? _buildActionForTask(taskInfo)
: FlatButton(
onPressed: () {
_checkPermission().then((hasGranted) {
setState(() {
_permissionReady = hasGranted;
});
});
},
child: Text(
"Thử lại",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20.0),
)),
)
],
),
flexibleSpace: GradientBar(),
),
I am creating a function to download. After I hit the download button, it encountered this error. Download and delete buttons are displayed normally.
I tried many ways but still got that error. I still don't know how it can overflow 99788px?
Don't use a Row inside title, try using just the text widget and move the other widgets (, the one inside builder) to the action parameter, it accepts a list of widgets to the right of the appbar
Try wrapping your button with a Container and giving it fixed width.
You can also try to give fixed width to your constraints
I want to add some text validation to my CupertinoTextField but there's no validator for this Widget. How can I solve this?
I tried searching on the internet for some solutions but nothing came out.
CupertinoTextField(
prefix: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
customIcon,
),
),
style: TextStyle(
fontSize: 30,
),
keyboardType: TextInputType.number,
maxLength: maxLength,
maxLines: 1,
maxLengthEnforced: true,
placeholder: placeholderText,
onChanged: onChangedFunction,
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(32.0),
),
)
You need to use TextEditingController & perform the validation manually.
Basic validation for checking if the field is empty or not.
code:
TextEditingController _myPhoneField = TextEditingController();
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_myPhoneField.text.isEmpty) {
showCupertinoDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text('error'),
content: Text('Phone Field is Empty'),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('ok'))
],
);
});
} else {
// Validation passed
}
},
child: Text('submit'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoTextField(
clearButtonMode: OverlayVisibilityMode.editing,
controller: _myPhoneField, // Add this
prefix: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
CupertinoIcons.phone_solid,
),
),
style: TextStyle(
fontSize: 30,
),
keyboardType: TextInputType.number,
maxLength: 10,
maxLines: 1,
maxLengthEnforced: true,
placeholder: 'Enter Phone',
onChanged: (v) {
print(v);
},
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(32.0),
),
),
],
),
);
}
This is not about CupertinoTextField, but if you still want to validate input on Cupertino, you can use the CupertinoTextFormFieldRow widget.
CupertinoTextFormFieldRow(
controller: _usernameController,
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Please enter a valid username.';
}
return null;
},
decoration: BoxDecoration(
color: Colors.black12,
border: Border.all(
color: Colors.black12,
),
borderRadius: BorderRadius.circular(8.0),
),
)
Map item;
List data;
Future getdata() async{
http.Response response= await http.get(Uri.encodeFull("https://talaikis.com/api/quotes/"));
item=json.decode(response.body);
setState(() {
data=item["quotes"];
});
debugPrint(data.toString());
}
I want to display this request in stateful widget which is like this
#override
Widget build(BuildContext context) {
return new Scaffold(
drawer: drawerLeft(),
appBar: AppBar(
title: Text(
"IN TIME",
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w700),
),
backgroundColor: clr,
elevation: 0.0,
leading: MaterialButton(
child: Icon(
Icons.view_headline,
color: Colors.black,
),
onPressed: () {
scaffoldKey.currentState.openDrawer();
},
)),
key: scaffoldKey,
body: AnimatedContainer(
padding: EdgeInsets.only(top: 50.0),
duration: Duration(milliseconds: 1000),
curve: Curves.ease,
color: clr,
child: PageView.builder(
itemCount: 7, //7days
onPageChanged: (int page) {
this.setState(() {
Random rnd;
rnd = new Random();
int r = 0 + rnd.nextInt(_colors.length - 0);
clr = _colors[r];
});
},
controller: pageViewController,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Stack(
children: <Widget>[
Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
),
height:
MediaQuery.of(scaffoldKey.currentContext).size.height -
150.0,
width:
MediaQuery.of(scaffoldKey.currentContext).size.width -
20.0,
child: Stack(
children: <Widget>[
Positioned(
width: MediaQuery.of(scaffoldKey.currentContext)
.size
.width -
100.0,
left: index != currentPage
? getMappedValue(20.0, 100.0, 160.0, 20.0, pos)
: getMappedValue(20.0, 100.0, 20.0, -120.0, pos),
top: 20.0,
child: Opacity(
opacity: index != currentPage
? getMappedValue(20.0, 100.0, 0.0, 01.0, pos)
: getMappedValue(20.0, 100.0, 01.0, 00.0, pos),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
_days[index],
maxLines: 1,
softWrap: true,
style: TextStyle(
color: Colors.deepOrange,
fontSize: 22.0,
fontWeight: FontWeight.w600),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Text(
'Quote for the day',
softWrap: true,
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w300),
),
),
],
),
),
),
],
),
),
],
),
);
},
),
),
);
}
}
*Please help me out *
If I understand, you want to display the quotes under some padding that are being retrieved to your List which I'll assume to be an inferenced List<String>. If so, you could just use a ListView within your widget tree to display every fetched item in that list, like so:
(...)
data != null
? Padding(
padding: const EdgeInsets.only(top: 15.0),
child: ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(data[index]),
);
},
),
)
: Container(),
(...)