how to make a control in a lisTile with flutter. i get datas from json and display them in a listTile,. but i want to make a if control to show a button.
if(data[position]['value'] == 0){
sho raised button;
}else{
don't show it;
}
You can add a button on the trailing edge of the tile, using the trailing property of ListTile.
For example, here we add an IconButton :
Widget _ = ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text("Row $index"),
trailing: (data[position]['value'] == 0)
? IconButton(icon: Icon(Icons.alarm), onPressed: () {})
: null);
});
Related
I'm trying to generate a 300 list like this:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: "Zulfa Application",
home: new Home(data: new List<String>.generate(300,(i)=>"Ini data ke $i"),),
));
}
class Home extends StatelessWidget {
final List<String> data;
Home({required this.data});
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar : new AppBar(
backgroundColor: Colors.purpleAccent,
title: new Text("Zulfalogy Content"),
),
body: new Container(
child: new ListView.builder(
itemCount: data.length,
itemBuilder: (context, index){
return new ListTile(
leading: new Icon(Icons.widgets),
title: new Text("${data[index]}"),
);
}
),
),
);
}
}
And it thrown an error like this:
_TypeError (type 'Null' is not a subtype of type 'List<String>' of 'function result')
I didnt know how its going. i just following some tutorial and it still error. Hope u guys can help me to solve this:)
I have been copying your code as you post it and it worked fine for me
could you share your flutter version. or try to upgrade your flutter sdk.
or try to copy this >>
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: "Zulfa Application",
home: Home(data: List.generate(300,(i)=>"Ini data ke $i"),),
));
}
class Home extends StatelessWidget {
final List? data;
Home({ this.data});
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar : new AppBar(
backgroundColor: Colors.purpleAccent,
title: new Text("Zulfalogy Content"),
),
body: new Container(
child: new ListView.builder(
itemCount: data!.length,
itemBuilder: (context, index){
return new ListTile(
leading: new Icon(Icons.widgets),
title: new Text("${data![index]}"),
);
}
),
),
);
}
}
I have a screen that consist of ExpansionTile and as we know that ExpansionTile has children property. The thing that I would like to do is I need to catch the trigger click of ExpansionTile, so when user click the ExpansionTile it will run FutureBuilder to get a data from API, is there a way to do that. Because until now... ExpansionTile always runs together with the children
Here is part of the code
ExpansionTile(
children:[] //here.. I would like to call the data from api, when user click the expansiontile
title: Text(
"${dataAll["data"][i]["lowongan"]}",
style: GoogleFonts.poppins(
fontWeight: FontWeight.w600,
color: isHovered ||
listLokerModel.value
.lokerState[i]
? dark_button
: Colors.white,
fontSize: 20)),
subtitle: Text(
"${dataAll["data"][i]["start"]} - ${dataAll["data"][i]["end"]}",
style: GoogleFonts.poppins(
color: isHovered ||
listLokerModel.value
.lokerState[i]
? dark_button
: Colors.white,
fontSize: 16)),
trailing: Icon(
Icons.keyboard_arrow_down_sharp,
color: isHovered ||
listLokerModel
.value.lokerState[i]
? dark_button
: Colors.white,
))
Here's simple solution to it.
Inside ExpansionTile, children add FutureBuilder, refer below code, you will get an idea.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ExpansionTile(title:Text('hello'),
children:[
FutureBuilder(
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as String;
return Center(
child: Text(
'$data',
style: TextStyle(fontSize: 18),
),
);
}
}
// Displaying LoadingSpinner to indicate waiting state
return Center(
child: CircularProgressIndicator(),
);
},
// Future that needs to be resolved
// inorder to display something on the Canvas
future: getData(),
),
]);
}
Future<String> getData() {
return Future.delayed(Duration(seconds: 2), () {
return "I am data";
// throw Exception("Custom Error");
});
}
}
Here's the image
If you look image, there's a text field and an add button at the bottom right. I want the user to enter the word and add that to a list using that button.
In order to access the value from the text field, I used (TextEditingController)
Please find the code for the widget below.
FYI: This widget gets called when an icon is pressed on its previous page
final wordList = []; // list that I'm trying to render
Widget _doSomething() {
setState(() async => wordList.add(await Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Enter Something..'),
),
body: TextField(
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Add word',
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pop(context, myController.text);
},
tooltip: "Toggle input value",
child: const Icon(Icons.add),
),
);
}))));
return _getList();
}
Above, I return _getList(). _getList() is another widget where I have the list view code in order to display the word list values in the same page. (code below)
Widget _getList() {
return Scaffold(
body: ListView.builder(
itemCount: wordList.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(wordList[index]),
);
},
),
);
}
I apologize if something is unclear. Please feel free to ask me for more explanation. Thanks for you help.
First you do not need to use new when creating instance of class. So new Text() will become Text().
Second, if you use navigate use the .of() constructor, it will change your current screen. You can use the Navigator.push() method. The function would be async and would return of void. You can just retrun the widget in your main widget.
third, why are you returning a whole MaterialApp in a function. it should be in your main.dart.
void _doSomething() async {
wordList.add(await Navigator.
.push(context,MaterialPageRoute<void>(builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Enter Something..'),
),
body: TextField(
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(), hintText: 'Add word',),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pop(context, myController.text);
},
tooltip: "Toggle input value",
child: const Icon(Icons.add),
),
);
})));
setState(()=> wordList = wordList);
}
For get list:
Widget _getList() {
return Scaffold(
body: ListView.builder(
itemCount: wordList.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(wordList[index]),
);
},
),
);
}
I'm searching for a solution to pass my snapshot via Navigator or others to my Detail Page.
class SoccerList extends StatelessWidget {
#override
Widget build(BuildContext context) {
final database = Provider.of<FirestoreDatabase>(context, listen: false);
return StreamBuilder<List<Soccer>>(
stream: database.soccerStream(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
final soccer = snapshot.data;
if (soccer == null) {
return Scaffold(
body: Center(
child: Text('User list is empty',
style: Theme.of(context).textTheme.headline6),
),
);
}
return ListView.builder(
itemCount: soccer.length,
itemBuilder: (context, index) {
final item = soccer[index];
return Container(
margin: EdgeInsets.fromLTRB(15, 5, 15, 5),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5), //color of shadow
spreadRadius: 5, //spread radius
blurRadius: 7, // blur radius
offset: Offset(0, 2), // changes position of shadow
//first paramerter of offset is left-right
//second parameter is top to down
),
//you can set more BoxShadow() here
],
),
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailBetScreen(soccer: soccer)
//[index],
)
);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
leading: IconButton(
iconSize: 24,
icon: new SvgPicture.asset('assets/ball/fussball7.svg'), onPressed: () { },
),
title: item.displayname != null? Text(item.displayname) : Text(item.sporttype),
subtitle: Text(item.sporttype),
),
);
},
);
}
The error message is:
Exception caught by widgets library:
type 'List' is not a subtype of type 'DocumentSnapshot'
The relevant error-causing widget was
MaterialApp
How do i pass this snapshot (soccer) to a Detail Page? Sure the snapshot contains a List....i need both. Thnaks in advance for any idea!
This is my Stream:
Stream<List<Soccer>> soccerStream() => _service.soccerStream<Soccer>(
path: FirestorePath.bets(),
builder: (data, documentId) => Soccer.fromMap(data, documentId),
);
And this is my Detail Screen:
class DetailBetScreen extends StatelessWidget {
final DocumentSnapshot soccerBet;
DetailBetScreen({Key key, #required this.soccerBet}) : super(key: key);
You can try this:
class DetailBetScreen extends StatelessWidget {
final dynamic soccerBet;
DetailBetScreen({Key key, #required this.soccerBet}) : super(key: key);
i created a search delegate class and what i want sounds logically simple but i cant wrap my head around it as i am new programming
i want to get the text or maybe i should say string of the text in the listTile i tap on ,
then pass that text to the showResult of search delegate and view it in a text widget
... here is my code
import 'package:flutter/material.dart';
import 'package:schooler/style/const.dart';
//follow steps 1 - 3
class DataSearch extends SearchDelegate<String> {
final List<String> languages = [//3.here is my list
'dart',
'Csharp',
'Java',
'JavaScript',
'C++',
'go ',
'python',
'php'
];
final List<String> recentSearch = [
'go ',
'python',
'php',
];
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
},
)
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
return Scaffold(
body: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(),
Text(languages[0].substring(query.length)),//2.i want to return the gotten index here
],
),
],
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionList = query.isEmpty
? recentSearch
: languages.where((element) => element.startsWith(query)).toList();
return ListView.builder(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context); //1.when i tap the item on the listTile i want it to get the index of the taped item
},
leading: query.isEmpty
? Icon(
Icons.history,
)
: Icon(Icons.search),
title: RichText(
text: TextSpan(
text: suggestionList[index].substring(
0,
query.length,
),
style: TextStyle(
color: kBlackColor,
fontWeight: kBold,
),
children: [
TextSpan(
text: suggestionList[index].substring(query.length),
style: TextStyle(color: kGreyColor),
),
],
),
),
),
itemCount: suggestionList.length,
);
}
}
here if i tap on 'go' it should get get the text and pass it to the showResult
here is my show result ..but i just hard coded my 'list[0]index in there' i guess what i am trying to say is get the text from the item i taped and show it here
First lets fix your itemBuilder in your ListView so it indexes each element and then add that index into your showResults() function call so you have access to it:
ListView.builder(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) => ListTile( // Add index here to pass the index to the builder.
onTap: () {
showResults(context, index); // Add the index to function call
},
Just be sure your showResults() function is modified to accept an int index parameter, and while I dont see that function, I am assuming it calls buildResults() at some point which needs to be modified to accept an index:
#override
Widget buildResults(BuildContext context, int index) {
return Scaffold(
body: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(),
Text(languages[index].substring(query.length)),// Use the index here to return the desired text
],
),
],
),
);
}