I have multiple images each with their own redirect link. Currently this works fine at displaying using a list view build to display the images inside a gesture detector.
However, I’d like to add a dot indicator to show which image is being viewed. How can I get the index of the image being displayed? Or increase / decrease a counter when swiping left or right.
I’ve looked into carousels but they don’t seem to allow each image to redirect to somewhere else.
As per example pointed to by #chunhunghan above in the comments, you need to replace map<Widget> ( (image, url) {..}
with
imgList.map((image) {int index = imgList.indexOf(image); ..}
I was able to get it to work with the above change. Revised code snippet for the build method:
#override
Widget build(BuildContext context) {
return Column(children: [
CarouselSlider(
items: child,
autoPlay: false,
enlargeCenterPage: true,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_current = index;
print("${_current}");
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imgList.map((image) { //these two lines
int index=imgList.indexOf(image); //are changed
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)),
);
},
),
),
]);
}
If I understand you clear. with package https://pub.dev/packages/carousel_slider
swipe image to left or right can get current page from onPageChanged event
and use InkWell wrap image, you can navigate to other page. In my demo just print click message
code snippet
final List child = map<Widget>(
imgList,
(index, i) {
return Container(
margin: EdgeInsets.all(5.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Stack(children: <Widget>[
InkWell(
onTap: () { print("you click ${index} "); },
child: Image.network(i, fit: BoxFit.cover, width: 1000.0)),
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color.fromARGB(200, 0, 0, 0), Color.fromARGB(0, 0, 0, 0)],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Text(
'No. $index image',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
),
]),
),
);
},
).toList();
...
class _CarouselWithIndicatorState extends State<CarouselWithIndicator> {
int _current = 0;
#override
Widget build(BuildContext context) {
return Column(children: [
CarouselSlider(
items: child,
autoPlay: false,
enlargeCenterPage: true,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_current = index;
print("${_current}");
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(
imgList,
(index, url) {
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)),
);
},
),
),
]);
}
}
The solution I found, besides change map to use imgList, was to put .toList() at the imgList.map function return as follows:
#override
Widget build(BuildContext context) {
return Column(children: [
CarouselSlider(
items: child,
autoPlay: false,
enlargeCenterPage: true,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_current = index;
print("${_current}");
});
},
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imgList.map((image) {
int index=imgList.indexOf(image);
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)
),
);
},
).toList(), // this was the part the I had to add
),
]);
}
Vertical Indicators On Slider or Flutter Carousel
class VerticalSlider extends StatefulWidget {
#override
_VerticalSliderState createState() => _VerticalSliderState();
}
class _VerticalSliderState extends State<VerticalSlider> {
List imageSliders=[
//add your items here
];
int _current = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Vertical sliding carousel ')),
body: Stack(
children: [
Container(
child: CarouselSlider(
options: CarouselOptions(
viewportFraction: .6,
aspectRatio: 1.2,
enlargeCenterPage: true,
scrollDirection: Axis.vertical,
autoPlay: true,
onPageChanged: (index, reason) {
setState(() {
_current = index;
});
}
),
items: imageSliders,
)
),
Positioned(
top: 50,
right: 10,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: imgList.map((url) {
int index = imgList.indexOf(url);
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index
? Colors.white60
: Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
),
],
),
);
}
}
And you may add custom indicators too.
The easiest way is to use CarouselSlider with the AnimatedSmoothIndicator widget
int _current = 0;
#override
Widget build(BuildContext context) {
Column(children: [
CarouselSlider(
options: CarouselOptions(
height: MediaQuery.of(context).size.height / 2,
onPageChanged: (i, r) {
setState(() {
_current = i;
});
}),
items: imageList.map((e) => Container(
child: Image.network(e, fit: BoxFit.cover),
))
.toList(),
),
Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
child: AnimatedSmoothIndicator(
activeIndex: _current,
count: imageList.length,
effect: ExpandingDotsEffect(
activeDotColor: Color.fromRGBO(0, 0, 0, 0.9),
dotWidth: 8,
dotHeight: 8),
),
)
]);
add auto slider code for flutter like this....
output screen shorts is here
class _ProductDetailsState extends State<ProductDetails> {
List imageSliders = [
'assets/images/man_1.png',
'assets/images/man_2.png',
'assets/images/man_3.png',
'assets/images/woman_1.png',
'assets/images/woman_2.png',
'assets/images/woman_3.png',
'assets/images/woman_4.png',
'assets/images/woman_5.png',
'assets/images/woman_6.png',
'assets/images/woman_7.png',
];
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFF000000),
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: null,
statusBarColor: Color(0xFFFFFFFF),
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.dark,
));
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
leading: Padding(
padding: const EdgeInsets.only(
left: 20,
top: 10,
),
child: IconButton(
icon: Icon(
Icons.keyboard_backspace_sharp,
size: 35,
color: Colors.grey[600],
),
onPressed: () => Navigator.of(context).pop(),
),
),
actions: [
Padding(
padding: const EdgeInsets.only(
left: 0,
top: 10,
),
child: IconButton(
icon: const Icon(
Icons.search_outlined,
color: Colors.black,
size: 30,
),
onPressed: () {},
),
),
Padding(
padding: const EdgeInsets.only(
left: 0,
top: 10,
right: 20,
),
child: IconButton(
icon: Stack(
children: [
if (_newNotification)
Positioned(
right: 1,
top: 1,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.red),
width: 20.0 / 2.5,
height: 20.0 / 2.5,
),
),
Icon(
Icons.notifications_none_outlined,
color: Colors.black,
size: 30,
)
],
),
onPressed: () {},
),
),
],
),
body: Column(
children: [
Container(
child: CarouselSlider(
options: CarouselOptions(
height: 200,
viewportFraction: .6,
aspectRatio: 1.2,
enlargeCenterPage: true,
scrollDirection: Axis.horizontal,
autoPlay: true,
onPageChanged: (index, reason) {
setState(() {
activeIndex = index;
});
}
),
items: [
for(var item in imageSliders ) Image.asset(item)
],
)
),
Positioned(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: imageSliders.map((url) {
int index = imageSliders.indexOf(url);
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 4.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: activeIndex == index
? Colors.blue
: Color.fromRGBO(0, 0, 0, 0.4),
),
);
}).toList(),
),
),
],
),
);
}
}
Related
import 'package:bubble/bubble.dart';
import 'package:dialogflow_flutter/dialogflowFlutter.dart';
import 'package:dialogflow_flutter/googleAuth.dart';
import 'package:dialogflow_flutter/language.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ChatBotScreen extends StatefulWidget {
const ChatBotScreen({Key? key}) : super(key: key);
#override
_ChatBotScreenState createState() => _ChatBotScreenState();
}
class _ChatBotScreenState extends State<ChatBotScreen> {
///Dialogflow
void response(query) async {
AuthGoogle authGoogle = await AuthGoogle(fileJson: "assets/services.json").build();
DialogFlow dialogflow = DialogFlow(authGoogle: authGoogle, language: Language.english);
AIResponse aiResponse = await dialogflow.detectIntent(query);
setState(() {
messages.insert(0, {"data": 0, "message":
aiResponse.getListMessage()![0]["text"]["text"][0].toString()
}
);
}
);
}
final messageInsert = TextEditingController();
///list where needed fixing i guess
List<Map> messages = [];
#override
Widget build(BuildContext context) {
return Scaffold(backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.black87,
centerTitle: false,
toolbarHeight: 100,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
),
elevation: 10,
title: const Text("LAIRA",
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
fontSize: 24,
),
),
),
body: Column(
children: <Widget>[
Flexible(
///listview builder
child: ListView.builder(
reverse: true,
itemCount: messages.length,
itemBuilder: (context, index) => chat(
messages[index]["message"].toString(),
messages[index]["data"]
)
)
),
///divider
const Divider(
color: Colors.white,
height: 6.0,
),
Container(
padding: const EdgeInsets.only(left: 15.0, right: 15.0, bottom: 10, top: 10),
///Textfield
margin: const EdgeInsets.symmetric(horizontal: 8.0),
child: Row(
children: [
Flexible(
child: TextField(
controller: messageInsert,
decoration: InputDecoration(
fillColor: Colors.grey[200],
contentPadding:
const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
),
),
hintText: "Type your message...",
hintStyle: const TextStyle(
fontFamily: 'Lato',
fontSize: 18.0)),
)
),
///onpressed send
Container(
margin: const EdgeInsets.symmetric(horizontal: 4.0),
child: IconButton(
icon: const Icon(
Icons.send,
size: 30.0,
),
onPressed: () {
if (messageInsert.text.isEmpty) {
if (kDebugMode) {
print("empty message");
}
} else {
setState(() {
messages.insert(0, {"data": 1, "message": messageInsert.text});
});
response(messageInsert.text);
messageInsert.clear();
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}
}
),
)
],
),
),
const SizedBox(
height: 15.0,
)
],
),
);
}
///chat system
Widget chat(String message, int data) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Bubble(
radius: const Radius.circular(10.0),
color: data == 0 ? Colors.blue : Colors.black87,
elevation: 5,
alignment: data == 0 ? Alignment.topLeft : Alignment.topRight,
nip: data == 0 ? BubbleNip.leftBottom : BubbleNip.rightTop,
child: Padding(
padding: const EdgeInsets.all(7.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// CircleAvatar(
// backgroundImage: AssetImage(
// data == 0 ? "assets/bot.png" : "assets/user.png"),
// ),
const SizedBox(
width: 10.0,
),
Flexible(
child: Text(
message,
style: const TextStyle(
color: Colors.white,
fontSize: 19,
fontFamily: 'Lato'
),
)
)
],
),
)
),
);
}
}
I have defined a variable named data in the Controller class. I am getting the error I mentioned above in the fillWordlist method. I created listview.builder in the historyWordList method in the view class. but the list does not appear on the screen and I am getting this error. 'List<Word?>' is not a subtype of type 'List' of 'val'E/flutter (29035): #0 RxObjectMixin.value= (package:get/get_rx/src/rx_types/rx_core/rx_impl .darts)
E/flutter (29035): #1 WordController.fillWordList (package:your_research_translation/controller/word_controller.dart:56:10)'
Controller.class
class WordController extends GetxController {
TextEditingController controllerInput1 = TextEditingController();
TextEditingController controllerInput2 = TextEditingController();
RxBool active2 = false.obs;
final translator = GoogleTranslator();
RxList data = <Word>[].obs;
#override
void onInit() {
fillWordList();
super.onInit();
}
onClickIconButtonFavori() {
if (controllerInput1.text.isNotEmpty && controllerInput2.text.isNotEmpty) {
addNote();
clear();
}
}
showText() {
if (active2.value == true) {
return;
}
active2.toggle();
}
ekle(Word word) async {
var val = await WordRepo().add(word);
showDilog("Kayıt Başarılı");
update();
return val;
}
updateWord(Word word) async {
var val = await WordRepo().update(word);
showDilog("Kayıt Başarılı");
return val;
}
deleteWord(int? id) async {
var val = await WordRepo().deleteById(id!);
return val;
}
fillWordList() async {
data.value = await WordRepo().getAll();
}
translateLanguage(String newValue) async {
if (newValue == null || newValue.length == 0) {
return;
}
List list = ["I", "i"];
if (newValue.length == 1 && !list.contains(newValue)) {
return;
}
var translate = await translator.translate(newValue, from: 'en', to: 'tr');
controllerInput2.text = translate.toString();
return translate;
}
showDilog(String message) {
Get.defaultDialog(title: "Bilgi", middleText: message);
}
addNote() async {
var word =
Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
await ekle(word);
fillWordList();
}
clear() {
controllerInput2.clear();
controllerInput1.clear();
}
updateNote() async {
var word =
Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
await updateWord(word);
await fillWordList();
update();
}
}
view class: Main_page.dart
class MainPage extends StatelessWidget {
String _firstLanguage = "English";
String _secondLanguage = "Turkish";
WordController controller = Get.put(WordController());
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: _drawer,
backgroundColor: Colors.grey.shade300,
appBar: _appbar,
body: _bodyScaffold,
floatingActionButton: _floattingActionButton,
);
}
SingleChildScrollView get _bodyScaffold {
return SingleChildScrollView(
child: Column(
children: [
chooseLanguage,
translateTextView,
//futureBuilder,
],
),
);
}
AppBar get _appbar {
return AppBar(
backgroundColor: Colors.blueAccent,
centerTitle: true,
title: Text("TRANSLATE"),
elevation: 0.0,
);
}
get chooseLanguage => Container(
height: Get.height / 12.0,
decoration: buildBoxDecoration,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
firstChooseLanguage,
changeLanguageButton,
secondChooseLanguage,
],
),
);
get buildBoxDecoration {
return BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
width: 3.5,
color: Colors.grey,
),
),
);
}
get translateTextView => Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
margin: EdgeInsets.only(left: 2.0, right: 2.0, top: 2.0),
child: _formTextField,
),
Obx(
() => Container(
height: controller.active2 == true
? Get.height / 2.3
: Get.height / 1.6,
child: historyWordList,
),
)
],
);
Widget get historyWordList {
return ListView.builder(
itemCount: controller.data.length,
itemBuilder: (context, index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
margin: EdgeInsets.only(left: 8.0, right: 8.0, top: 0.8),
child: Container(
color: Colors.white30,
padding: EdgeInsets.only(left: 8.0, top: 8.0, bottom: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Obx(()=>Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
firstText(controller.data[index].value),
secondText(controller.data[index].value),
],
)),
historyIconbutton,
],
),
),
);
},
);
}
get _formTextField {
return Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.white30,
height: Get.height / 6.0,
padding: EdgeInsets.only(left: 16.0, top: 8.0, bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
textFormFieldEntr, //one textfield
favoriIconButton,
],
),
),
textFormField, //burası kapandı // second
],
),
);
}
get textFormFieldEntr {
return Flexible(
child: Container(
height: Get.height / 5.2,
child: TextFormField(
readOnly: true, //sadece okuma
onTap: () {
showMaterialBanner();
},
controller: controller.controllerInput1,
onChanged: (text) {
if (text.isEmpty) {
controller.active2(false);
} else {
controller.active2(true);
}
},
maxLines: 6,
decoration: InputDecoration(
hintText: "Enter",
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
),
);
}
void showMaterialBanner() {
ScaffoldMessenger.of(Get.context!).showMaterialBanner(MaterialBanner(
backgroundColor: Colors.white,
content: Padding(
padding: const EdgeInsets.only(top: 40.0),
child: Column(
children: [
TextFormField(
controller: controller.controllerInput1,
maxLines: 7,
onChanged: (text) {
controller.translateLanguage(text);
if (text.isNotEmpty) {
controller.showText();
}
// controller.showText();
},
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: () {
if (controller.controllerInput1.text.length > 0) {
controller.clear();
} else {
controller.clear();
closeBanner();
}
},
icon: Icon(Icons.clear),
),
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
SizedBox(height: Get.height / 6.0),
TextFormField(
controller: controller.controllerInput2,
maxLines: 7,
onTap: () {
if (controller.controllerInput1.text.isEmpty) {
controller.clear();
} else {
controller.addNote();
}
closeBanner();
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
],
),
),
actions: [
IconButton(
onPressed: () {
closeBanner();
},
icon: Icon(null),
),
]));
}
void closeBanner() {
ScaffoldMessenger.of(Get.context!).hideCurrentMaterialBanner();
}
get textFormField {
return Obx(() {
return Container(
child: Visibility(
visible: controller.active2.value, //false
child: Container(
color: Colors.white30,
height: Get.height / 5.2,
padding:
EdgeInsets.only(left: 16.0, right: 42.0, top: 8.0, bottom: 8.0),
child: TextFormField(
readOnly: true,
controller: controller.controllerInput2,
maxLines: 6,
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
),
),
),
),
);
});
}
IconButton get historyIconbutton {
return IconButton(
onPressed: () {},
icon: Icon(Icons.history),
iconSize: 30.0,
);
}
Text firstText(Word word) {
return Text(
"İngilizce: ${word.wordEn ?? ""}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}
get changeLanguageButton {
return Material(
color: Colors.white,
child: IconButton(
icon: Icon(
Icons.wifi_protected_setup_rounded,
color: Colors.indigo,
size: 30.0,
),
onPressed: () {},
),
);
}
get secondChooseLanguage {
return Expanded(
child: Material(
color: Colors.white,
child: InkWell(
onTap: () {},
child: Center(
child: Text(
this._secondLanguage,
style: TextStyle(
color: Colors.blue[600],
fontSize: 22.0,
),
),
),
),
),
);
}
get firstChooseLanguage {
return Expanded(
child: Material(
color: Colors.white,
child: InkWell(
onTap: () {},
child: Center(
child: Text(
this._firstLanguage,
style: TextStyle(
color: Colors.blue[600],
fontSize: 22.0,
),
),
),
),
),
);
}
Text secondText(Word word) {
return Text(
"Türkçe: ${word.wordTr ?? ""}",
style: TextStyle(
fontWeight: FontWeight.w400,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}
get favoriIconButton {
return IconButton(
alignment: Alignment.topRight,
onPressed: controller.onClickIconButtonFavori,
icon: Icon(
Icons.forward,
color: Colors.blueAccent,
size: 28.0,
),
);
}
FloatingActionButton get _floattingActionButton {
return FloatingActionButton(
onPressed: () {
Get.to(WordListPage());
},
child: Icon(
Icons.app_registration,
size: 30,
),
);
}
Drawer get _drawer {
return Drawer(
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
userAccountsDrawerHeader,
drawerFavorilerim,
drawersettings,
drawerContacts,
],
),
);
}
ListTile get drawerContacts {
return ListTile(
leading: Icon(Icons.contacts),
title: Text("Contact Us"),
onTap: () {
Get.back();
},
);
}
ListTile get drawersettings {
return ListTile(
leading: Icon(Icons.settings),
title: Text("Settings"),
onTap: () {
Get.back();
},
);
}
ListTile get drawerFavorilerim {
return ListTile(
leading: Icon(
Icons.star,
color: Colors.yellow,
),
title: Text("Favorilerim"),
onTap: () {
Get.to(FavoriListPage());
},
);
}
UserAccountsDrawerHeader get userAccountsDrawerHeader {
return UserAccountsDrawerHeader(
accountName: Text("UserName"),
accountEmail: Text("E-mail"),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.grey,
child: Text(
"",
style: TextStyle(fontSize: 40.0),
),
),
);
}
}
This error is due to null safety. Try adding ! after every instance of word which you are passing in the function
I have a program that uses a List, but I get this error, how to fix it?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: [
CustomScrollView(physics: BouncingScrollPhysics(), slivers: [
_list(),
]),
]),
);
}
_list() {
return List.generate(
actions.length,
(i) => _card(actions[i]),
);
}
_card(
String phrase,
) {
return SliverToBoxAdapter(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.black26, width: 0.1),
borderRadius: BorderRadius.circular(10),
),
margin: EdgeInsets.only(right: 50, left: 50, top: 20),
child: InkWell(
splashColor: Colors.black12,
borderRadius: BorderRadius.circular(10),
splashFactory: InkRipple.splashFactory,
onTap: () => _speak(phrase),
child: Column(children: <Widget>[
SizedBox(height: 15.0),
Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Text(
phrase,
style: TextStyle(
fontFamily: 'Circular',
fontSize: 17.0,
color: Colors.grey[800]),
),
),
SizedBox(height: 15.0),
]),
),
),
);
}
Your method _list() returns a List<Widget>.
Therefore, you should remove the brackets in your CustomScrollView:
CustomScrollView(physics: BouncingScrollPhysics(), slivers: _list()),
I was working on merging few images and display it as one.
I have two dart files one is for adding images and other is for displaying the merged result.
first file code is,
class SingleImageUpload extends StatefulWidget {
#override
_SingleImageUploadState createState() {
return _SingleImageUploadState();
}
}
class _SingleImageUploadState extends State<SingleImageUpload> {
List<Object> images = List<Object>();
File _selectedFile;
bool _inProcess = false;
Map data = {};
Readerservice _readerservice;
#override
void initState() {
// TODO: implement initState
super.initState();
setState(() {
images.add("Add Image");
images.add("Add Image");
images.add("Add Image");
images.add("Add Image");
});
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: Padding(
padding: EdgeInsets.only(left: 12),
child: IconButton(
icon: Icon(Icons.arrow_back_ios,
color: Colors.black,
size: 30,),
onPressed: () {
Navigator.pushNamed(context, '/');
},
),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:<Widget>[
Text('Basic AppBar'),
]
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.more_vert,
color: Colors.black,
size: 30,),
onPressed: () {
print('Click start');
},
),
],
),
body:
Column(
children: <Widget>[
SizedBox(height: 10),
Row(children: <Widget>[
Text('Image',
style: TextStyle(
color: Colors.black,
fontSize: 33,
fontWeight: FontWeight.bold,
)),
Text('Merger',
style: TextStyle(
color: Colors.orange,
fontSize: 33,
fontWeight: FontWeight.bold,
)),
]),
SizedBox(height: 40),
Text(' merge it here'),
SizedBox(height: 10),
Expanded(
child: buildGridView(),
),
RaisedButton(
textColor: Colors.white,
color: Colors.orange,
child: Text("Finish",
style: TextStyle(fontSize: 15),),
onPressed: () {
pasimage();
},
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0),
),
),
],
),
),
);
}
Widget buildGridView() {
return GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
childAspectRatio: 1,
children: List.generate(images.length, (index) {
if (images[index] is ImageUploadModel) {
ImageUploadModel uploadModel = images[index];
return Card(
clipBehavior: Clip.antiAlias,
child: Stack(
children: <Widget>[
Image.file(
uploadModel.imageFile,
width: 300,
height: 300,
),
Positioned(
right: 5,
top: 5,
child: InkWell(
child: Icon(
Icons.remove_circle,
size: 20,
color: Colors.red,
),
onTap: () {
setState(() {
images.replaceRange(index, index + 1, ['Add Image']);
});
},
),
),
],
),
);
} else {
return Card(
child: IconButton(
icon: Icon(Icons.add),
onPressed: () {
//popup
showDialog(
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
elevation: 16,
child: Container(
height: 180.0,
width: 330.0,
child: ListView(
children: <Widget>[
SizedBox(height: 20),
//Center(
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
"Add a Receipt",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 24,
color: Colors.black,
fontWeight: FontWeight.bold),
),
),
// ),
SizedBox(height: 20),
FlatButton(
child: Text(
'Take a photo..',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 20),
),
onPressed: () {
_onAddImageClick(index,ImageSource.camera);
Navigator.of(context).pop();
// picker.getImage(ImageSource.camera);
},
textColor: Colors.black,
),
FlatButton(
child: Text(
'Choose from Library..',
style: TextStyle(fontSize: 20),
textAlign: TextAlign.left,
),
onPressed: () {
_onAddImageClick(index,ImageSource.gallery);
Navigator.of(context).pop();
},
textColor: Colors.black,
),
],
),
),
);
},
);
//pop ends
},
),
);
}
}),
);
}
Future _onAddImageClick(int index, ImageSource source ) async {
setState(() {
_inProcess = true;
});
File image = await ImagePicker.pickImage(source: source);
if(image != null){
File cropped = await ImageCropper.cropImage(
sourcePath: image.path,
maxWidth: 1080,
maxHeight: 1080,
compressFormat: ImageCompressFormat.jpg,
androidUiSettings: AndroidUiSettings(
toolbarColor: Colors.black,
toolbarWidgetColor: Colors.white,
//toolbarTitle: "RPS Cropper",
statusBarColor: Colors.deepOrange.shade900,
backgroundColor: Colors.black,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false
),
iosUiSettings: IOSUiSettings(
minimumAspectRatio: 1.0,
)
);
this.setState((){
_selectedFile = cropped ;
_inProcess = false;
});
} else {
this.setState((){
_inProcess = false;
});
}
getFileImage(index);
}
void getFileImage(int index) async {
// var dir = await path_provider.getTemporaryDirectory();
setState(() {
ImageUploadModel imageUpload = new ImageUploadModel();
imageUpload.isUploaded = false;
imageUpload.uploading = false;
imageUpload.imageFile = _selectedFile;
imageUpload.imageUrl = '';
images.replaceRange(index, index + 1, [imageUpload]);
});
}
void pasimage(){
Navigator.pushReplacementNamed(context, '/crop',arguments: {
'imageList':ImagesMerge(
images,///required,images list
direction: Axis.vertical,///direction
backgroundColor: Colors.black26,///background color
fit: false,///scale image to fit others
),
});
}
}
class ImageUploadModel {
bool isUploaded;
bool uploading;
File imageFile;
String imageUrl;
ImageUploadModel({
this.isUploaded,
this.uploading,
this.imageFile,
this.imageUrl,
});
}
when I tap the finish button after adding the images it shows an error
The following _TypeError was thrown while handling a gesture:
type 'List' is not a subtype of type 'List'
The page just on captures the data sent from the code above and display the image.
please if anyone know why is the error and help me .
Change the images to List<Object> images = [].
Hi I have designed a List view wrapped with flatbutton but I am not able to get index after clicking the list view below is the code. I am wraped with GestureDetector.
List<GestureDetector> _buildListItemsfromFlower() {
return ExcerciselistPojo.randomList.map((flowers) {
var flatbutton = GestureDetector(
child: Card(
elevation: 2.0,
child: new Row(
textBaseline: TextBaseline.alphabetic,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Container(
child: new Column(
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.height / 15,
margin: EdgeInsets.fromLTRB(0, 5, 0, 0),
child: new Text(
flowers.name,
style: TextStyle(
color: Colors.black,
fontSize: 20,
decoration: TextDecoration.none),
),
),
new Container(
margin: EdgeInsets.fromLTRB(15, 10, 0, 0),
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.height / 15,
child: new Text(
flowers.duration,
style: TextStyle(
color: Colors.pink,
fontSize: 20,
decoration: TextDecoration.none),
)),
],
)),
new Container(
margin: new EdgeInsets.fromLTRB(55, 0, 0, 0),
child: ImageSequenceAnimator(
"assets/images/" + flowers.imageUrl,
"Pic_",
0,
5,
"webp",
3,
isAutoPlay: true,
color: null,
fps: 2,
isBoomerang: false,
isLooping: true,
),
width: 80,
height: 80,
),
],
)));
return GestureDetector(
child: flatbutton,
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ExcerciseDetails(
ExcerciselistPojo.randomList[2].name,
ExcerciselistPojo.randomList[2].image,
ExcerciselistPojo.randomList[2].description),
));
},
);
}).toList();
}
I want to to next dart file with index value. Please let me know how to get index value after clicking the above list view.
You need to put your ExcerciselistPojo.randomList inside a variable and access the index from the list
var yourRandomList = ExcerciselistPojo.randomList;
yourRandomList.map((flowers) {
int index = yourRandomList.indexWhere((flowersInside) => flowers.imageUrl == flowersInside.imageUrl);
}).toList();
Perhaps a look at ListView.builder examples would help you find the answer you seek.