How to create searchable ListView in popup flutter? - flutter

How it possible to create a listView with Search function in a popup flutter?
I call the listView using API laravel. I want data in the popup will be able to be select or user can search it in popup and then select it. As user select the data and click submit data will be able to post in database.
below is the function that I used to call the data
List _listViewData = List();
#override
initState() {
super.initState();
// when loading your widget for the first time, loads country from db
_countryA();
}
void _countryA() async {
// gets data from db
final countryA = await CallApi().getData('countries');
var resBody = json.decode(countryA.body);
setState(() {
// converts db row data to List<String>, updating state
_listViewData = resBody;
});
}
I just know how to call the data of country using dropdown in an alert button.
I dont want it to be display in dropdown but instead in a list in flutter.
below is function that I called in the dropdown
void _showDialog() {
// flutter defined function
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Select Country", textAlign:TextAlign.center,),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
content: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: DropdownButton(
items: _listViewData.map((item) {
return new DropdownMenuItem(
child: new Text(item['country']),
value: item['id'].toString(),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_mySelectionAr = newVal;
});
},
value: _mySelectionAr,
),
),
],
),
);
},
);
}
So, the conclusion is that I want it to be display in listview in the flutter popup not a dropdown in a popup. I just cannot figure out how to call all the list data of country in a list in popup include with the search function.

Edit
The most simple way is after folk this github.
You can update file https://github.com/figengungor/country_pickers/blob/master/lib/countries.dart directly
or in
https://github.com/figengungor/country_pickers/blob/master/lib/country_picker_dialog.dart at line 113 change _allCountries to what you need, you can hard code or use your own ready made api but need to follow owner's Country Class.
You can use https://pub.dev/packages/country_pickers directly or reference source code and build your own
for Counties you need does not exist. you can fork this github project and modify directly https://github.com/figengungor/country_pickers/blob/master/lib/countries.dart
It support features you need can use in showDialog and inside is a ListView
also provide search by phone and name
full example code
import 'package:country_pickers/country.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:country_pickers/country_pickers.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Country Pickers Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (context) => DemoPage(),
},
);
}
}
class DemoPage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<DemoPage> {
Country _selectedDialogCountry =
CountryPickerUtils.getCountryByPhoneCode('90');
Country _selectedFilteredDialogCountry =
CountryPickerUtils.getCountryByPhoneCode('90');
Country _selectedCupertinoCountry =
CountryPickerUtils.getCountryByIsoCode('tr');
Country _selectedFilteredCupertinoCountry =
CountryPickerUtils.getCountryByIsoCode('DE');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Country Pickers Demo'),
),
body: ListView(
padding: EdgeInsets.all(8.0),
children: <Widget>[
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('CountryPickerDropdown'),
ListTile(title: _buildCountryPickerDropdown(false)),
],
),
),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('CountryPickerDropdown (filtered)'),
ListTile(title: _buildCountryPickerDropdown(true)),
],
),
),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('CountryPickerDialog'),
ListTile(
onTap: _openCountryPickerDialog,
title: _buildDialogItem(_selectedDialogCountry),
),
],
),
),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('CountryPickerDialog (filtered)'),
ListTile(
onTap: _openFilteredCountryPickerDialog,
title: _buildDialogItem(_selectedFilteredDialogCountry),
),
],
),
),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('CountryPickerCupertino'),
ListTile(
title: _buildCupertinoSelectedItem(_selectedCupertinoCountry),
onTap: _openCupertinoCountryPicker,
),
],
),
),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('CountryPickerCupertino (filtered)'),
ListTile(
title: _buildCupertinoSelectedItem(
_selectedFilteredCupertinoCountry),
onTap: _openFilteredCupertinoCountryPicker,
),
],
),
),
],
),
);
}
_buildCountryPickerDropdown(bool filtered) => Row(
children: <Widget>[
CountryPickerDropdown(
initialValue: 'AR',
itemBuilder: _buildDropdownItem,
itemFilter: filtered
? (c) => ['AR', 'DE', 'GB', 'CN'].contains(c.isoCode)
: null,
onValuePicked: (Country country) {
print("${country.name}");
},
),
SizedBox(
width: 8.0,
),
Expanded(
child: TextField(
decoration: InputDecoration(labelText: "Phone"),
),
)
],
);
Widget _buildDropdownItem(Country country) => Container(
child: Row(
children: <Widget>[
CountryPickerUtils.getDefaultFlagImage(country),
SizedBox(
width: 8.0,
),
Text("+${country.phoneCode}(${country.isoCode})"),
],
),
);
Widget _buildDialogItem(Country country) => Row(
children: <Widget>[
CountryPickerUtils.getDefaultFlagImage(country),
SizedBox(width: 8.0),
Text("+${country.phoneCode}"),
SizedBox(width: 8.0),
Flexible(child: Text(country.name))
],
);
void _openCountryPickerDialog() => showDialog(
context: context,
builder: (context) => Theme(
data: Theme.of(context).copyWith(primaryColor: Colors.pink),
child: CountryPickerDialog(
titlePadding: EdgeInsets.all(8.0),
searchCursorColor: Colors.pinkAccent,
searchInputDecoration: InputDecoration(hintText: 'Search...'),
isSearchable: true,
title: Text('Select your phone code'),
onValuePicked: (Country country) =>
setState(() => _selectedDialogCountry = country),
itemBuilder: _buildDialogItem)),
);
void _openFilteredCountryPickerDialog() => showDialog(
context: context,
builder: (context) => Theme(
data: Theme.of(context).copyWith(primaryColor: Colors.pink),
child: CountryPickerDialog(
titlePadding: EdgeInsets.all(8.0),
searchCursorColor: Colors.pinkAccent,
searchInputDecoration: InputDecoration(hintText: 'Search...'),
isSearchable: true,
title: Text('Select your phone code'),
onValuePicked: (Country country) =>
setState(() => _selectedFilteredDialogCountry = country),
itemFilter: (c) => ['AR', 'DE', 'GB', 'CN'].contains(c.isoCode),
itemBuilder: _buildDialogItem)),
);
void _openCupertinoCountryPicker() => showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) {
return CountryPickerCupertino(
backgroundColor: Colors.black,
itemBuilder: _buildCupertinoItem,
pickerSheetHeight: 300.0,
pickerItemHeight: 75,
initialCountry: _selectedCupertinoCountry,
onValuePicked: (Country country) =>
setState(() => _selectedCupertinoCountry = country),
);
});
void _openFilteredCupertinoCountryPicker() => showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) {
return CountryPickerCupertino(
backgroundColor: Colors.white,
pickerSheetHeight: 200.0,
initialCountry: _selectedFilteredCupertinoCountry,
onValuePicked: (Country country) =>
setState(() => _selectedFilteredCupertinoCountry = country),
itemFilter: (c) => ['AR', 'DE', 'GB', 'CN'].contains(c.isoCode),
);
});
Widget _buildCupertinoSelectedItem(Country country) {
return Row(
children: <Widget>[
CountryPickerUtils.getDefaultFlagImage(country),
SizedBox(width: 8.0),
Text("+${country.phoneCode}"),
SizedBox(width: 8.0),
Flexible(child: Text(country.name))
],
);
}
Widget _buildCupertinoItem(Country country) {
return DefaultTextStyle(
style:
const TextStyle(
color: CupertinoColors.white,
fontSize: 16.0,
),
child: Row(
children: <Widget>[
SizedBox(width: 8.0),
CountryPickerUtils.getDefaultFlagImage(country),
SizedBox(width: 8.0),
Text("+${country.phoneCode}"),
SizedBox(width: 8.0),
Flexible(child: Text(country.name))
],
),
);
}
}

Related

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)

FilterChip inside ModalBottomSheet

Hi I'm a beginner flutter developer, I have a StatefulWidget widget and a ListView here is a button to display ModalBottomSheet
The ModalBottomSheet has a FilterChip widget that allows the user to apply some filters to the ListView, but I would like to keep the FilterChip state even after the user pop the ModalBottomSheet.
class AvailableMeals extends StatefulWidget {
static const routeName = 'available-meals';
#override
_AvailableMealsState createState() => _DietAvailableMealsState();
}
class _DietAvailableMealsState extends State<DietAvailableMeals> {
bool status = false;
#override
Widget build(BuildContext context) {
buildFilterBox() {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(
'SelectFilter',
style: TextStyle(fontSize: 10.sp),
),
),
Container(
child: Wrap(
spacing: 25,
children: [
FilterChip(
selected: status,
label: Text('Vegan'),
onSelected: (value) {
setState(() {
status = value;
});
})
],
),
),
],
),
);
}
return Scaffold(
appBar: AppBar(
title: Text('Meals'),
actions: [
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return buildFilterBox();
});
},
icon: Icon(Icons.search))
],
),
body: Container(child : Column(children: [
Expanded(
child: ListView.builder(
itemBuilder: (ctx, index) => ChangeNotifierProvider.value(
value: _customList[index], child: MealCard(_customList[index])),
itemCount: _customList.length,
));
] ))
}

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

Passing value to previous widget

I have simple form , inside it have CircularAvatar when this is pressed show ModalBottomSheet to choose between take picture from gallery or camera. To make my widget more compact , i separated it to some file.
FormDosenScreen (It's main screen)
DosenImagePicker (It's only CircularAvatar)
ModalBottomSheetPickImage (It's to show ModalBottomSheet)
The problem is , i don't know how to passing value from ModalBottomSheetPickImage to FormDosenScreen. Because value from ModalBottomSheetPickImage i will use to insert operation.
I only success passing from third Widget to second Widget , but when i passing again from second Widget to first widget the value is null, and i think the problem is passing from Second widget to first widget.
How can i passing from third Widget to first Widget ?
First Widget
class FormDosenScreen extends StatefulWidget {
static const routeNamed = '/formdosen-screen';
#override
_FormDosenScreenState createState() => _FormDosenScreenState();
}
class _FormDosenScreenState extends State<FormDosenScreen> {
String selectedFile;
#override
Widget build(BuildContext context) {
final detectKeyboardOpen = MediaQuery.of(context).viewInsets.bottom;
print('trigger');
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Tambah Dosen'),
actions: <Widget>[
PopupMenuButton(
itemBuilder: (_) => [
PopupMenuItem(
child: Text('Tambah Pelajaran'),
value: 'add_pelajaran',
),
],
onSelected: (String value) {
switch (value) {
case 'add_pelajaran':
Navigator.of(context).pushNamed(FormPelajaranScreen.routeNamed);
break;
default:
}
},
)
],
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(height: 20),
DosenImagePicker(onPickedImage: (file) => selectedFile = file),
SizedBox(height: 20),
Card(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormFieldCustom(
onSaved: (value) {},
labelText: 'Nama Dosen',
),
SizedBox(height: 20),
TextFormFieldCustom(
onSaved: (value) {},
prefixIcon: Icon(Icons.email),
labelText: 'Email Dosen',
keyboardType: TextInputType.emailAddress,
),
SizedBox(height: 20),
TextFormFieldCustom(
onSaved: (value) {},
keyboardType: TextInputType.number,
inputFormatter: [
// InputNumberFormat(),
WhitelistingTextInputFormatter.digitsOnly
],
prefixIcon: Icon(Icons.local_phone),
labelText: 'Telepon Dosen',
),
],
),
),
),
SizedBox(height: kToolbarHeight),
],
),
),
Positioned(
child: Visibility(
visible: detectKeyboardOpen > 0 ? false : true,
child: RaisedButton(
onPressed: () {
print(selectedFile);
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: colorPallete.primaryColor,
child: Text(
'SIMPAN',
style: TextStyle(fontWeight: FontWeight.bold, fontFamily: AppConfig.headerFont),
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
textTheme: ButtonTextTheme.primary,
),
),
bottom: kToolbarHeight / 2,
left: sizes.width(context) / 15,
right: sizes.width(context) / 15,
)
],
),
);
}
}
Second Widget
class DosenImagePicker extends StatefulWidget {
final Function(String file) onPickedImage;
DosenImagePicker({#required this.onPickedImage});
#override
DosenImagePickerState createState() => DosenImagePickerState();
}
class DosenImagePickerState extends State<DosenImagePicker> {
String selectedImage;
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
child: InkWell(
onTap: () async {
await showModalBottomSheet(
context: context,
builder: (context) => ModalBottomSheetPickImage(
onPickedImage: (file) {
setState(() {
selectedImage = file;
widget.onPickedImage(selectedImage);
print('Hellooo dosen image picker $selectedImage');
});
},
),
);
},
child: CircleAvatar(
foregroundColor: colorPallete.black,
backgroundImage: selectedImage == null ? null : MemoryImage(base64.decode(selectedImage)),
radius: sizes.width(context) / 6,
backgroundColor: colorPallete.accentColor,
child: selectedImage == null ? Text('Pilih Gambar') : SizedBox(),
),
),
);
}
}
Third Widget
class ModalBottomSheetPickImage extends StatelessWidget {
final Function(String file) onPickedImage;
ModalBottomSheetPickImage({#required this.onPickedImage});
#override
Widget build(BuildContext context) {
return SizedBox(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Wrap(
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
InkWell(
onTap: () async {
final String resultBase64 =
await commonFunction.pickImage(quality: 80, returnFile: ReturnFile.BASE64);
onPickedImage(resultBase64);
},
child: CircleAvatar(
foregroundColor: colorPallete.white,
backgroundColor: colorPallete.green,
child: Icon(Icons.camera_alt),
),
),
InkWell(
onTap: () async {
final String resultBase64 =
await commonFunction.pickImage(returnFile: ReturnFile.BASE64, isCamera: false);
onPickedImage(resultBase64);
},
child: CircleAvatar(
foregroundColor: colorPallete.white,
backgroundColor: colorPallete.blue,
child: Icon(Icons.photo_library),
),
),
],
),
),
);
}
}
The cleanest and easiest way to do this is through Provider. It is one of the state management solutions you can use to pass values around the app as well as rebuild only the widgets that changed. (Ex: When the value of the Text widget changes). Here is how you can use Provider in your scenario:
This is how your model should look like:
class ImageModel extends ChangeNotifier {
String _base64Image;
get base64Image => _base64Image;
set base64Image(String base64Image) {
_base64Image = base64Image;
notifyListeners();
}
}
Don't forget to add getters and setters so that you can use notifyListeners() if you have any ui that depends on it.
Here is how you can access the values of ImageModel in your UI:
final model=Provider.of<ImageModel>(context,listen:false);
String image=model.base64Image; //get data
model.base64Image=resultBase64; //set your image data after you used ImagePicker
Here is how you can display your data in a Text Widget (Ideally, you should use Selector instead of Consumer so that the widget only rebuilds if the value its listening to changes):
#override
Widget build(BuildContext context) {
//other widgets
Selector<ImageModel, String>(
selector: (_, model) => model.base64Image,
builder: (_, image, __) {
return Text(image);
},
);
}
)
}
You could achieve this easily. If you are using Blocs.

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