Related
I need some help when implementing the search bar funcionality in Flutter.
I am implementing flappy_search_bar: https://pub.dev/packages/flappy_search_bar
However, it does return any value when I try to search something.
Is there anything I am missing? Seems trivial this kind of implementations, just query some list and include the results in other list but I cannot figure out the way to do it.
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
TextEditingController textController = TextEditingController();
Future<List<dynamic>> search(String search) async {
await Future.delayed(Duration(seconds: 2));
List<dynamic> dogs = BreedList.where((dog) => dog['breed'].contains(search)).toList();
return dogs;
// return List(search.length, (int index) {
// return DogClass(breed: "$search $index");
// });
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(children: [
Container(
margin: const EdgeInsets.only(top: 60, bottom: 15),
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: Container(
width: MediaQuery.of(context).size.width -
(MediaQuery.of(context).size.width / 3.5),
height: 80,
child: SearchBar<dynamic>(
searchBarStyle: SearchBarStyle(borderRadius: BorderRadius.circular(20)),
onSearch: search,
cancellationWidget: Text('Cancel'),
emptyWidget: SizedBox.shrink(),
shrinkWrap:true,
onItemFound: (dynamic dogs, int index) {
return Container(
child: ListTile(
title: Text(dogs.breed.toString())
),
);
}),
//child: const Icon(Icons.search, color: Colors.white),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(Dimensions.radius20),
color: Colors.white),
),
)
],
),
),
//wrapping with this widgets the scroll problem is solved in list
const Expanded(
child: SingleChildScrollView(
child: BookPageBody(),
)),
]));
}
}
I'm quite inexperienced with flutter and have created this script.
When you tap on the red container you create a Row of buttons,
I would like when I click on a button in the Row -> the text of the blue container becomes the same as the text contained in the tapped button
Anyone know how I can do?
Thank you :)
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Chat(),
);
}
}
class Chat extends StatefulWidget {
const Chat({Key? key}) : super(key: key);
#override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
String text = 'Henlo i am Gabriele!';
List<Container> OutputList = [];
void tool(String text) async {
List ListText = text.split(' ');
for (var i in ListText) {
OutputList.add(
Container(
child: GestureDetector(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(i),
),
),
),
),
),
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
GestureDetector(
onTap: () {
setState(() {
tool(text);
print(OutputList);
});
},
child: Container(
width: 150.0,
height: 50.0,
color: Colors.red,
child: Center(child: Text('START ->')),
),
),
SizedBox(height: 50.0),
Row(
children: OutputList,
),
SizedBox(height: 50.0),
Container(
color: Colors.blue,
width: 200.0,
height: 50.0,
child: Text(''),
),
],
),
),
);
}
}
Yes you can add a few line of code check here i try to solve.
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Chat(),
);
}
}
class Chat extends StatefulWidget {
const Chat({Key? key}) : super(key: key);
#override
_ChatState createState() => _ChatState();
}
class _ChatState extends State<Chat> {
String text = 'Henlo i am Gabriele!';
//step 1 create variable
String newGeneratedText = "";
List<Container> OutputList = [];
void tool(String text) async {
List ListText = text.split(' ');
for (var i in ListText) {
OutputList.add(
Container(
child: GestureDetector(
onTap: () {
//add logic here to concatinate values
setState(() {
newGeneratedText = newGeneratedText + " " + i;//added " " for one space
});
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(i),
),
),
),
),
),
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
GestureDetector(
onTap: () {
setState(() {
tool(text);
print(OutputList);
});
},
child: Container(
width: 150.0,
height: 50.0,
color: Colors.red,
child: Center(child: Text('START ->')),
),
),
SizedBox(height: 50.0),
Wrap( // added for fixing more values and solve overflow exceptions error
children: OutputList,
),
SizedBox(height: 50.0),
Container(
color: Colors.blue,
width: 200.0,
height: 50.0,
child: Text(newGeneratedText), //final print values
),
],
),
),
);
}
}
I have a code that outputs fields for the user to fill in (code below. I have shortened it here for ease of reading.). I would like to add one more field to this form, which can upload various photos from the phone gallery (preferably with the ability to delete a photo if the user made a mistake when choosing). How can I implement this?
class FormForDeviceService extends StatefulWidget {
#override
State<StatefulWidget> createState() => _FormForDeviceService();
}
class _FormForDeviceService extends State {
final _formKey = GlobalKey<FormState>();
Widget build(BuildContext context) {
return Container(padding: const EdgeInsets.all(10.0),
child: Form(key: _formKey, child: Column(children: <Widget>[
new Text('What is problem', style: TextStyle(fontSize: 20.0),),
new TextFormField(decoration: const InputDecoration(
hintText: 'Describe the problem',),
ElevatedButton(
onPressed: (){if(_formKey.currentState!.validate()) {_formKey.currentState?.reset();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Form completed successfully', style: TextStyle(color: Colors.black),),
backgroundColor: Colors.yellow,));
}},
child: const Text('Submit', style: TextStyle(color: Colors.black),),
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.yellow)),)
],)));
}
}
Page at the moment
my expectations (or something similar)
An another approach is here-
(I have made a separate widget to handle all these things and you just need to attach it in any scrollable widget)
my code is as follow:
Main Code with that custom widget:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_memory/image_picker_widget.dart';
void main() {
runApp(GetMaterialApp(title: 'Flutter', home: Flutter()));
}
class Flutter extends StatefulWidget {
const Flutter({Key? key}) : super(key: key);
#override
State<Flutter> createState() => _FlutterState();
}
class _FlutterState extends State<Flutter> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter'),
centerTitle: true,
),
body: Center(
child: Column(
children: [
//This is the widget I am talking about
ImagePickerWidget()
],
),
),
);
}
}
And now the code for that custom widget:
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class ImagePickerWidget extends StatefulWidget {
const ImagePickerWidget({Key? key}) : super(key: key);
#override
State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
}
class _ImagePickerWidgetState extends State<ImagePickerWidget> {
late List<CustomImage> images;
late double size;
late ImagePicker imagePicker;
late int idGenerator;
#override
void initState() {
images = [];
size = 100;
idGenerator = 0;
imagePicker = ImagePicker();
}
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
pickImage();
},
child: Text('Pick Image')),
Wrap(
children: images.map((image) {
return Stack(children: [
SizedBox(
height: size,
width: size,
child: ClipRRect(
child: Image.memory(
image.imageData,
fit: BoxFit.fill,
))),
Positioned(
right: 4,
top: 4,
child: InkWell(
onTap: () {
//delete image
images.removeWhere(
(element) => element.imageData == image.imageData);
setState(() {});
},
child: Container(
color: Colors.white, child: Icon(Icons.clear))))
]);
}).toList())
],
);
}
Future<void> pickImage() async {
// XFile? image = await imagePicker.pickImage(source: ImageSource.camera);
XFile? image = await imagePicker.pickImage(source: ImageSource.gallery);
if (image != null) {
Uint8List imageData = await image.readAsBytes();
int id = idGenerator++;
images.add(CustomImage(imageData: imageData, id: id));
setState(() {});
}
}
}
class CustomImage {
Uint8List imageData;
int id;
CustomImage({required this.imageData, required this.id});
}
You can customize the widget in order to use the images list of that widget or you can simply pass the callbacks for that.
we store file here your can use path(string) instead file
List<File> myfile = [];
image_picker package used here to pick image
image_picker: ^0.8.4+10
call like this in your code
Container(
height: 200,
padding: EdgeInsets.all(4),
child: PickPhoto())
Pick photo widget
class PickPhoto extends StatefulWidget {
const PickPhoto({Key? key}) : super(key: key);
#override
State<PickPhoto> createState() => _PickPhotoState();
}
class _PickPhotoState extends State<PickPhoto> {
#override
Widget build(BuildContext context) {
return Material(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
width: 45,
height: 45,
child: ElevatedButton(
onPressed: () async {
var file =
await picker?.pickImage(source: ImageSource.gallery);
setState(() {
myfile.add(File(file!.path));
});
},
child: Text("Add Photo"))),
),
Expanded(
child: ListView.builder(
// physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: myfile.length,
itemBuilder: (context, index) => Container(
padding: EdgeInsets.all(4),
height: 175,
width: 125,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Align(
alignment: Alignment.topRight,
child: IconButton(
onPressed: () {
setState(() {
myfile.removeAt(index);
});
},
icon: Icon(Icons.close),
),
),
Expanded(
child: Container(
child: myfile[index] == null
? Text("")
: Image.file(
myfile[index],
fit: BoxFit.fill,
),
),
),
],
),
)),
)
],
),
);
}
}
SampleCode
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
ImagePicker? picker;
void main() {
WidgetsFlutterBinding.ensureInitialized();
picker = ImagePicker();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MySQL Test',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [FormForDeviceService()],
),
);
}
}
List<File> myfile = [];
List<int> f = [1, 2, 3, 4, 5];
List<bool> fs = [false, false, false, true, true];
class FormForDeviceService extends StatefulWidget {
#override
State<StatefulWidget> createState() => _FormForDeviceService();
}
class _FormForDeviceService extends State {
final _formKey = GlobalKey<FormState>();
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(10.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
new Text(
'What is problem',
style: TextStyle(fontSize: 20.0),
),
new TextFormField(
decoration: const InputDecoration(
hintText: 'Describe the problem',
),
),
Container(
height: 200,
padding: EdgeInsets.all(4),
child: PickPhoto()),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState?.reset();
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
'Form completed successfully',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.yellow,
));
}
},
child: const Text(
'Submit',
style: TextStyle(color: Colors.black),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.yellow)),
)
],
)));
}
}
class PickPhoto extends StatefulWidget {
const PickPhoto({Key? key}) : super(key: key);
#override
State<PickPhoto> createState() => _PickPhotoState();
}
class _PickPhotoState extends State<PickPhoto> {
#override
Widget build(BuildContext context) {
return Material(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Container(
width: 45,
height: 45,
child: ElevatedButton(
onPressed: () async {
var file =
await picker?.pickImage(source: ImageSource.gallery);
setState(() {
myfile.add(File(file!.path));
});
},
child: Text("Add Photo"))),
),
Expanded(
child: ListView.builder(
// physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: myfile.length,
itemBuilder: (context, index) => Container(
padding: EdgeInsets.all(4),
height: 175,
width: 125,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Align(
alignment: Alignment.topRight,
child: IconButton(
onPressed: () {
setState(() {
myfile.removeAt(index);
});
},
icon: Icon(Icons.close),
),
),
Expanded(
child: Container(
child: myfile[index] == null
? Text("")
: Image.file(
myfile[index],
fit: BoxFit.fill,
),
),
),
],
),
)),
)
],
),
);
}
}
I have list of products in bottom sheet, when I choose any product I want to parent's widget to add it, unfortunately my product adds only after hot reload, or when I create a new route from bottom sheet to parent's widget, how can I solve this problem, any ideas? Here is the part of the bottom sheet code
class IceBottomSheet extends StatefulWidget {
const IceBottomSheet({Key? key}) : super(key: key);
#override
_IceBottomSheetState createState() => _IceBottomSheetState();
}
class _IceBottomSheetState extends State<IceBottomSheet> {
final _model = ProductWidgetsModel();
#override
Widget build(BuildContext context) {
List<Widget> productWidgetList = [];
products.forEach((product) =>
productWidgetList.add(SingleProductWidget(product: product)));
return Provider(
model: _model,
child: Expanded(
child: GridView.count(
crossAxisSpacing: 10,
mainAxisSpacing: 16,
shrinkWrap: true,
crossAxisCount: 2, children: productWidgetList),
),
);
}
}
class SingleProductWidget extends StatefulWidget {
final Product product;
const SingleProductWidget({Key? key, required this.product})
: super(key: key);
#override
State<SingleProductWidget> createState() => _SingleProductWidgetState();
}
class _SingleProductWidgetState extends State<SingleProductWidget> {
#override
Widget build(BuildContext context) {
final model = Provider.of(context)?.model;
return Padding(
padding: const EdgeInsets.all(5.0),
child:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(
width: double.infinity,
height: 100,
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: widget.product.image,
),
shape: BoxShape.circle,
border: Border.all(
color: model?.idSelected == widget.product.id
? Colors.yellow
: Colors.grey,
width: 5.0,
style: BorderStyle.solid,
),
),
child: GestureDetector(
onTap: () {
model?.idSelected = widget.product.id;
// Route route =
// MaterialPageRoute(builder: (context) => BerryPage(context,));
// Navigator.push(context, route);
if(model?.idSelected == 1){
menuRow.removeAt(2);
Navigator.pop(context);
choice.insert(2, Adds(id: 102, name: 'Холодок', img: 'https://autogear.ru/misc/i/gallery/73434/2759438.jpg'));
}
}),
),
),
And here is the part of parent's widget code, it is inside GestureDetector
else if (index == 2){
setState(() {
});
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext builder) {
return Container(
height: 250,
child: Column(
children: [
SizedBox(
height: 10,
),Row(
children: [
Padding(
padding: EdgeInsets.only(left: MediaQuery.of(context).size.width*0.25 + MediaQuery.of(context).size.width *0.12),
child: Text(
'Холодок',
style: TextStyle(
fontFamily: 'Newfont',
fontSize: 22,
),
),
),
SizedBox(width: MediaQuery.of(context).size.width*0.25,),
IconButton(icon: Icon(Icons.close),onPressed: (){Navigator.pop(context);},)
],
),
Divider(),
IceBottomSheet(),
],
));
},
);
So when you open the BottomSheet you have to add await before it, so when you call Navigator.pop(context, data_you_want_to_pass_to_parent) it will wait for some data to be returned.
final data = await openBottomSheet();
inside the bottomSheet when you want to close, just pass the the desired data as so
Navigator.pop(context, data_you_want_to_pass_to_parent);
I want to have a scrollable list on my home screen. I tried to implement my Listviewbuilder called Cardslist() into the home screen, but I always get this exception thrown: RenderFlex children have non-zero flex, incoming height constraints are unbounded. Heres the code for the home screen:
import 'package:biminda_app/Components/cards_list.dart';
import 'package:biminda_app/Components/real_new_finished_card.dart';
import 'package:flutter/material.dart';
import 'package:biminda_app/Components/custom_Buttons.dart';
import 'package:biminda_app/Components/constants.dart';
import 'package:flutter/rendering.dart';
import 'package:biminda_app/Screens/new_card_screen1.dart';
import 'package:biminda_app/Screens/settings.dart';
import 'package:biminda_app/Components/card_data.dart';
import 'package:biminda_app/Components/cards_list.dart';
class HomeScreen extends StatefulWidget {
static const String id = 'home_screen';
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String individualsName;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(
20,
40,
20,
0,
),
child: TextField(
style: TextStyle(
color: Colors.black,
),
decoration: kTextFieldInputDecoration,
onChanged: (value) {
individualsName = value;
// TODO: Der Input muss das Individum in der Liste
// TODO: erkennen und anzeigen
},
),
),
//TODO HIER
Expanded(
child: Column(
children: <Widget>[
CardsList(),
],
)),
Center(
child: Container(
child: MainButton(
functionality: 'New',
onPressed: () {
Navigator.pushNamed(context, NewCard.id);
}),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SideButton(
functionality: 'Settings',
onPressed: () {
Navigator.pushNamed(context, Settings.id);
}),
SideButton(
functionality: 'Calendar',
onPressed: () {
Navigator.pushNamed(context, Settings.id);
}),
],
),
),
],
),
);
}
}
And here's the code for Cardslist():
class CardsList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Consumer<CardData>(builder: (context, cardData, child) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
final card = cardData.cards[index];
return FinalCardCreation(
finalname: card.cname,
finalbirthday: card.cbirthday,
);
});
});
}
}
The code for the created card FinalCardCreation():
class CardFinish extends StatefulWidget {
#override
CardFinishState createState() => CardFinishState();
}
class CardFinishState extends State<CardFinish> {
#override
Widget build(BuildContext context) {
return SizedBox(
height:
MediaQuery.of(context).size.height * 0.5, //<-- set height of the card
child: FinalCardCreation(),
);
}
}
class FinalCardCreation extends StatelessWidget {
String finalname;
String finalbirthday;
FinalCardCreation({
Key key,
#required this.finalname,
#required this.finalbirthday,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
color: Color(0xFFef9a9a),
margin: EdgeInsets.all(2),
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Column(
children: <Widget>[
SizedBox(height: 8),
Expanded(
child: FinalCardContent(
name: finalname,
birthday: finalbirthday,
),
)
],
),
);
}
}
class FinalCardContent extends StatelessWidget {
String name;
String birthday;
FinalCardContent({Key key, #required this.name, #required this.birthday})
: super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$name',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 50.0,
color: Colors.black,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$birthday',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 50.0,
color: Colors.black,
),
),
),
],
),
);
}
}
I tried to wrap my Cardslist() multiple ways but I always got this exception. Thank you for your time and answer.
Column is a widget that can grow infinitely in height. It does not impose any height constraints to its children. Expanded are a smart way to include ListViews in Column since they fit all the possible space of the Column on screen, but impose a constraint to their children.
You can either remove the Column wrapping your CardList or, if you really need that Column for other stuff later, try wrapping CardList in another Expanded.