Gesture detection in Flutter TextSpan - gesture

Is there a way to detect which word in the TextSpan was touched by the user?
This paragraph is here to get round the stack overflow robot that is insisting that I write more stuff :)

You can improve by yourself
import 'package:flutter/gestures.dart';
...
new RichText(
text: new TextSpan(text: 'Non touchable. ', children: [
new TextSpan(
text: 'Tap here.',
recognizer: new TapGestureRecognizer()..onTap = () => print('Tap Here onTap'),
)
]),
);

Screenshot:
Use recognizer property of TextSpan which allows almost all types of event.
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'Single tap',
style: TextStyle(color: Colors.red[300]),
recognizer: TapGestureRecognizer()..onTap = () {
// Single tapped.
},
),
TextSpan(
text: ' Double tap',
style: TextStyle(color: Colors.green[300]),
recognizer: DoubleTapGestureRecognizer()..onDoubleTap = () {
// Double tapped.
}
),
TextSpan(
text: ' Long press',
style: TextStyle(color: Colors.blue[300]),
recognizer: LongPressGestureRecognizer()..onLongPress = () {
// Long Pressed.
},
),
],
),
)

Iterate over the string to get an array of strings, create separate text span for each and add the gesture recognizer
List<TextSpan> createTextSpans(){
final string = """Text seems like it should be so simple, but it really isn't.""";
final arrayStrings = string.split(" ");
List<TextSpan> arrayOfTextSpan = [];
for (int index = 0; index < arrayStrings.length; index++){
final text = arrayStrings[index] + " ";
final span = TextSpan(
text: text,
recognizer: TapGestureRecognizer()..onTap = () => print("The word touched is $text")
);
arrayOfTextSpan.add(span);
}
return arrayOfTextSpan;

late TapGestureRecognizer tapGestureRecognizer;
#override
void initState() {
super.initState();
tapGestureRecognizer = TapGestureRecognizer()
..onTap = () {
widget.onProfileDetails();
};
}
#override
void dispose() {
super.dispose();
tapGestureRecognizer.dispose();
}
#override
Widget build(BuildContext context) {
return Flexible(
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: widget.notificationObject.name,
style: TextStyle(
fontSize: width * 0.044,
fontFamily: 'HelveticaNeueRegular',
color: Theme.of(context).primaryColor,
),
recognizer: tapGestureRecognizer,
),
],
),
),
);
}

RichText(
text: TextSpan(
text: "If you don't have a account ",
style: TextStyle(
fontFamily: AppFonts.phagsPa,
fontSize: 16,
color: AppColors.white,
),
children: [
TextSpan(
text: "sign-up".toUpperCase(),
style: TextStyle(
color: AppColors.btnBgColor,
fontWeight: FontWeight.bold,
),
recognizer: TapGestureRecognizer()
..onTap = () {
Get.to(() => MerchantSignupPage());
},
),
TextSpan(text: " here")
],
),
textAlign: TextAlign.center,
),

Related

How to display my text on multiple lines?

I'm trying to figuring out how I can show my text on multiple lines. Here's my code:
title: Row(
children: [
Text(
_snapshot.data['username'],
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w700),
),
SizedBox(width: 5.0),
Text(
"${comment.data()['comment']}",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w500),
)
],
),
But when the text is too long I get this error:
When I wrapped second text with expanded it looks like that
I want something like this
I think you can try use a RichText, see this code:
RichText(
text: TextSpan(
text: 'Title ', // _snapshot.data['username']
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
children: <TextSpan>[
TextSpan(//"${comment.data()['comment']}"
text: 'this is a very long text text text'
'text text text text text text text text text text'
'text text text text text text text text text',
style: TextStyle(
fontWeight: FontWeight.normal,
),
)
],
),
),
Using "maxLines" (Text widget) property should work, It should wrap the text.
This looks like a use-case for RichText because the only difference between the two Text widgets is the font-weight.
You can update your code to use this instead and add as much space as you want before ${comment.data()['comment']}:
title: RichText(
text: TextSpan(
title: _snapshot.data['username'],
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w700),
children: <TextSpan>[
TextSpan(text: " ${comment.data()['comment']}", style: TextStyle(fontWeight: FontWeight.w500)),
],
),
)
I use this way.
https://i.stack.imgur.com/6WrQi.png
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: ListView(
children: const <Widget>[
Card(
child: ListTile(
leading: FlutterLogo(size: 56.0),
title: Text('Two-line ListTile Two-line ListTile Two-line ListTile'),
subtitle: Text('Here is a second line'),
),
),
Card(
child: ListTile(
leading: FlutterLogo(size: 72.0),
title: Text('Three-line ListTile'),
subtitle: Text(
'A sufficiently long subtitle warrants three lines.'
),
isThreeLine: true,
),
),
],
),
),
);
}
}
Just add your Text widget inside a Sizedbox or Container with fixed width, and it will flow into multiline.
SizedBox(
width: 200,
child: Text("Some long text",
maxLines: 3,
style: const TextStyle(fontSize: 14, color: colorWhite))
)
You can use maxLine and overflow properties to control how much lines the text can run through, and what happens when the maximum line is exceeded

Use Key from ListView of Firebase data in another (onPressed)-function

as you see in my code I want to export the key (docID of ListTile) to the function onPressedNegativ. With that I want to be able to edit the data of my firestore database. The exact idea behind that is, to update the field ergebnis to another value that a different icon is visible as leading of my ListTile.
So the question is, how can I export the right docID of the ListTile where I pressed the button which bring me to the onPressedNegativ function?
Thanks for any kind of help.
void onPressedNegativ() {
// update something in firebase
// how can I get the actual docID?
}
Widget _buildList(QuerySnapshot snapshot) {
return ListView.separated(
padding: EdgeInsets.all(20),
separatorBuilder: (context, index) => Container(
height: 10,
),
itemCount: snapshot.docs.length,
itemBuilder: (context, index) {
final doc = snapshot.docs[index];
return ListTile(
key: Key(doc.id),
leading: (doc["ergebnis"] == "Ausstehend")
? Icon(Icons.schedule)
: Icon(Icons.check),
title: Text(
doc["nachname"] + ", " + doc["vorname"],
),
subtitle: Text(doc["adresse"] +
" / " +
doc["Geburtsdatum"] +
" / " +
doc["telefon"]),
trailing: Wrap(
spacing: 12,
children: [
OutlineButton.icon(
borderSide: BorderSide(color: Colors.red),
onPressed: onPressedNegativ,
icon: Icon(
Icons.cancel_rounded,
color: Colors.red,
),
label: Text(
"Test positiv",
style: TextStyle(color: Colors.red),
),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
),
OutlineButton.icon(
borderSide: BorderSide(color: Colors.green),
onPressed: () {},
icon: Icon(
Icons.check_box_rounded,
color: Colors.green,
),
label: Text(
"Test negativ",
style: TextStyle(color: Colors.green),
),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
)
],
),
);
},
);
}
}
Void onPressedNegativ(String docID) {
//Use your docID to do logic you want
// Or update something in firebase
print("got this ID from my button: $docID");
}
And when you want to call it from onpressed:
onPressed: ()=> onPressedNegativ(doc.id),

I want to pass totalCartPrice to amount in openCheckout() in flutter application

I am new to flutter so please help me in this. I want to pass this value user provider.userModel.total cart price / 100 to amount in open checkout()
When user will click on checkout it will redirect to Razorpay payment gateway.
Code:
import 'package:flutter_ecommerce/helpers/style.dart';
import 'package:flutter_ecommerce/models/cart_item.dart';
import 'package:flutter_ecommerce/provider/app_provider.dart';
import 'package:flutter_ecommerce/provider/user_provider.dart';
import 'package:flutter_ecommerce/services/order.dart';
import 'package:flutter_ecommerce/widgets/custom_text.dart';
import 'package:flutter_ecommerce/widgets/loading.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:uuid/uuid.dart';
import 'package:razorpay_flutter/razorpay_flutter.dart';
class CartScreen extends StatefulWidget {
#override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
final _key = GlobalKey<ScaffoldState>();
OrderServices _orderServices = OrderServices();
Razorpay razorpay;
#override
void initState() {
// TODO: implement initState
super.initState();
razorpay = new Razorpay();
razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, handlePaymentSuccess);
razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, handleErrorFailure);
razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, handleExternalWallet);
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
razorpay.clear();
}
UserProvider userProvider;
void openCheckout() {
var options = {
"key": "rzp_test_UhHkdZJX3q5bRq",
"amount": userProvider.userModel.totalCartPrice,
"name": "Payment",
"description": "Payment for the product",
"prefill": {
"contact": "",
"email": "",
},
"external": {
"wallets": ["paytm"]
}
};
try {
razorpay.open(options);
} catch (e) {
print(e.toString());
}
}
void handlePaymentSuccess(PaymentSuccessResponse response) {
Fluttertoast.showToast(msg: "SUCCESS: " + response.paymentId);
}
void handleErrorFailure(PaymentFailureResponse response) {
Fluttertoast.showToast(
msg: "ERROR: " + response.code.toString() + " - " + response.message);
}
void handleExternalWallet(ExternalWalletResponse response) {
Fluttertoast.showToast(msg: "EXTERNAL_WALLET: " + response.walletName);
}
#override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
final appProvider = Provider.of<AppProvider>(context);
return Scaffold(
key: _key,
appBar: AppBar(
iconTheme: IconThemeData(color: black),
backgroundColor: white,
elevation: 0.0,
title: CustomText(text: "Shopping Cart"),
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.pop(context);
}),
),
backgroundColor: white,
body: appProvider.isLoading
? Loading()
: ListView.builder(
itemCount: userProvider.userModel.cart.length,
itemBuilder: (_, index) {
return Padding(
padding: const EdgeInsets.all(16),
child: Container(
height: 120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: white,
boxShadow: [
BoxShadow(
color: red.withOpacity(0.2),
offset: Offset(3, 2),
blurRadius: 30)
]),
child: Row(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
topLeft: Radius.circular(20),
),
child: Image.network(
userProvider.userModel.cart[index].image,
height: 120,
width: 140,
fit: BoxFit.fill,
),
),
SizedBox(
width: 10,
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RichText(
text: TextSpan(children: [
TextSpan(
text: userProvider
.userModel.cart[index].name +
"\n",
style: TextStyle(
color: black,
fontSize: 20,
fontWeight: FontWeight.bold)),
TextSpan(
text:
"\$${userProvider.userModel.cart[index].price / 100} \n\n",
style: TextStyle(
color: black,
fontSize: 18,
fontWeight: FontWeight.w300)),
TextSpan(
text: "Quantity: ",
style: TextStyle(
color: grey,
fontSize: 16,
fontWeight: FontWeight.w400)),
TextSpan(
text: userProvider
.userModel.cart[index].quantity
.toString(),
style: TextStyle(
color: primary,
fontSize: 16,
fontWeight: FontWeight.w400)),
]),
),
IconButton(
icon: Icon(
Icons.delete,
color: red,
),
onPressed: () async {
appProvider.changeIsLoading();
bool success =
await userProvider.removeFromCart(
cartItem: userProvider
.userModel.cart[index]);
if (success) {
userProvider.reloadUserModel();
print("Item removed from cart");
_key.currentState.showSnackBar(SnackBar(
content: Text("Removed from Cart!")));
appProvider.changeIsLoading();
return;
} else {
appProvider.changeIsLoading();
}
})
],
),
)
],
),
),
);
}),
bottomNavigationBar: Container(
height: 70,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RichText(
text: TextSpan(children: [
TextSpan(
text: "Total: ",
style: TextStyle(
color: grey,
fontSize: 22,
fontWeight: FontWeight.w400)),
TextSpan(
text: " \$${userProvider.userModel.totalCartPrice / 100}",
style: TextStyle(
color: black,
fontSize: 22,
fontWeight: FontWeight.normal)),
]),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), color: black),
child: FlatButton(
onPressed: () {
if (userProvider.userModel.totalCartPrice == 0) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
//this right here
child: Container(
height: 200,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
Text(
'Your cart is empty',
textAlign: TextAlign.center,
),
],
),
],
),
),
),
);
});
return;
}
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
//this right here
child: Container(
height: 200,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'You will be charged \$${userProvider.userModel.totalCartPrice / 100} upon delivery!',
textAlign: TextAlign.center,
),
SizedBox(
width: 320.0,
child: RaisedButton(
onPressed: () {
openCheckout();
// var uuid = Uuid();
// String id = uuid.v4();
// _orderServices.createOrder(
// userId: userProvider.user.uid,
// id: id,
// description:
// "Some random description",
// status: "complete",
// totalPrice: userProvider
// .userModel.totalCartPrice,
// cart: userProvider
// .userModel.cart);
// for (CartItemModel cartItem
// in userProvider
// .userModel.cart) {
// bool value = await userProvider
// .removeFromCart(
// cartItem: cartItem);
// if (value) {
// userProvider.reloadUserModel();
// print("Item added to cart");
// _key.currentState.showSnackBar(
// SnackBar(
// content: Text(
// "Removed from Cart!")));
// } else {
// print("ITEM WAS NOT REMOVED");
// }
// }
// _key.currentState.showSnackBar(
// SnackBar(
// content: Text(
// "Order created!")));
// Navigator.pop(context);
},
child: Text(
"Accept",
style:
TextStyle(color: Colors.white),
),
color: const Color(0xFF1BC0C5),
),
),
SizedBox(
width: 320.0,
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text(
"Reject",
style: TextStyle(
color: Colors.white),
),
color: red),
)
],
),
),
),
);
});
},
child: CustomText(
text: "Check out",
size: 20,
color: white,
weight: FontWeight.normal,
)),
)
],
),
),
),
);
}
}
But when I am trying to do like this it passes the null value to amount. Please help me out in these.
Razor pay taking amount in the rupees, so if you have 100Rupees then in the checkout you have to pass your amount *100 .
So below checkout method is :
void openCheckout() {
var options = {
"key": "rzp_test_UhHkdZJX3q5bRq",
"amount": userProvider.userModel.totalCartPrice * 100,
"name": "Payment",
"description": "Payment for the product",
"prefill": {
"contact": "",
"email": "",
},
"external": {
"wallets": ["paytm"]
}
};
try {
razorpay.open(options);
} catch (e) {
print(e.toString());
}
}
Check the below link :
https://razorpay.com/docs/payment-gateway/web-integration/standard/

Error while returning the number of count of collections in firebase flutter?

i'm developing an admin app in that i'm tired to return the number of users from firebase, i got few help from stackoverflow and was able to print in the terminal but its returning null on the app can someone please help me.this my code
class _AdminState extends State<Admin> {
Future<String> getUsersCount() async{
var length = -1;
await Firestore.instance.collection('users').getDocuments().then((myDocuments){
print("${myDocuments.documents.length}");
length = myDocuments.documents.length;
});
return Future.value(length.toString());
}
Page _selectedPage = Page.dashboard;
MaterialColor active = Colors.indigo;
MaterialColor notActive = Colors.grey;
final databaseReference = Firestore.instance;
bool isDelete= true;
var values;
TextEditingController categoryController = TextEditingController();
TextEditingController brandController = TextEditingController();
GlobalKey<FormState> _categoryFormKey = GlobalKey();
//GlobalKey<FormState> _brandFormKey = GlobalKey();
// BrandService _brandService = BrandService();
CategoryService _categoryService = CategoryService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Expanded(
child: FlatButton.icon(
onPressed: () {
setState(() => _selectedPage = Page.dashboard);
},
icon: Icon(
Icons.dashboard,
color: _selectedPage == Page.dashboard
? active
: notActive,
),
label: Text('Dashboard'))),
Expanded(
child: FlatButton.icon(
onPressed: () {
setState(() => _selectedPage = Page.manage);
},
icon: Icon(
Icons.sort,
color:
_selectedPage == Page.manage ? active : notActive,
),
label: Text('Manage'))),
],
),
elevation: 0.0,
backgroundColor: Colors.white,
),
body: _loadScreen());
}
Widget _loadScreen() {
switch (_selectedPage) {
case Page.dashboard:
return FutureBuilder(
future: getUsersCount(),
builder: (BuildContext context, AsyncSnapshot<String> text) {
print(text);
if(text== "-1"){
return CircularProgressIndicator();
} else {
return Column(
children: <Widget>[
ListTile(
subtitle: Text('Admin View', textAlign: TextAlign.center,
style: TextStyle(fontSize: 29.0,
color: Colors.indigo,
fontWeight: FontWeight.bold),),
),
Expanded(child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,),
children: <Widget>[
Padding(
padding: const EdgeInsets.all(18.0), child: Card(
child: ListTile(title: FlatButton.icon(
onPressed: null,
icon: Icon(
Icons.directions_boat, color: Colors.black,),
label: Text("Boats", style: TextStyle(
fontSize: 9, color: Colors.indigo),)),
subtitle: Text('3', textAlign: TextAlign.center,
style: TextStyle(
color: active, fontSize: 50.0),)),
),
),
Padding(padding: const EdgeInsets.all(18.0),
child: Card(child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(
Icons.people, color: Colors.black,),
label: Text("Users", style: TextStyle(
fontSize: 9, color: Colors.indigo),)),
subtitle: Text(text.data != null ? text.data : '',
textAlign: TextAlign.center,
style: TextStyle(color: active, fontSize: 50.0),
)),
),
),
Padding(
padding: const EdgeInsets.all(22.0),
child: Card(
child: ListTile(
title: FlatButton.icon(
onPressed: null,
icon: Icon(
Icons.bookmark, color: Colors.black,),
label: Text("Bookings", style: TextStyle(
fontSize: 8, color: Colors.indigo),)),
subtitle: Text(
'120',
textAlign: TextAlign.center,
style: TextStyle(
color: active, fontSize: 50.0),
)),
),
),
],
),
),
],
);
} })
i was returning a null string value but when include this set of lines Text(text.data??'default value') i was able to clear that error but still not able to clear my issue someone please help me
You need to add await before getting data from Firestore, since it is and async and you are not waiting for the result and returning the value which is initialized to 0
Future<String> getUsersCount() async {
var length = 0;
await Firestore.instance.collection('users').getDocuments().then((myDocuments){
print("${myDocuments.documents.length}");
length = myDocuments.documents.length;
});
return Future.value(length.toString());
}
As you can see the value of users count(36) is getting printed but it is not return because the return gets called before the async execution is getting finish..
Initialize your length to -1 in getUsersCount method and then in build method before returning the cloumn widget check the text (snapshot value) :
if (text == "-1"){
return Center(
child: CircularProgressIndicator(backgroundColor: Colors.red,)
);
} else{
return Column(....)
}

Flutter: Firebase How to change the query and the content

I am trying to change the query according to the selected community.
When you select the community you must show the content of this community.
I have found a solution but I do not think it is the right one, because the application has 39 countries.
Those 39 require you to have a query for each one and there are many lines of code.
I hope there is some better solution than what I found.
GIF APP
- The error that appears is because there is no other country.
SearchClub.dart
This is the function that returns a query related to the countries.
I want to use one and not make several queries for each country.
searchClubs(TextEditingController countryChanged) {
var widgetFireUpdate;
setState(() {
if(countryChanged.text == 'SPAIN') {
widgetFireUpdate = new FirebaseAnimatedList(
query: FirebaseDatabase.instance.reference().child(widget.player.platform).child("CLUB").orderByChild('country').equalTo(countryChanged.text),
sort: (a, b) => a.value['createdDate'].compareTo(b.value['createdDate']),
reverse: true,
shrinkWrap: true,
defaultChild: new CircularProgressIndicator(),
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
return new StreamBuilder<Event>(
stream: itemRef2.orderByKey().onValue,
builder: (context, AsyncSnapshot<Event> snapshot2){
if(snapshot2.hasData) {
try {
return new Container(
decoration: new BoxDecoration(
color: Colors.grey[300],
),
child: new ListTile(
leading: snapshot.value['logoURL'].toString().indexOf('images/assets/logo_notfound.png') == -1 ? new CachedNetworkImage(imageUrl: snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8) : new Image.asset(snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8),
title: new Text(snapshot.value['name'].toUpperCase(), style: new TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: MediaQuery.of(context).size.width/30)),
subtitle: new RichText(
text: new TextSpan(
children: <TextSpan>[
new TextSpan(text: "CAPITÁN:", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35, fontWeight: FontWeight.bold)),
new TextSpan(text: " ${snapshot.value['captain'].toUpperCase()}", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35)),
]
),
),
),
);
}catch(e) {
return new Container();
}
} else if(snapshot2.hasError){
return new Container();
} else {
return new Container(
child: new Center(
child: new CircularProgressIndicator(
backgroundColor: Colors.red,
),
),
);
}
},
);
},
);
} else if(countryChanged.text == 'BRAZIL') {
widgetFireUpdate = new FirebaseAnimatedList(
query: FirebaseDatabase.instance.reference().child(widget.player.platform).child("CLUB").orderByChild('country').equalTo(countryChanged.text),
sort: (a, b) => a.value['createdDate'].compareTo(b.value['createdDate']),
reverse: true,
shrinkWrap: true,
defaultChild: new CircularProgressIndicator(),
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
return new StreamBuilder<Event>(
stream: itemRef2.orderByKey().onValue,
builder: (context, AsyncSnapshot<Event> snapshot2){
if(snapshot2.hasData) {
try {
return new Container(
decoration: new BoxDecoration(
color: Colors.grey[300],
),
child: new ListTile(
leading: snapshot.value['logoURL'].toString().indexOf('images/assets/logo_notfound.png') == -1 ? new CachedNetworkImage(imageUrl: snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8) : new Image.asset(snapshot.value['logoURL'], width: MediaQuery.of(context).size.width/8),
title: new Text(snapshot.value['name'].toUpperCase(), style: new TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: MediaQuery.of(context).size.width/30)),
subtitle: new RichText(
text: new TextSpan(
children: <TextSpan>[
new TextSpan(text: "CAPITÁN:", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35, fontWeight: FontWeight.bold)),
new TextSpan(text: " ${snapshot.value['captain'].toUpperCase()}", style: new TextStyle(color: Colors.black, fontSize: MediaQuery.of(context).size.width/35)),
]
),
),
),
);
}catch(e) {
return new Container();
}
} else if(snapshot2.hasError){
return new Container();
} else {
return new Container(
child: new Center(
child: new CircularProgressIndicator(
backgroundColor: Colors.red,
),
),
);
}
},
);
},
);
}
});
return widgetFireUpdate;
}
// OPEN LIST COMMUNITY
Widget _buildBottomPicker() {
final FixedExtentScrollController scrollController = new FixedExtentScrollController();
return new Container(
height: MediaQuery.of(context).size.height/3.5,
color: CupertinoColors.white,
child: new DefaultTextStyle(
style: const TextStyle(
color: CupertinoColors.black,
fontSize: 22.0,
),
child: new SafeArea(
child: new CupertinoPicker(
scrollController: scrollController,
itemExtent: MediaQuery.of(context).size.height/15,
magnification: 0.7,
diameterRatio: 0.5,
backgroundColor: CupertinoColors.white,
onSelectedItemChanged: (int index) {
setState(() {
_comunidad.text = _comunidades[index];
_imgComunidad = _imgComunidades[index];
});
},
children: new List<Widget>.generate(_comunidades.length, (int index) {
return new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(_comunidades[index]),
],
);
}),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: searchBar.build(context),
body: new Container(
color: widget.themeConsole,
child: new Column(
children: <Widget>[
new Card(
elevation: 0.0,
color: Colors.grey[50],
child: new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width/1.35,
child: new TextFormField(
controller: _comunidad,
style: new TextStyle(color: Colors.white),
enabled: false,
decoration: new InputDecoration(
labelText: 'Community:',
labelStyle: new TextStyle(color: Colors.white),
icon: new Image.asset(_imgComunidad, width: 24.0),
filled: true,
fillColor: Colors.grey[800],
),
validator: (String value){
player.country = value;
},
),
),
new IconButton(
icon: new Icon(Icons.flag, color: Colors.grey[800], size: 30.0,),
color: Colors.black,
onPressed: ()async {
await showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return _buildBottomPicker();
},
);
},
),
],
),
),
),
new Flexible(child: searchClubs(_comunidad))
],
)
),
);
}
SearchClub Complete: https://pastebin.com/zbeU6M1u
From what I have understood, you are using firebase real time database where you have child name as country and have data inside that node. You want to make queries in such a way that when you select a country, that particular query should be made like when selecting Argentina everything inside Argentina in your database should be called.
Store value of country names in a list and make a string for calling countries.
String country="";
List<String> country_name=["Argentina","Brazil","Spain"....];
Now on press function can be like this-
onPressed: () {
setState(() {
country=country_name[1];//example
});
country_call();
}
This will help us when we change the country name.
Lastly make changes in your firebase reference-
Future<void> country_call()async{
final FirebaseDatabase database = FirebaseDatabase().instance();
setState(() {
itemRef = database.reference().child(country);
itemRef.onChildAdded.listen(_onEntryAdded);
itemRef.onChildChanged.listen(_onEntryChanged);
});
}
By changing you can call different queries without writing for 39 different countries. If you are using a list view to show our data, make sure to empty it in country_call function. That can be done by simply equating it to null list("[]").
I was searching for something similar but could not find anything on the website. I used this approach to fix my problem. I hope it was helpful for you too.

Resources