Flutter SingelChildScrollView for column is not working - flutter

I have the following code in flutter. The first Expanded with flex 1 can be scrolled if needed but the next Expanded with flex 2 and the list of widgets (createButtons(answerList)) can not be scrolled and I can not figure out why? Both have the scrollable in them!
import 'package:flutter/material.dart';
import '../../backend/QuestionaireConstants/question.dart';
import '../../backend/utils/constants.dart';
import '../../backend/utils/setupcomingRoute.dart';
import '../../backend/widgets/button_content.dart';
import '../../backend/widgets/reusable_cart.dart';
int selectedAnswer = -1;
int counter = 0;
Color determineColor(int selection) {
return selectedAnswer == selection ? Colors.white : Colors.black;
}
class SelectionWindow extends StatefulWidget {
const SelectionWindow({Key? key}) : super(key: key);
#override
_SelectionWindowState createState() => _SelectionWindowState();
}
class _SelectionWindowState extends State<SelectionWindow> {
#override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as List<Question>;
int count = args[0].counter;
int arraylen = args.length;
List answerList = args[count].possibleAnswers;
String upcomingRoute = setUpcomingRoute(count, arraylen, args);
List<Widget> createButtons(list) {
List<Widget> buttons = [];
//creating single choice buttons
for (var i = 0; i < list.length; i++) {
buttons.add(
Row(
children: [
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
selectedAnswer = i;
});
},
child: ReusableCard(
colour: selectedAnswer == i
? Colors.blue.shade900
: Colors.blue.shade200,
cardChild: ButtonContent(
label: args[count].possibleAnswers[i],
textColour: determineColor(i),
),
),
),
),
],
),
);
}
return buttons;
}
//showing error screen
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text('Please select one answer before continuing.'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text(
'Approve',
style: TextStyle(fontSize: 22),
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
return Scaffold(
appBar: AppBar(
iconTheme: backwardsArrowBlack,
automaticallyImplyLeading: false,
title: appBarText,
backgroundColor: Colors.blue.shade100,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(args[count].questionText,
style: multipleChoiceTextStyle),
),
),
),
Expanded(
flex: 2,
child: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: createButtons(answerList),
),
),
Expanded(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: GestureDetector(
onTap: () {
if (args[0].counter > 0) {
args[0].counter -= 1;
args[count - 1].givenAnswers.clear();
}
Navigator.pop(context);
},
child: backwardsButton,
),
),
Expanded(
child: GestureDetector(
onTap: () {
if (selectedAnswer == -1) {
_showMyDialog();
} else {
args[count].givenAnswers.add(args[count]
.possibleAnswers[selectedAnswer]);
selectedAnswer = -1;
if (args[0].counter == arraylen - 1) {
args[0].counter += 1;
Navigator.pushNamed(context, '/endScreen',
arguments: args)
.then((_) => setState(() {}));
} else {
args[0].counter += 1;
Navigator.pushNamed(
context,
upcomingRoute,
arguments: args,
).then((_) => setState(() {}));
}
}
},
child: forwardButton,
),
),
],
),
),
),
],
),
),
],
),
);
}
}
The emulator shows the following error in case of having many answers in the list that are not fit in the page:
====================================================================================================
D/EGL_emulation(15191): app_time_stats: avg=10.35ms min=0.79ms max=89.84ms count=52
D/EGL_emulation(15191): app_time_stats: avg=104.68ms min=0.77ms max=1043.27ms count=11
D/EGL_emulation(15191): app_time_stats: avg=69.44ms min=11.30ms max=1017.83ms count=19
I/flutter (15191): type 'Null' is not a subtype of type 'FutureOr<int>'
D/EGL_emulation(15191): app_time_stats: avg=151.10ms min=0.54ms max=925.70ms count=12
======== Exception caught by rendering library =====================================================
The following assertion was thrown during layout:
A RenderFlex overflowed by 203 pixels on the bottom.

This worked:
import 'package:flutter/material.dart';
import '../../backend/QuestionaireConstants/question.dart';
import '../../backend/utils/constants.dart';
import '../../backend/utils/setupcomingRoute.dart';
import '../../backend/widgets/button_content.dart';
import '../../backend/widgets/reusable_cart.dart';
int selectedAnswer = -1;
int counter = 0;
Color determineColor(int selection) {
return selectedAnswer == selection ? Colors.white : Colors.black;
}
class SelectionWindow extends StatefulWidget {
const SelectionWindow({Key? key}) : super(key: key);
#override
_SelectionWindowState createState() => _SelectionWindowState();
}
class _SelectionWindowState extends State<SelectionWindow> {
#override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as List<Question>;
int count = args[0].counter;
int arraylen = args.length;
List answerList = args[count].possibleAnswers;
String upcomingRoute = setUpcomingRoute(count, arraylen, args);
List<Widget> createButtons(list) {
List<Widget> buttons = [];
//creating single choice buttons
for (var i = 0; i < list.length; i++) {
buttons.add(
Row(
children: [
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
selectedAnswer = i;
});
},
child: ReusableCard(
colour: selectedAnswer == i
? Colors.blue.shade900
: Colors.blue.shade200,
cardChild: ButtonContent(
label: args[count].possibleAnswers[i],
textColour: determineColor(i),
),
),
),
),
],
),
);
}
return buttons;
}
//showing error screen
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text('Please select one answer before continuing.'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text(
'Approve',
style: TextStyle(fontSize: 22),
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
return Scaffold(
appBar: AppBar(
iconTheme: backwardsArrowBlack,
automaticallyImplyLeading: false,
title: appBarText,
backgroundColor: Colors.blue.shade100,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(args[count].questionText,
style: multipleChoiceTextStyle),
),
),
),
Expanded(
flex: 2,
child: SingleChildScrollView(
child: Column(
children: createButtons(answerList),
),
),
),
Expanded(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: GestureDetector(
onTap: () {
if (args[0].counter > 0) {
args[0].counter -= 1;
args[count - 1].givenAnswers.clear();
}
Navigator.pop(context);
},
child: backwardsButton,
),
),
Expanded(
child: GestureDetector(
onTap: () {
if (selectedAnswer == -1) {
_showMyDialog();
} else {
args[count].givenAnswers.add(args[count]
.possibleAnswers[selectedAnswer]);
selectedAnswer = -1;
if (args[0].counter == arraylen - 1) {
args[0].counter += 1;
Navigator.pushNamed(context, '/endScreen',
arguments: args)
.then((_) => setState(() {}));
} else {
args[0].counter += 1;
Navigator.pushNamed(
context,
upcomingRoute,
arguments: args,
).then((_) => setState(() {}));
}
}
},
child: forwardButton,
),
),
],
),
),
),
],
),
);
}
}

Related

Why setState() is calling reloading listview upon item selected, how to stop it ? in flutter App

My app reads data from PostgreSQL and displays on the screen in a listview. While selecting an item from listview app is getting refreshed and items are appending to existing list. My intention is to read data only once from the DB, display in list view, select single/multiple and proceed with processing. Any suggestions would be appriciated.
import 'package:e2/Models/MasterPositions.dart';
import 'package:flutter/material.dart';
import 'package:e2/Models/model_positions.dart';
class MasterControl extends StatefulWidget {
const MasterControl({super.key});
#override
State<MasterControl> createState() => _MasterControlState();
}
class _MasterControlState extends State<MasterControl> {
List<MasterPositions> selectedContacts = [];
List<MasterPositions> fetchedPositions = [];
List<MasterPositions> positions = [];
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Master Control"),
centerTitle: true,
automaticallyImplyLeading: false,
),
body: SafeArea(
child: Column(
children: [
Expanded(
child: FutureBuilder<List<dynamic>>(
future: ModelsPositions().fetchPositionsData(),
builder: (context, snapshot) {
List<dynamic> positionsRaw = snapshot.data ?? [];
for (var pos in positionsRaw) {
positions.add(MasterPositions(
custID: pos[0],
custName: pos[1],
mtm: double.tryParse(pos[2]) ?? 0.0,
availableCash: double.tryParse(pos[3]) ?? 0.0,
));
}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Center(child: CircularProgressIndicator());
default:
if (snapshot.hasError) {
return const Center(
child: Text(
'Error while loading Master Positions screen'));
} else {
return buildPositions(positions);
}
}
},
)),
],
),
),
);
}
Widget buildPositions(List<dynamic> positions) {
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: positions.length,
itemBuilder: (context, index) {
final pos = positions[index];
final custID = pos.custID;
final custName = pos.custName;
final mtm = pos.mtm;
final availableCash = pos.availableCash;
final isSelected = pos.isSelected;
return ListTile(
horizontalTitleGap: -5,
title: Card(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(custID),
const SizedBox(height: 5),
Text(custName)
],
),
),
Flexible(
fit: FlexFit.tight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('MTM : $mtm',
softWrap: false,
style: const TextStyle(fontFamily: 'Roboto')),
const SizedBox(height: 10),
Text(
'Available : $availableCash',
softWrap: false,
),
const SizedBox(
height: 10,
),
],
),
),
],
),
),
leading: isSelected
? Icon(
Icons.check_circle,
color: Colors.green[700],
)
: const Icon(
Icons.check_circle_outline,
color: Colors.grey,
),
onTap: () {
setState(() {
positions[index].isSelected = !positions[index].isSelected;
if (positions[index].isSelected == true) {
selectedContacts.add(MasterPositions(
custID: custID,
custName: custName,
mtm: mtm,
availableCash: availableCash));
} else if (positions[index].isSelected == false) {
selectedContacts.removeWhere(
(element) => element.custID == positions[index].custID);
}
});
},
);
});
}
}
I often use something like this:
if (snapshot.hasData) {
if (snapshot.data!.isNotEmpty) {
List<dynamic> positionsRaw = snapshot.data ?? [];
for (var pos in positionsRaw) {
positions.add(MasterPositions(
custID: pos[0],
custName: pos[1],
mtm: double.tryParse(pos[2]) ?? 0.0,
availableCash: double.tryParse(pos[3]) ?? 0.0,
));
return buildPositions(positions);
} else {
// return something
}
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
And so you can guarantee that your widget will be built with data, and only be rebuilt when your new data it's loaded

Pass items to a list to previous screen in Flutter

I have a search page that displays names with an add icon. When I press the add icon I want to pass the name to my previous screen that displays a list with names. I tried to do it as you can see down in my code but I have an error that my Athlete model doesn't have the constructor add. Can you help me figure out how to display the names in my list in previous screen? Thanks in advance!
My first screen that I display a list with names:
class AthleteScreen extends StatefulWidget {
const AthleteScreen({Key? key}) : super(key: key);
#override
State<AthleteScreen> createState() => _AthleteScreenState();
}
class _AthleteScreenState extends State<AthleteScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Future<List<Athlete>>? futureAthletebyTeamKey;
final List<Athlete> _athlete = [];
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Athletes'),
actions: <Widget>[
Row(
children: [
IconButton(
onPressed: () {
Navigator.of(context)
.push<Athlete>(
MaterialPageRoute(builder: (_) => const AddAthlete()))
.then((value) => setState(() {
if (value != null && value is Athlete) {
Athlete.add(_athlete[index].lastName, _athlete[index].firstName,_athlete[index].fatherName); //here is when I push to the page where the names that I want to add are displayed
}
}));
},
icon: const Icon(Icons.add),
color: Colors.black,
iconSize: 30.0,
),
],
),
],
),
body: Stack(
children: [
SingleChildScrollView(
child: Column(children: [
FutureBuilder<List<Athlete>>(
future: futureAthletebyTeamKey,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Athlete> _athlete = snapshot.data;
return ListView.builder(
itemCount: _athlete.length,
itemBuilder: (BuildContext context, int i) {
return CheckboxListTile(
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Flexible(
child: Text(
'${_athlete[i].lastName} ${_athlete[i].firstName}',
),
),
],
),
} else if (snapshot.hasError) {
logger.e('${snapshot.error}');
}
return const Center(
heightFactor: 20,
child: CircularProgressIndicator.adaptive(),
);
},
),
]),
),
);
}
}
My second screen where the names that I want to add in the list of my first page are displayed
class AddAthlete extends StatefulWidget {
const AddAthlete({Key? key}) : super(key: key);
#override
State<AddAthlete> createState() => _AddAthleteState();
}
class _AddAthleteState extends State<AddAthlete> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Future<List<Athlete>>? futureSearchAthleteByName;
#override
void initState() {
futureSearchAthleteByName =
ApiService.searchAthletesByName(context) as Future<List<Athlete>>?;
text = myController.text;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Text(
'Add Athletes',
),
],
),
),
body: SingleChildScrollView(
child: Column(
children: [
Stack(
children: [
SingleChildScrollView(
child: Column(children: [
FutureBuilder<List<Athlete>>(
future: futureSearchAthleteByName,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Athlete> _athlete = snapshot.data;
return ListView.builder(
itemCount: _athlete.length,
itemBuilder: (BuildContext context, int index) {
if (myController.text == '') {
return Container();
} else if (myController.text != '' &&
_athlete[index]
.lastName!
.toLowerCase()
.contains(myController.text
.toLowerCase()) ||
_athlete[index]
.firstName!
.toLowerCase()
.contains(
myController.text.toLowerCase())) {
return Column(
children: [
ListTile(
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
),
Row(
children: [
Flexible(
child: Text(
'${_athlete[index].lastName} ${_athlete[index].firstName}',
),
),
],
),
Row(
children: [
Flexible(
child: Text(
'(${_athlete[index].fatherName})',
),
),
],
),
],
),
trailing: IconButton(
icon: const Icon(
Icons.add,
color: Colors.black,
),
onPressed: () {
Navigator.pop(
context,
Athlete(
lastName: _athlete[index]
.lastName,
firstName: _athlete[index]
.firstName,
fatherName: _athlete[index]
.fatherName));
print(_athlete[index].lastName);
print(_athlete[index].firstName);
print(_athlete[index].fatherName); \\here is when I pop the names in my previous screen
},
),
),
],
);
}
});
} else if (snapshot.hasError) {
logger.e('${snapshot.error}');
}
return Container();
},
),
]),
),
],
),
],
),
),
);
}
}
If I was you I might do it in a different way
I add all the user id to the list on the second screen and pass the list to the second screen
in the first screen I call the API and get all the data by id and show it
(when a user doesn't select any element don't call the API)

how to show all text (Flutter)?

how to show the text in full? I'm getting this error (on the screen).
what should I change in my code? Is there any way to do it? In case you want to see the code please let me know I will update more.
read_mode.dart
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:quiz2/const/state.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/database/category_provider.dart';
import 'package:quiz2/database/db_helper.dart';
import 'package:quiz2/database/question_provider.dart';
import 'package:quiz2/model/user_answer_model.dart';
import 'package:quiz2/utils/utils.dart';
import 'package:quiz2/widgets/question_body.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ReadModePage extends StatefulWidget {
ReadModePage({Key key, this.title}):super(key: key);
final String title;
#override
_ReadModePageState createState() => _ReadModePageState();
}
class _ReadModePageState extends State<ReadModePage> {
SharedPreferences prefs;
int indexPage = 0;
CarouselController buttonCarouselController = CarouselController();
List<UserAnswer> userAnswers = new List<UserAnswer>();
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async{
prefs = await SharedPreferences.getInstance();
indexPage = await prefs.getInt("${context.read(questionCategoryState).state.name}_${context.read(questionCategoryState).state.ID}") ?? 0;
print('Save index page: ${indexPage}');
Future.delayed(Duration(milliseconds: 500)).then((value) => buttonCarouselController.animateToPage(indexPage));
});
}
#override
Widget build(BuildContext context) {
var questionModule = context.read(questionCategoryState).state;
return WillPopScope(child: Scaffold(
appBar: AppBar(title: Text(questionModule.name),
leading: GestureDetector(onTap: () => showCloseDialog(questionModule),
child: Icon(Icons.arrow_back), ),),
body: Container(
color: Colors.teal[100],
child: FutureBuilder<List<Question>>(
future: getQuestionByCategory(questionModule.ID),
builder: (context, snapshot){
if(snapshot.hasError)
return Center(
child: Text('${snapshot.error}'),);
else if(snapshot.hasData)
{
if(snapshot.data.length>0)
{
return Container(margin: const EdgeInsets.all(5.0),
alignment: Alignment.topCenter,
child: Card(
elevation: 20,
child: Container(
child: SingleChildScrollView(
child: Column(children: [
SizedBox(height: 15,),
QuestionBody(context: context,
carouselController: buttonCarouselController,
questions: snapshot.data,
userAnswers: userAnswers,),
SizedBox(height: 30,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(onPressed: () => showAnswer(context), child: Text("Show Answer"))
],)
],)
)
)
));
}
else return Center(
child: Text('Category don\'n have any question'));
} else
return Center(
child: CircularProgressIndicator(),);
}
),
),
), onWillPop: () async{
showCloseDialog(questionModule);
return true;
});
}
showCloseDialog(Category questionModule) {
showDialog(
context: context,
builder:(_) => new AlertDialog(
title: Text('Close'),
content: Text("Do you want to save this question index?"),
actions: [
TextButton(onPressed: (){
Navigator.of(context).pop(); //close dialog
Navigator.pop(context); //close screen
}, child: Text("No")),
TextButton(onPressed: (){
prefs.setInt("${context.read(questionCategoryState).state.name}_${context.read(questionCategoryState).state.ID}",
context.read(currentReadPage).state);
Navigator.of(context).pop(); //close dialog
Navigator.pop(context); //close screen
}, child: Text("Yes"))
],)
);
}
}
Future <List<Question>> getQuestionByCategory(int id) async{
var db = await copyDB();
var result = await QuestionProvider().getQuestionCategoryId(db, id);
return result;
}
question_body.dart
import 'package:auto_size_text/auto_size_text.dart';
import 'package:carousel_slider/carousel_controller.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:quiz2/const/state.dart';
import 'package:quiz2/database/question_provider.dart';
import 'package:quiz2/model/user_answer_model.dart';
import 'package:flutter/material.dart';
import 'package:quiz2/utils/utils.dart';
class QuestionBody extends StatelessWidget {
QuestionBody({Key key,
this.context,
this.userAnswers,
this.carouselController,
this.questions}):super(key:key);
BuildContext context;
List<UserAnswer> userAnswers;
CarouselController carouselController;
List<Question> questions;
#override
Widget build(BuildContext context){
return CarouselSlider(
carouselController: carouselController,
items: questions.asMap().entries.map((e) => Builder(
builder: (context) {
return Consumer(builder: (context, watch, _){
var userAnswerState = watch(userAnswerSelected).state;
var isShowAnswer = watch(isEnableShowAnswer).state;
return Column(
children: [
Expanded(
child: Column(
children: [
Text( //Question
context.read(isTestMode).state ? "${e.key+1}: ${e.value.questionText}":
"${e.value.questionId}: ${e.value.questionText}",
style: TextStyle(height:2, fontSize: 16)),
Visibility(//Question is image
visible: (e.value.isImageQuestion == null || e.value.isImageQuestion == 0 ? false:true),
child: Container(
height: MediaQuery.of(context).size.height/15*2,
child: e.value.isImageQuestion == 0 ? Container():
Image.network("${e.value.questionImage}",
fit: BoxFit.fill,)
)),
Expanded( //Answer A
child: ListTile(
title: AutoSizeText('${e.value.answerA}',
style: TextStyle(color: isShowAnswer ? e.value.correctAnswer == 'A' ? Colors.red : Colors.grey:Colors.black),
),
leading: Radio(
value: "A",
groupValue: getGroupValue(isShowAnswer,e,userAnswerState),
onChanged: (value) => setUserAnswer(context,e,value),
),
)),
Expanded( //Answer B
child: ListTile(
title: AutoSizeText('${e.value.answerB}',
style: TextStyle(color: isShowAnswer ? e.value.correctAnswer == 'B' ? Colors.red : Colors.grey:Colors.black),
),
leading: Radio(
value: "B",
groupValue: getGroupValue(isShowAnswer,e,userAnswerState),
onChanged: (value) => setUserAnswer(context,e,value),
),
)),
Expanded( //Answer C
child: ListTile(
title: AutoSizeText('${e.value.answerC}',
style: TextStyle(color: isShowAnswer ? e.value.correctAnswer == 'C' ? Colors.red : Colors.grey:Colors.black),
),
leading: Radio(
value: "C",
groupValue: getGroupValue(isShowAnswer,e,userAnswerState),
onChanged: (value) => setUserAnswer(context,e,value),
),
)),
Expanded( //Answer D
child: ListTile(
title: AutoSizeText('${e.value.answerD}',
style: TextStyle(color: isShowAnswer ? e.value.correctAnswer == 'D' ? Colors.red : Colors.grey:Colors.black),
),
leading: Radio(
value: "D",
groupValue: getGroupValue(isShowAnswer,e,userAnswerState),
onChanged: (value) => setUserAnswer(context,e,value),
),
))
],
)),
],
);
},
);
},
)).toList(), options: CarouselOptions(
autoPlay: false,
enlargeCenterPage: true,
viewportFraction: 0.9,
initialPage: 0,
height: MediaQuery.of(context).size.height/5*2,
onPageChanged: (page,_){
context.read(currentReadPage).state = page;
context.read(isEnableShowAnswer).state = false;
}
));
}
getGroupValue(bool isShowAnnswer, MapEntry<int, Question> e, UserAnswer userAnswerState){
return isShowAnnswer ? e.value.correctAnswer : (context.read(isTestMode).state ?
context.read(userListAnswer).state[e.key].answered:'');
}
}
Is there any way to do it? In case you want to see the code please let me know I will update more.
screen
Your widget tree seems a bit complicated for no reason.
Assuming what you wanted to achieve was to have your Show Answer button always be visible at the bottom of the Card and the other content on the top of this button to scroll itself inside the Card, this is a much better way to have the structure,
class Minimal extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Minimal')),
body: Container(
margin: const EdgeInsets.all(5.0),
alignment: Alignment.topCenter,
child: Card(
elevation: 20,
child: Container(
height: MediaQuery.of(context).size.height / 5 * 2,
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 15),
Container(
color: Colors.deepOrange,
width: double.infinity,
child: Column(
children: [
// Replace this Text with your QuestionBody
Text('asdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \nasdasd \n'),
],
),
),
SizedBox(height: 30),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [TextButton(onPressed: () {}, child: Text("Show Answer"))],
),
],
),
),
),
),
);
}
}
Now, your QuestionBody also seems to have some unnecessary stuff.
Instead of having,
return Column(
children: [
Expanded(
child: Column(
children: [
Text( //Question
Just do,
return Column(
children: [
Text( //Question
Finally remove the height restriction from the CarouselOptions since we already gave that height to the Container inside the Card.
Either give your parent widget more height or wrap your text inside a SingleChildScrollView for example to make the text scrollable

AppBar in flutter

I have designed a news application in flutter where I have an app bar with tabs following it. In the tabbarview I have a list of news. on click of the news, it will show details description and image of the news(as shown in the image). When I try to put the app bar in that file. Two app bar appears. What would the possible way sort it out?
Here is the code:
appBar: AppBar(
title: Text(""),
backgroundColor: Color(0xFF125688), //#125688 //FFFF1744
actions: <Widget>[
Container(
alignment: Alignment.topRight,
child: FlatButton(
onPressed: () {},
padding: EdgeInsets.fromLTRB(0, 10.0, 8.0, 0),
child: Text(
date,
style: TextStyle(
color: Colors.white,
),
)),
)
],
bottom: TabBar(
tabs: <Widget>[
Tab(text: "TOP-HEADLINES"),
Tab(text: "LATEST-NEWS"),
Tab(text: "SPORTS"),
Tab(text: "CRIME-NEWS"),
],
isScrollable: true,
),
),
body: TabBarView(children: [
TopHeadlines(),
LatestNews(),
Sports(),
CrimeNews(),
],
),
CODE FOR TOPHEADLINES()
class TopHeadlines extends StatefulWidget {
int index;
String value_image,value_description,value_title;
TopHeadlines({Key key,this.value_image,this.value_description,this.value_title,this.index}) : super(key:key);
#override
_topHeadlines createState() => _topHeadlines();
}
class _topHeadlines extends State<TopHeadlines> {
List<News> dataList = List();
bool _isLoading = false;
BuildContext context1;
Future<String> loadFromAssets() async {
DateTime oops = DateTime.now();
String d_date = DateFormat('ddMMyyyy').format(oops);
var url = 'https://www.example.com/json-12.json';
print(url);
var response = await http
.get('$url', headers: {"charset": "utf-8", "Accept-Charset": "utf-8"});
String utfDecode = utf8.decode(response.bodyBytes);
return utfDecode;
}
Future loadyourData() async {
setState(() {
_isLoading = true;
});
String jsonString = await loadFromAssets();
String newStr = jsonString.substring(1, jsonString.length - 1);
print(newStr);
Map newStringMap = json.decode(newStr);
var list = new List();
newStringMap.forEach((key, value) {
list.add(value);
});
for (var newsList in list) {
var news = News.fromJson(newsList);
dataList.add(news);
}
print('This is the length' + dataList.length.toString());
print(dataList[0].title);
setState(() {
_isLoading = false;
});
}
#override
void initState() {
super.initState();
loadyourData();
}
#override
Widget build(BuildContext context) {
DateTime oops = DateTime.now();
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Container(
child: _isLoading ? Center(
child: CircularProgressIndicator(),) :
ListView.builder(
itemCount: dataList.length, itemBuilder: (context, index) {
return SizedBox(
height: 130.0,
child: Card(
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: (){
// dataList;
Navigator.push(context, MaterialPageRoute(builder: (context) {
print(index);
return Newsdetail(value_image: dataList[index].image,value_description: dataList[index].description,value_title: dataList[index].title, );
}));
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(
child: Image.network(
dataList[index].image,
height: 92.5,
width: 75.0,
)),
Expanded(
child: Text(
dataList[index].title,
style: TextStyle(
//title
fontSize: 15.0, color: Colors.grey,
),
),
)
],
),
),
),
],
),
),
);
},
),
));
}
}
Remove the appBars from these views:
TopHeadlines(),
LatestNews(),
Sports(),
CrimeNews(),
Only return the Content you want to display by return a Container or the widget you want to display

Flutter display Listview when button pressed

List<ServicesMensCollection> menServicesList = []
..add(ServicesMensCollection('ihdgfstfyergjergdshf', 'janik', 10))
..add(ServicesMensCollection('ihdgfstfyergjerg', 'janik', 10))
..add(ServicesMensCollection('ihdgfstfyergjerg', 'janik', 10))
..add(ServicesMensCollection('ihdgfstfyergjergdf', 'janik', 10))
bool _value2 = false;
void _value2Changed(bool value) => setState(() => _value2 = value);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
body: new Container(
decoration: new BoxDecoration(color: const Color(0xFFEAEAEA)),
child: Padding(
padding: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
child: Column(
children: <Widget>[
servicesCategory(),
],),),)); }
Widget servicesButton() {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: () {listView();},
child: Text('Mens'),),
RaisedButton(
onPressed: () {listView();},
child: Text('Womens')),
RaisedButton(
onPressed: () {listView();},
child: Text('Childrens'),
)]); }
Widget listView(){
return ListView.builder(
itemCount: menServicesList.length,
itemBuilder: (BuildContext context, int index) {
return list(index); },);
}
Widget list(int index){
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(menServicesList[index].name),
Text(menServicesList[index].name),
Checkbox(onChanged:_value2Changed,
value: _value2,
)],),);
}}
I am implementing listview with checkbox in my project.I have 3 buttons which is created in a row.I want to display the list when the button is clicked.Here the issue is listview is not at all visible for me.I had implemented the same example in android but i don't know how to do this in flutter.
Try this. This is a sample screen which you can refer for your implementation.
In this there are 3 sample list which are being replaced to main list on selection, you can add a function which will sort the list based on selection (so no need to have multiple lists)
import 'package:flutter/material.dart';
/*
These are the sample list for demo
*/
List<ItemVO> mainList = List();
List<ItemVO> sampleMenList = [
ItemVO("1", "Mens 1"),
ItemVO("2", "Mens 2"),
ItemVO("3", "Mens 3")
];
List<ItemVO> sampleWomenList = [
ItemVO("1", "Women 1"),
ItemVO("2", "Women 2"),
ItemVO("3", "Women 3")
];
List<ItemVO> sampleKidsList = [
ItemVO("1", "kids 1"),
ItemVO("2", "kids 2"),
ItemVO("3", "kids 3")
];
class TestScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _TestScreen();
}
}
class _TestScreen extends State<TestScreen> {
#override
void initState() {
super.initState();
mainList.addAll(sampleMenList);
}
#override
Widget build(BuildContext context) {
return Material(
child: Stack(
children: <Widget>[
ListView.builder(
itemBuilder: (BuildContext context, index) {
return getCard(index);
},
itemCount: mainList.length,
),
Container(
margin: EdgeInsets.only(bottom: 20),
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
mainList.clear();
setState(() {
mainList.addAll(sampleMenList);
});
},
heroTag: "btn1",
child: Text("Mens"),
),
FloatingActionButton(
onPressed: () {
mainList.clear();
setState(() {
mainList.addAll(sampleWomenList);
});
},
heroTag: "btn2",
child: Text("Women"),
),
FloatingActionButton(
onPressed: () {
mainList.clear();
setState(() {
mainList.addAll(sampleKidsList);
});
},
heroTag: "btn3",
child: Text("Kids"),
)
],
),
),
],
),
);
}
/*
Get the card item for a list
*/
getCard(int position) {
ItemVO model = mainList[position];
return Card(
child: Container(
height: 50,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"ID:: "+model._id,
style: TextStyle(fontSize: 18, color: Colors.black),
),
Padding(padding: EdgeInsets.only(left: 5,right: 5)),
Text(
"Name:: "+model._name,
style: TextStyle(fontSize: 18, color: Colors.black),
)
],
),
),
margin: EdgeInsets.all(10),
);
}
}
/*
Custom model
i.e. for itemList
*/
class ItemVO {
String _id, _name;
String get id => _id;
set id(String value) {
_id = value;
}
get name => _name;
set name(value) {
_name = value;
}
ItemVO(this._id, this._name);
}
In your code you didn't added ListView in widget, so it will not show any list, so try adding ListView in widget and then change the list data and try it.
I think You have 2 choices on how to tackle your problem.
Preload the listViews and set their visibility to gone / invisible
Try to play around with the code from this blog