How to display the middle element of a list in Flutter? - flutter

I have a similar widget for CupertinoPicker, but it was made by hand. I need to make the middle element of the list be selected by default, not the initial one as it is now. I've tried different options but haven't been able to do it yet. Please tell me how to implement this, I will be grateful for the help?
widget
class WheelSpeedPicker extends StatefulWidget {
final Function(dynamic) onValueChanged;
final int? startPosition;
final double itemSize;
final double? listHeight;
final int currentPosition;
final double? listWidth;
final FixedExtentScrollController? controller;
const WheelSpeedPicker({
Key? key,
required this.onValueChanged,
required this.currentPosition,
required this.itemSize,
this.startPosition,
this.listHeight,
this.controller,
this.listWidth,
}) : super(key: key);
#override
_WheelTimePickerState createState() {
return _WheelTimePickerState();
}
}
class _WheelTimePickerState extends State<WheelSpeedPicker> {
FixedExtentScrollController? fixedExtentScrollController;
int? currentPosition;
#override
void initState() {
super.initState();
currentPosition = widget.currentPosition;
fixedExtentScrollController = widget.controller ??
FixedExtentScrollController(initialItem: currentPosition ?? 0);
}
void _listener(int position) {
setState(() {
currentPosition = position;
});
widget.onValueChanged(currentPosition);
}

#override
void initState() {
super.initState();
// swap this
// currentPosition = widget.currentPosition;
// with this
currentPosition = (time.length / 2).floor();
fixedExtentScrollController = widget.controller ??
FixedExtentScrollController(initialItem: currentPosition ?? 0);
}
Other than that, I think your widget would be more useful if you added the items list to the widget parameters:
class WheelSpeedPicker extends StatefulWidget {
final Function(dynamic) onValueChanged;
final List<String> items;
final int? startPosition;
final double itemSize;
final double? listHeight;
final int currentPosition;
final double? listWidth;
final FixedExtentScrollController? controller;
const WheelSpeedPicker({
Key? key,
required this.items,
required this.onValueChanged,
required this.currentPosition,
required this.itemSize,
this.startPosition,
this.listHeight,
this.controller,
this.listWidth,
}) : super(key: key);
And then you'd have a more coherent set of parameters, because you already have a startPosition in the interface.
#override
void initState() {
super.initState();
currentPosition = widget.startPosition;
fixedExtentScrollController = widget.controller ??
FixedExtentScrollController(initialItem: startPosition ?? 0);
}

Related

how can i place forloop so that i dont get error?

how can i use forloop to generate values of data variable please help i am a beginner
class Mentions extends StatefulWidget {
const Mentions({
Key? key,
this.width,
this.height,
required this.fullname,
required this.username,
required this.photourl,
}) : super(key: key);
final double? width;
final double? height;
final List<String> fullname;
final List<String> username;
final List<String> photourl;
#override
_MentionsState createState() => _MentionsState();
}
class _MentionsState extends State<Mentions> {
List<Map<String, dynamic>> data = [];
void data1(
for(int i = 0; i< widget.fullname.length; i++) {
data.add({"Full Name": widget.fullname[i], "username": widget.username[i], "photourl" :widget.photourl[i] });
}
)
);
#override
Widget build(BuildContext context) {
return Container();
}
}
you can place your method inside initState
class _MentionsState extends State<Mentions> {
List<Map<String, dynamic>> data = [];
void data1 (){
for(int i = 0; i< widget.fullname.length; i++) {
data.add({
"Full Name": widget.fullname[i],
"username": widget.username[i],
"photourl" :widget.photourl[i]
});
}
)
}
#override
void initState() {
super.initState();
data1();
}
#override
Widget build(BuildContext context) {
return Container();
}
}
try this:
class Mentions extends StatefulWidget {
Mentions({
required this.fullname,
required this.username,
required this.photourl,
this.width,
this.height,
Key? key,
}) : super(key: key) {
for (var i = 0; i < fullname.length; i++) {
users.add({
'Full Name': fullname[i],
'username': username[i],
'photourl': photourl[i]
});
}
}
final double? width;
final double? height;
final List<String> fullname;
final List<String> username;
final List<String> photourl;
late final List<Map<String, dynamic>> users;
#override
_MentionsState createState() => _MentionsState();
}
class _MentionsState extends State<Mentions> {...}
then you can just use widget.users in _MentionsState. but you can even not set all this lists in widget constructor, do mapping to users before, and set to widget constructor just one list with users. and do you really need stateful widget instead of stateless?

Pass value from Statefulwidget to Providerclass Flutter

i want to pass postid value from a statefulwidget to a function inside Providerclass, somebody please help
class CommentPage extends StatefulWidget {
final String postid;
final String postdescription;
CommentPage({
required this.postdescription,
Key? key,
required this.postid,
}) : super(key: key);
#override
State<CommentPage> createState() => _CommentPageState();
}
Providerclass
class CommentPageProvider extends ChangeNotifier {
static CommentPageProvider instance = CommentPageProvider();
List<HomeFeedDataModel> homeFeedDatacollection = [];
List<CommentsModelData> commentsDatacollection = [];
List<SingleUserPostModelData> singleuserdatacollection = [];
bool isLoadingdata = false;
bool isSingleUserdata = false;
bool isLikePressed = false;
bool isLoadCommentsPressed = false;
bool isLikeButtonPressed = false;
bool isCommentsDataloaded = false;
getCommentsData() async {
isCommentsDataloaded = true;
commentsData = await CommentService().getCommentsdata(post_id: );
notifyListeners();
}
so that i can fetch matching comments,
What's wrong with passing the post ID into the getCommentsData() as a parameter?
class CommentPageProvider extends ChangeNotifier {
static CommentPageProvider instance = CommentPageProvider();
List<HomeFeedDataModel> homeFeedDatacollection = [];
List<CommentsModelData> commentsDatacollection = [];
List<SingleUserPostModelData> singleuserdatacollection = [];
bool isLoadingdata = false;
bool isSingleUserdata = false;
bool isLikePressed = false;
bool isLoadCommentsPressed = false;
bool isLikeButtonPressed = false;
bool isCommentsDataloaded = false;
getCommentsData(String postId) async {
// I changed the name of this because there is no 'commentsData' field in your provider class
commentsDatacollection = await CommentService().getCommentsdata(post_id: postId);
isCommentsDataloaded = true;
notifyListeners();
}
By declaring your data collection as nullable (List<CommentsModelData> commentsDatacollection = [];), I think you could remove the boolean isCommentsDataloaded and simply check for a null value in your widget build method.
CommentPage
Here you just access the provider and pass through the post ID.
class CommentPage extends StatefulWidget {
final String postid;
final String postdescription;
CommentPage({
required this.postdescription,
Key? key,
required this.postid,
}) : super(key: key);
#override
State<CommentPage> createState() => _CommentPageState();
}
class _CommentPageState extends State<CommentPage> {
#override
Widget build(BuildContext context) {
final provider = Provider.of<CommentPageProvider>(context).getCommentsData(widget.postId);
}
}
Let me know if this helped!

how to use a data transfer from the parent widget?

Here is the child class that receives from its parent the index data that identifies the box to modify
class InformationPatient extends StatefulWidget {
final Patients patients;
final int index;
const InformationPatient(this.patients, this.index, {Key? key})
: super(key: key);
#override
State<InformationPatient> createState() => _InformationPatientState();
}
class _InformationPatientState extends State<InformationPatient> {
final int indexitem = 0;
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
}
void _addNote(String newtitle, String newnote, String newconclusion) {
final newNOTE = Patients(
listOfNotes: [
ListNote(title: newtitle, note: newnote, conclusion: newconclusion)
],
);
boxPatient.put(indexitem, newNOTE);
Navigator.of(context).pop();
}
This way works but I don't have the index of the parent, I give it to him
final int indexitem = 0; <--- Works perfectly with my function patientbox.put() it receives the index
boxPatient.put(indexitem, newNOTE);
I would like to give indexbox the value of index but I don't know how to do it or if there is another way
final int indexitem = ??? <---- add the value of index
boxPatient.put(indexitem, newNOTE);
obviously I can't use index directly in the function boxPatient.put()
Thank you very much for your help
To read variables from the widget inside the state, you can simply refer to widget.<variable>. So in your example
boxPatient.put(widget.index, newNOTE);

How to use Hive to modify only one value of ca class model?

Here is my problem when I add a new patient to my boxPatient everything is added with the constructor of my class Patient.
After creating a patient I would like to be able to add notes to him so add to the box of this patient with boxpatient.put(index, value)
However, when I add a new value with the Patient constructor it modifies all the other fields with null which is normal but I was wondering if there was a way to avoid modifying all the other fields and to modify only the listnote field
Here is the addition to my patient box of a new patient:
class PatientList extends StatefulWidget {
const PatientList({Key? key}) : super(key: key);
#override
State<PatientList> createState() => _PatientListState();
}
class _PatientListState extends State<PatientList> {
List<Patients> patientList = [];
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
//boxPatient.clear();
print('Patient ${boxPatient.values}');
}
void _bottomnewpatient(BuildContext ctx) {
TextEditingController namecontroller = TextEditingController();
TextEditingController firstnamecontroller = TextEditingController();
TextEditingController dateofbirthcontroller = TextEditingController();
TextEditingController emailcontroller = TextEditingController();
TextEditingController phonenumbercontroller = TextEditingController();
void _submitData() {
final enteredname = namecontroller.text;
final enteredfirstname = firstnamecontroller.text;
final entereddateofbirth = dateofbirthcontroller.text;
final enteredemail = emailcontroller.text;
final enteredphonenumber = phonenumbercontroller.text;
if (enteredname.isEmpty ||
enteredfirstname.isEmpty ||
entereddateofbirth.isEmpty ||
enteredemail.isEmpty ||
enteredphonenumber.isEmpty) {
print('No input');
return;
}
final newPT = Patients(
name: enteredname,
firstname: enteredfirstname,
dateofbirth: entereddateofbirth,
email: enteredemail,
numero: enteredphonenumber,
date: DateTime.now(),
id: DateTime.now().millisecondsSinceEpoch,
//id: DateTime.now().millisecondsSinceEpoch,
//listOfNotes: [],
);
boxPatient.add(newPT);
Navigator.of(context).pop();
}
And here is the addition of a new note to the patient box pointed by the index:
The problem here is that I call my constructor Patients() so it rebuilds all my fields how to avoid that.
With this builder also don't have the possibility to add more notes as it rebuilds each time.
class InformationPatient extends StatefulWidget {
final Patients patients;
final int index;
const InformationPatient(this.patients, this.index, {Key? key})
: super(key: key);
#override
State<InformationPatient> createState() => _InformationPatientState();
}
class _InformationPatientState extends State<InformationPatient> {
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
}
void _addNote(String newtitle, String newnote, String newconclusion) {
final newNOTE = Patients(
listOfNotes: [
ListNote(title: newtitle, note: newnote, conclusion: newconclusion)
],
);
boxPatient.put(widget.index, newNOTE);
Navigator.of(context).pop();
}
and here is the class model:
import 'package:hive_flutter/hive_flutter.dart';
part 'listpatient.g.dart';
#HiveType(typeId: 0)
class Patients {
#HiveField(0)
final String? name;
#HiveField(1)
final String? firstname;
#HiveField(3)
final String? dateofbirth;
#HiveField(4)
final String? email;
#HiveField(5)
final String? numero;
#HiveField(6)
final DateTime? date;
#HiveField(7)
final int? id;
#HiveField(8)
final List<ListNote>? listOfNotes;
const Patients({
this.name,
this.firstname,
this.dateofbirth,
this.email,
this.numero,
this.date,
this.id,
this.listOfNotes,
});
}
#HiveType(typeId: 10)
class ListNote {
#HiveField(1)
final String? title;
#HiveField(2)
final String? note;
#HiveField(3)
final String? conclusion;
ListNote({
this.title,
this.note,
this.conclusion,
});
}
Thank you very much for your help! :)

Make parameter variable usable to setState in flutter

I want to get the value of latitude and longitude variables, so that I can pass them to the fetchAlbum() function inside initstate().
class MainContent extends StatefulWidget {
final double latitude;
final double longitude;
MainContent({Key key, #required this.latitude, #required this.longitude}) : super(key: key);
#override
_MainContentState createState() => _MainContentState();
}
class _MainContentState extends State<MainContent> {
bool isLoading = false;
Future<Album> futureAlbum;
#override
void initState() {
super.initState();
var a = 23.2599; // update the value of 'a' by using 'latitude' variable
var b = 77.4126; // update the value of 'a' by using 'longitude' variable
futureAlbum = fetchAlbum(a, b);
}
Do it like this:
var a = widget.latitude;
var b = widget.longitude;