Flutter : How to make every card unique using Listview.builder? - android

This is the code I have written in my home.dart file.
SliverToBoxAdapter(
child: Container(
width: MediaQuery.of(context).size.width,
height: 245,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount:10,
itemBuilder: (context, index) {
return VideoCard(long: true);
}
),
),
),
This is the VideoCard() class
class VideoCard extends material.StatelessWidget {
final bool long;
const VideoCard({
#material.required this.long,
material.Key key,
}) : super(key: key);
#override
material.Widget build(material.BuildContext context) {
return material.Padding(
padding: const material.EdgeInsets.all(10.0),
child: CardWidget(
gradient: false,
button: true,
width: long ? 360 : 180,
child: material.Column(
mainAxisAlignment: material.MainAxisAlignment.start,
children: <material.Widget>[
material.Container(
width: long ? 360 : 180,
height: 90,
decoration: material.BoxDecoration(
image: material.DecorationImage(
image: material.AssetImage('assets/images/bitcoin.png'),
fit: material.BoxFit.contain),
borderRadius: material.BorderRadius.only(
topLeft: material.Radius.circular(10),
topRight: material.Radius.circular(10),
),
),
child: material.Text(""),
),
material.Padding(
padding: const material.EdgeInsets.all(8.0),
child: material.Text(
"BITCOIN - A pioneer in Crypto!",
overflow: material.TextOverflow.ellipsis,
maxLines: 2,
style: material.TextStyle(
color: material.Colors.white,
fontFamily: 'Red Hat Display',
backgroundColor: material.Colors.black,
fontSize: 16),
),
),
material.Padding(
padding: const material.EdgeInsets.symmetric(horizontal: 8.0),
child: material.Row(
children: <material.Widget>[
material.Icon(BoxIcons.bx_bar_chart_alt_2, size: 16),
material.Text(
"Beginner",
style: material.TextStyle(
color: material.Color(0xFFADADAD),
fontFamily: 'Red Hat Display',
fontSize: 10),
),
material.Spacer(),
material.Text(
"10 mins",
style: material.TextStyle(
color: material.Color(0xFFADADAD),
fontFamily: 'Red Hat Display',
fontSize: 10),
),
material.Icon(BoxIcons.bx_timer, size: 16),
],
),
),
material.Spacer(),
material.Padding(
padding: const material.EdgeInsets.only(top: 6.0),
child: material.GestureDetector(
child: material.Container(
padding: material.EdgeInsets.fromLTRB(0, 14, 0, 14),
decoration: material.BoxDecoration(gradient: Colors().waves),
child: material.Row(
mainAxisAlignment: material.MainAxisAlignment.spaceEvenly,
children: <material.Widget>[
material.Icon(BoxIcons.bx_play_circle,
color: material.Colors.black),
material.Text(
"Learn it",
style: material.TextStyle(
color: material.Colors.black,
fontFamily: 'Red Hat Display',
fontSize: 18),
)
],
),
),
onTap: () {
material.Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => VideoPage(),
),
);
},
),
),
],
),
),
);
}
}
This is the result I got.
But I want unique text,image for every card(list).
The dedign for every list should be same. But text,image,onTap() gesture should be different for every card(list) .
Is my logic is wrong?
Any answer is appreciated!

You've hard coded the text, image and onTap. You should pass the data from the map or list and use [index] to tell your code that card with index 0 in the list, should use text with index 0, and card with index 1, should use text with index 1.
If the items in your list will not change, and you want to hardcode them, you can do that without .builder. You can simply use ListView widget. You can also use Row and/or Column widgets.
ListView(
child: Column(
children[
Card(),
Card(),
Card()
]))
If you want a two column design, create two Columns or ListView inside a Row widget.

You can pass parameters to the constructor of VideoCard like VideoCard(text: textFromListView, image: imageFromListView). In VideoPage you can do like this as well like VideoPage(text: textFromVideoCard, imaeg: imageFromVideoCard);
In VideoCard onTap() you can do like
onTap: () {
material.Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => VideoPage(text: textFromVideoCard, image: imageFromVideoCard),
),
);
},
Then in VideoPage you can access to text and image that you want to. Happy coding.

Related

ListViewBuilder problem when i run my code on emulatior. its shows that "Bottom over flowed by 167 pixels"

This is my emulator image which is showing the problem, I also use my mobile but it same condition
I having problems when my container height is more than 100. I can solve my problem by using SingleChildScrollView. But I want to scroll my only my list portion and that's why I don't wanna use SingleChildScrollView. Will my container size increase or container height increase show any render problem?
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/transaction.dart';
class TransactionList extends StatelessWidget {
final List<Transaction> transaction;
TransactionList(this.transaction);
#override
Widget build(BuildContext context) {
return Container(
height: 200,
// height: 300, when i use 300 then the problem occures.
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (ctx, index) {
return Card(
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10),
decoration: BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
padding: EdgeInsets.all(10),
child: Text(
'\$${transaction[index].amount.toStringAsFixed(2)}',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.purple,
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
transaction[index].title,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
DateFormat.yMMMd().format(transaction[index].date),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey[600],
),
)
],
)
],
),
);
},
itemCount: transaction.length,
),
);
}
}
Wrap your MainScreen with SingleChildScollView Widget
I have solved this problem. But now my whole screen is scrollable. but it's ok now. I will manage. I add SingleChildScroll... in my main. Now it's ok to use.

use textField and listview.builder in bottom sheet

Hey everyone I'm new to flutter and I have a problem.
I want to create an application that users after tapping on the Btn the bottom sheet will be open and after that ( here problem ) show the text field(for search) and the listView.
problem: when I do this nothing show me( even the bottom sheet don't appear)
this is my code :
enter code here
GestureDetector(
onTap: () {
showModalBottomSheet(
// ---------------------//
context: context,
builder: (context) {
return Container(
color: Color(0xff737373),
// to make the radius visible
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10))),
child: countriesInfo == null
? Center(
child: CircularProgressIndicator(),
)
: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
child: TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'country',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
),
ListView.builder(
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_selectItem(countriesInfo[index]);
},
child: Container(
padding: EdgeInsets.only(left: 10, right: 10),
height: 50,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 10, offset: Offset(0, 10))],
),
child: Row(
children: [
Image.network(
countriesInfo[index]._flag,
width: 50,
height: 50,
),
Text(
countriesInfo[index]._name,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
],
), // name of the country
),
);
},
itemCount: countriesInfo == null ? 0 : countriesInfo.length,
),
],
)),
);
}); // end bottom nav
},
child: Container(
width: double.infinity,
margin: EdgeInsets.all(35),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(color: Color(0xFFA3A3A3), borderRadius: BorderRadius.all(Radius.circular(15))),
child: Center(
child: Text(
"${selectedCountry == null ? countriesInfo[0].name : selectedCountry!.name.toString()}",
style: TextStyle(fontSize: 18),
),
),
),
),
if know any documentation or idea tell me please thank you.

How to Scroll multiple Textfields together in Flutter

I have a situation where 2 Textfields are placed inside a Stack Widget overlapping one another. Is there anyway i can scroll both the textfields together vertically if the data exceeds the size of the screen?
Stack(
children: [
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(15, 8, 0, 0),
child: SyntaxView(
code: codeController.text,
syntax: Syntax.C,
syntaxTheme: SyntaxTheme.gravityDark(),
withZoom: true,
withLinesCount: true),
),
Container(
width: 362,
padding: EdgeInsets.fromLTRB(55, 12, 0, 0),
child: TextFormField(
scrollPhysics: NeverScrollableScrollPhysics(),
focusNode: codeFocus,
controller: codeController,
autofocus: true,
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
color: Color(0x00ffffff),
// color: Colors.yellow,
height: 1.35,
fontFamily: "CodeFont",
fontSize: 12,
),
decoration: InputDecoration(
border: InputBorder.none,
),
onChanged: (value) {
setState(() {
CODE = value;
// print("X : ${codeController.text}");
});
},
),
),
],
),
A simple way way to handle that situation is to wrap your content in a ListView, which handles scrolling of its children. Here's a snippet from the ListView docs as an example:
ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
)
https://api.flutter.dev/flutter/widgets/ListView-class.html

Provider not displaying updated state in another screen

so im using provider and change notifier, the problem is when i change the state and notifiy listeners in the same file the user interface is updated, but when i try to access the same data from the model in another screen it still keeps the original or first version and not the updated version, the class in the other file is even using change notifier provider and a consumer just as the file with the modal class inside but is not changing the value, its only keeping the initial value, the second file only has changenotifierprovider and consumer, but it only displays the initial not the updated but the first file with the model class, and change notifier function is displaying the updated version in its widgets
this is the part of my first where i created my changenotifier, theres more but it was long so i just added this part, but all widgets here display the updated state
class MyModel with ChangeNotifier{
String datesChosen = "Click here";
String checkin;
String checkout;
String email;
String name;
String roomtype = "Click here";
String phonenumber;
String hotelname;
void updateData1 (data){
datesChosen = data;
print(datesChosen);
notifyListeners();
}
void updateData2 (data){
roomtype = data;
print(roomtype);
notifyListeners();
}
And this is my second screen, which only displays the intial states even after they are updated in the frst screen
import 'package:flutter/material.dart';
import 'package:hotel_search/common/theme.dart';
import 'package:hotel_search/sliding_bottom_sheet_content.dart';
import 'package:hotel_search/home_page.dart';
import 'package:provider/provider.dart';
class BookScreen extends StatefulWidget {
#override
_BookScreenState createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
#override
void initState() {
super.initState();
/*Future.delayed(Duration(milliseconds: 1000)).then((v) {
Navigator.pop(context);
});*/
}
#override
Widget build(BuildContext context) {
final themeData = HotelConceptThemeProvider.get();
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
home:Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
elevation: 0,
titleSpacing: 0,
backgroundColor: Colors.white,
title: Text(' ' ,style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 20,
))
)
,
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 40,),
Container(
width: MediaQuery.of(context).size.width - 100,height: 100,
child:Image.asset(
"assets/images/brand.png",
width: 0,
height:0,
fit: BoxFit.cover,)),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding: EdgeInsets.only(left:20,top:20, bottom: 20),
width: MediaQuery.of(context).size.width,
child:Text('Review \nYour Booking' ,style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 30,
))
),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding: EdgeInsets.only(left:20,top:20),
width: MediaQuery.of(context).size.width,
child:Text("HOTEL NAME" ,style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20,
fontWeight: FontWeight.w700,
))
),
Row(
children: <Widget>[
Consumer<MyModel>(
builder: (context, myModel, children){
return
Container(
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text(myModel.datesChosen.toString() ,style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))
),
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text(myModel.roomtype.toString(), style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)),
)
,
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text("CHECK IN AND OUT TIME" ,style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))),
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text("TYPE OF ROOM CHOSEN" ,style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)))
]
)
);}),
Spacer(),
Container(
margin: EdgeInsets.only(right:20),
width: 150 ,
height:120,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("img/card.jpg"), fit: BoxFit.cover),
color: Colors.grey[300],
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10), boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3), // changes position of shadow
)
])
)
]
),
SizedBox(height: 60),
Divider(
height: 25,
color: Colors.grey[300],
),
SizedBox(height:20),
Container(
color: Color(0xff008d4b),
height: 60,
width: MediaQuery.of(context).size.width -50,
child:FlatButton(
onPressed: () {
/*...*/
},
child: Text(
"Book Now", style: TextStyle(
color: Colors.white,
fontFamily: 'Montserrat',
fontSize: 20,
),
),
),
)
]
),
)
)
)));
}
}
Have a look here at one of my more detailed answers about using the Provider. I think what you're missing is wrapping the application with a Provider Widget and calling setState(() {}); when you make those changes.
P.S. Please use Ctrl + Alt + L inside the editor to indent the code properly before asking a question. What you posted is barely readable. Also, you might wanna consider splitting up your code into multiple files and not just create the whole app in main.dart. You know... just some organizing here and there.

How to use column inside single child scroll view flutter

I have a column inside a single child scroll view. I need to make my login screen scroll when I type using the keyboard because the keyboard hides the password text field.
class UserRegistration extends StatefulWidget {
#override
_UserRegistrationState createState() => _UserRegistrationState();
}
class _UserRegistrationState extends State<UserRegistration> {
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Color(0xFF6C62FF)
));
return SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
child: Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
backgroundColor: Color(0xFF6C62FF),
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Column([![enter image description here][1]][1]
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(child: FittedBox(child: Text('Welcome', style: TextStyle(fontFamily: 'SourceSans', fontSize: 50, fontWeight: FontWeight.w600, color: Color(0xFFFFD700)),))),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Register', style: TextStyle(fontFamily: 'SourceSans', fontSize: 40, fontWeight: FontWeight.w600, color: Colors.white)),
SizedBox(height: 5,),
Text('Start from today', style: TextStyle(fontFamily: 'SourceSans', fontSize: 25, letterSpacing: 1.5,fontWeight: FontWeight.w600, color: Colors.white), overflow: TextOverflow.ellipsis,),
],
),
),
Form(
child: Column(
children: [
EditTextNormal(hintText: 'Email', iconData: Icons.email, textInputType: TextInputType.emailAddress, validate: false, errorText: 'Enter your email',),
SizedBox(height: 20,),
EditTextObscure(hintText: 'Password', iconData: Icons.lock, textInputType: TextInputType.text, validate: false, errorText: 'Enter your password',),
SizedBox(height: 50,),
Container(
height: 50,
width: 180,
child: FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)
),
onPressed: () {},
color: Colors.white,
child: Text('Register', style: TextStyle(color: Color(0xFF6C62FF), fontSize: 20), overflow: TextOverflow.ellipsis,),
),
)
],
),
),
Center(
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(text: 'Login', style: TextStyle(color: Color(0xFFFFD700), letterSpacing: 1, wordSpacing: 1.5))
],
text: 'Have an account? ',
style: TextStyle(fontSize: 18, fontFamily: 'SourceSans', fontWeight: FontWeight.bold, letterSpacing: 1, wordSpacing: 1.5)
),
),
),
],
),
),
),
),
);
}
}
This is my code but here when I use a column inside a single child scroll view space evenly does not work. Please give me a solution.
My output:
Expected Output:
Try This
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
minHeight: MediaQuery.of(context).size.height,
),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
// CONTENT HERE
],
),
),
),
),
);
}
Add Container inside SingleChildScrollView and assign it height based on your keyboard open or not.
Add Dependency:
dependencies:
keyboard_visibility: ^0.5.6
Initialize keyboard listener in initState() for callback
bool _isKeyBoardShown = false;
#protected
void initState() {
super.initState();
KeyboardVisibilityNotification().addNewListener(
onChange: (bool visible) {
setState(() {
_isKeyBoardShown = visible;
});
},
);
}
Based on _isKeyBoardShown value decide whether to add additional height on the screen or not.
Container(
width: MediaQuery.of(context).size.width,
height: _isKeyBoardShown
? MediaQuery.of(context).size.height +
MediaQuery.of(context).size.height / 2
: MediaQuery.of(context).size.height,
child: Column(....)
)
Note: Use MediaQuery to decide additional height don't use hard-coded values
here I used MediaQuery.of(context).size.height / 2

Categories

Resources