I have containers which user can tab to choose their interests.
Upon tabbing, container color changes to show users they have chosen this option, and the interest is added to a list (backend).
Currently, everything is functioning well, but I don't want users to choose more than 9 interests bcos those interests will probably not be as important anymore.
Anyone has any idea how can I limit the max number of items in my list? As well as not allowing users to tab on the 10th container, or maybe at any point of time only 9 containers will change color.
Any guidance is much appreciated! Stay safe all! :D
Below is the code where the interests are added or removed.
var chosenInterests = chosenSportsInterests +
chosenEntertainmentInterests +
chosenCharacterInterests +
chosenArtsInterests +
chosenWellnessInterests +
chosenLanguageInterests;
if (widget.viewInterest.isChosen) {
Widget build(BuildContext context) {
Container container = Container(
height: MediaQuery.of(context).size.height * 0.03,
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.024,
vertical: MediaQuery.of(context).size.height * 0.003),
// padding: EdgeInsets.fromLTRB(12, 6, 12, 6),
margin: EdgeInsets.fromLTRB(4.5, 3, 6, 3),
decoration: BoxDecoration(
color: widget.viewInterest.isChosen && chosenInterests.length < 9
? Colors.yellow[300]
: Color(0xff04072E),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 1,
offset: Offset(0, 1), // changes position of shadow
),
],
borderRadius: BorderRadius.circular(15),
),
child: Text(
'${widget.viewInterest.title}',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: widget.viewInterest.isChosen && chosenInterests.length < 9
? Colors.black
: Colors.white),
));
if (widget.viewInterest.isChosen && chosenInterests.length < 9) {
chosenSportsInterests.add('${widget.viewInterest.title}');
print(chosenInterests);
} else {
chosenSportsInterests.remove('${widget.viewInterest.title}');
print(chosenInterests);
}
I assume you are using a list and each time your user chooses an interest you add it to that list.
with this thing what you can do is whenever your user choose an interest before adding to the list check that list length and if it was larger than 9 you can show a message instead of adding to list
Related
I have list view and I need it scroll 360ْ
I mean when last item finish the first item start.
Lets say you have list of items. You can do this.
ListView.builder(builder: (context, index) {
final actualIndex = index % items.size();
return YourWidget(items[actualIndex]);
},
itemCount: 9999999999,
);
Consider using ListWheelScrollView with looping delegate.
ListWheelScrollView.useDelegate(
itemExtent: 30,
childDelegate: ListWheelChildLoopingListDelegate(
children: List<Widget>.generate(
10, (index) => Text('$index'),
),
),
)
I have one main map: Map<DateTime, List<dynamic>> _myEvents;. Within this variable I store many events related to days one ex: {2020-12-23 12:00:00.000Z: [{time: TimeOfDay(10:47), eventName: Navidad}]}. My events are stored by day but now I want to show the list of events from a given month (each time user change the month I update the list with the month's events).
What I'm trying:
_setMonthEvents(first,last){
_monthEvents.clear();
for(int i = first.day; i <= last.day; i++){
DateTime dayT = DateTime(first.year, first.month, i, first.hour,first.minute,first.second);
if(_myEvents[dayT] != null){
_monthEvents.addAll({'date': dayT, 'time': _myEvents[dayT][0]['time'], 'name': _myEvents[dayT][0]['name']});
}
}
setState(() {});
}
But with this approach only the last events saved keeps in the _monthEvents : {date: 2020-12-24 12:00:00.000Z, eventTime: TimeOfDay(12:30), eventName: Navidad} and if I put another it subscribes it..
This is my ListView (to show the events)
ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _monthEvents.length != null ? _monthEvents.length : 0,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
//
},
child: Dismissible(
child: ListTile(
leading: Padding(padding: EdgeInsets.only(top: 10), child: Icon(Icons.calendar_today_rounded)),
title: Text(_monthEvents.toString(), style: TextStyle(fontWeight: FontWeight.bold)), //returns the last insertion (the last event included)
subtitle: Text(
_monthEvents.length.toString(), //returns 3 *always*
style: TextStyle(fontWeight: FontWeight.w600, fontStyle: FontStyle.italic)
),
),
),);
},
);
I think I've been doing it wrong. What is the best approach to achieve my expected result?
My current result: A list with three equal elements (the last I added) and with length 3.
My expected result: A list with all the events from all days (a day can have more than one event) from a given month
I am not sure how to ask this question, therefore, bare with me.
first page displays a gridview of different items, when you click on one of the items it brings you to a description page of the item.
in this description page it uses futurebuilder where future: gets firebasefirestore.instance.collection......get()
it then follows with a builder:
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> documentData = snapshot.data.data();
//Add images
// imgList.clear();
imgList.add(documentData['item_images'][0]);
imgList.add(documentData['item_images'][1]);
imgList.add(documentData['item_images'][2]);
return ListView(
children: [
CarouselWithIndicatorDemo(),
],);
}
The CarouselWithIndicatorDemo() is straight from the Dart dev carousel_slider example.
Retrieving the data works perfectly fine and the carousel displays all 3 images from the imglist (seen above).
but when I go back to the previous page to click on another item, the images in the carousel do not update. I tried imgList.removeAt(0) 3 times to clear the list within the dispose:
#override
void dispose() {
imgList.removeAt(0);
imgList.removeAt(0);
imgList.removeAt(0);
super.dispose();
}
but that didn't work... how can I update this list correctly?
***************** EDIT *********************
in a dart file I am passing the following information:
Map<String, dynamic> documentData = snapshot.data.data();
List imageList = documentData['item_images'];
This is within my ListView( children:[
ImageSwipe(imageList: imageList) // instead of CarouselWithIndicatorDemo()
The other dart file:
class ImageSwipe extends StatefulWidget {
ImageSwipe({Key key, this.imageList}) : super(key: key);
final List imageList;
#override
_ImageSwipeState createState() => _ImageSwipeState();
}
class _ImageSwipeState extends State<ImageSwipe> {
int _selectedPage = 0;
#override
Widget build(BuildContext context) {
return Container(
height: 400.0,
child: Stack(
children: [
PageView(
onPageChanged: (value) {
setState(() {
_selectedPage = value;
});
},
children: [
for (var i = 0; i < widget.imageList.length; i++)
Container(
child: FadeInImage.assetNetwork(
placeholder: 'assets/missingImage.jpg',
image: widget
.imageList[i],
fit: BoxFit.cover,
),
),
],
),
Positioned(
bottom: 10.0,
left: 0.0,
right: 0.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (var i = 0; i < widget.imageList.length; i++)
AnimatedContainer(
duration: Duration(
milliseconds: 300,
),
curve: Curves.easeOutCubic,
margin: EdgeInsets.symmetric(horizontal: 5.0),
width: _selectedPage == i ? 36.0 : 10.0,
height: 10.0,
decoration: BoxDecoration(
color: AppColors.primaryColor,
borderRadius: BorderRadius.circular(
12.0,
),
),
)
],
),
),
]),
);
}
}
I have resolved and issue like that by using this:
final backgroundImages = ['signin_background.png','limpieza.jpg',/*'medicina.jpg',*/'plomero.jpg','profesor.jpg','veterinario.jpg'];
Then wrapping it in a animatedSwitcher like this:
Stack(
children: [
AnimatedSwitcher(
duration: Duration(milliseconds: 800),
transitionBuilder: (Widget image, Animation<double> animation) {
return FadeTransition(opacity: animation, child: image,);
},
child: Image.asset('assets/'+backgroundImages[pos],
width: MediaQuery.of(context).size.width,
key: ValueKey(pos),
fit: BoxFit.fill,
),
),
So you have to first fetch the images from your db or store them withing the app.
I'm using flutter. I have two dynamic lists of item available and items unavailable.
I want to show both lists in a way that it shows complete available item list then complete unavailable item list and flutter will decide the length dynamically.
Thank you.
This is a small example should show red Container for available items and blue items for unavailable items.
List<int> unavailable;
List<int> available;
Expanded(
child: CustomScrollView(slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final item = available[index];
if (index > available.length) return null;
return Container(color: Colors.red, height: 150.0); // you can add your available item here
},
childCount: available.length,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final item = unavailable[index];
if (index > unavailable.length) return null;
return Container(color: Colors.blue, height: 150.0); // you can add your unavailable item here
},
childCount: unavailable.length,
),
)
]));
We are using nnnick chart.js (open source chart) in our application for reporting purpose.There is a requirement to show the Custom tool-tip in the line chart.
As of now , Normal chart tooltip is showing based on the X-axis and Y axis dataset values. But Here we want to show the Dynamic additional data in the Tooltip.
For Example ,
Let us take a Student Enrollment .
here
X Axis Value - Enrollment Month (Jan,Feb,Mar....etc)
Y Axis Value - Number of Enrollments (10,20,30...ect)
After the Line chart is plotted , Now it is displaying (Jan ,10) in the tooltip.
We have to show the Number of Male & Female student details in the tool tip On mouse over the data point Jan 10 (i.e) (Jan,10, Male:5 , Female 5 ).
If you see the above screen shot , Green color is toop-tip is the normal one which is a built-in option. Red Color highlighted tool-tip is the one we are expecting.
Please provide any suggestion on this .
So you can achieve this using the custom tool tip function in the newer (not sure when it was included) version of chart js. You can have it display anything you want in place of a normal tooltip so in this case i have added a tooltip and a tooltip-overview.
The really annoying thing is though in this function you are not told which index you are currently showing a tooltip for. Two ways to solve this, override the showToolTip function so it actually passes this information or do a quick little hack to extract the label from the tooltip text and get the index from the labels array (hacky but quicker so i went for this one in the example)
So here is a quick example based upon the samples in chartjs samples folder. This is just a quick example so you would prob need to play around with the positioning and stuff until its what you need.
Chart.defaults.global.pointHitDetectionRadius = 1;
Chart.defaults.global.customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
var tooltipOverviewEl = $('#chartjs-tooltip-overview');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
tooltipOverviewEl.css({
opacity: 0
});
return;
}
//really annoyingly we don;t get told which index this comes from so going to have
//to extract the label from the text :( and then find the index based on that
//other option here is to override the the whole showTooltip in chartjs and have the index passed
var label = tooltip.text.substr(0, tooltip.text.indexOf(':'));
var labelIndex = labels.indexOf(label);
var maleEnrolmentNumber = maleEnrolments[labelIndex];
var femaleEnrolmentNumber = FemaleEnrolments[labelIndex];
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
tooltipEl.html(tooltip.text);
//quick an ddirty could use an actualy template here
var tooltipOverviewElHtml = "<div> Overall : " + (maleEnrolmentNumber + femaleEnrolmentNumber) + "</div>";
tooltipOverviewElHtml += "<div> Male : " + (maleEnrolmentNumber) + "</div>";
tooltipOverviewElHtml += "<div> Female : " + (femaleEnrolmentNumber) + "</div>";
tooltipOverviewEl.html(tooltipOverviewElHtml);
// Find Y Location on page
var top;
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
tooltipOverviewEl.css({
opacity: 1,
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var maleEnrolments = [5, 20, 15, 20, 20, 30, 50]; // Integer array for male each value is corresponding to each month
var FemaleEnrolments = [5, 0, 15, 20, 30, 30, 20]; // Integer array for Female each value is corresponding to each month
var labels = ["Jan", "February", "March", "April", "May", "June", "July"]; //Enrollment by Month
var lineChartData = {
labels: labels,
datasets: [{
label: "Student Details",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [10, 20, 30, 40, 50, 60, 70], //enrollement Details overall (Male + Female)
}]
};
var ctx2 = document.getElementById("chart2").getContext("2d");
window.myLine = new Chart(ctx2).Line(lineChartData, {
responsive: true
});
#canvas-holder1 {
width: 300px;
margin: 20px auto;
}
#canvas-holder2 {
width: 50%;
margin: 20px 25%;
position:relative;
}
#chartjs-tooltip-overview {
opacity: 0;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
left:200px;
top:0px
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
.chartjs-tooltip-key {
display:inline-block;
width:10px;
height:10px;
}
<script src="https://raw.githack.com/nnnick/Chart.js/master/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder2">
<div id="chartjs-tooltip-overview"></div>
<div id="chartjs-tooltip"></div>
<canvas id="chart2" width="600" height="600" />
</div>