flutter problem: My FAQs ui is not what I want - flutter

I have this problem that I want to make my FAQs UI like Original UI but i cant making like that.
I have this problem that I want to make my FAQs UI like Original UI but i cant making like that.
I want like this UI.
But its creating like this.
My UI is not matching please help me How to make it like original.
This is my code.
import 'package:cwc/constants/constants.dart';
import 'package:flutter/material.dart';
import '../skeleton.dart';
class FAQPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return FAQPageState();
}
}
class FAQPageState extends State<FAQPage> {
bool isExpand = false;
var selected;
#override
void initState() {
// TODO: implement initState
super.initState();
isExpand = false;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffffffff),
appBar: AppBar(
elevation: 0.5,
leading: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_back,
color: Colors.black,
size: tSize24,
)),
centerTitle: true,
backgroundColor: Colors.white,
),
body: isFAQLoading == true
? ButtonSkeleton()
: ListView.builder(
itemCount: faqListData.length,
itemBuilder: (context, index) {
return Column(children: <Widget>[
Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(1.0, 1.0),
spreadRadius: 0.2)
]),
child: Card(
elevation: 0,
shadowColor: Colors.grey,
margin: EdgeInsets.only(
bottom: 3,
),
child: ExpansionTile(
key: Key(index.toString()),
backgroundColor: Color(0xfff6f7f9),
initiallyExpanded: index == selected,
iconColor: Colors.grey,
title: Text(
'${faqListData[index]['question']}',
style: TextStyle(
color: Color(0xFF444444),
fontSize: tSize14,
fontWeight: FontWeight.w500),
),
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 10.0, bottom: 10, left: 17, right: 17),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Text(
"${faqListData[index]['answer']}",
style: TextStyle(
color: Color(0xFF444444),
fontSize: 13,
),
textAlign: TextAlign.start,
),
),
],
))
],
onExpansionChanged: ((newState) {
isExpand = newState;
print(newState);
if (newState)
setState(() {
Duration(seconds: 20000);
selected = index;
// isExpand=newState;
});
else
setState(() {
selected = -1;
// isExpand=newState;
});
print(selected);
})),
),
),
]);
}),
);
}
}

Hi I checked your code and looks just small thing is missing. When you are passing key to the Exapnsion tile you need to pass same key to ListView.builder then it works fine.
ListView.builder(
key: Key('builder ${selected.toString()}'),
itemCount: faqListData.length,
...
...
);

Related

Listview not showing on startup but shows after rebuilding/refreshing - Flutter

I need some help please. On startup, everything loads except the listview. When I do anything on the page the listview appears. Feels like a refresh/rebuild issue. How do I tell it to refresh the listview? I don't know where to maybe use setState (doesn't work in Scaffold)
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildBar(context),
body: HouseLayout(),
);}
class HouseLayout extends StatefulWidget {
#override
HouseLayoutState createState() {
return HouseLayoutState();
}
}
class HouseLayoutState extends State<HouseLayout> with TickerProviderStateMixin {
#override
Widget build(BuildContext context) {
int y = 0;
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(taal.HuisTitle,
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.white,
fontSize: 28,
)),
backgroundColor: Color.fromRGBO(61, 147, 243, 1.0)),
body: Stack(alignment: Alignment.bottomLeft, children: [
Column(children: [
Expanded(
flex: 10,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, indexA) {
var kasNaam = kaste[indexA];
return Padding(
padding: EdgeInsets.all(0.0),
child: Column(children: <Widget>[
Card(
color: Color.fromRGBO(96, 166, 243, 1.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$kasNaam',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.white,
fontSize: 20,
),
),
),
Container(
child: Row(
children: [
IconButton(
icon: Icon(Icons.edit,
color: Colors.white),
onPressed: () {
setState(() {
_editKasDialog(indexA);
});
}),
IconButton(
icon: Icon(Icons.delete,
color: Colors.white),
onPressed: () {
setState(() {
for (int i = 0;
i < kruideniers.length;
i++) {
if (kruideniers[i].kas ==
kaste[indexA]) {
y++;
}
}
if (y != 0) {
_deleteNotPossibleDialog(y);
}
if (y == 0) {
_deleteKasConfirmDialog(indexA);
}
});
}),
],
),
),
]),
),
_isSearching
? _buildSearchList(context, kasNaam)
: _bouKruideniersLys(context, kasNaam),
]),
);
},
itemCount: kaste.length,
)),
Container(height: 40),
]),
Container(color: Color.fromRGBO(61, 147, 243, 1.0), height: 40),
Positioned(
bottom: 0,
right: 0,
child: Stack(children: [
Container(width: 300, height: 350),
Positioned(...),
Positioned(...),
Positioned(...),
Positioned(...),
Positioned(...),
Container(width: 5, height: 5),
Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
elevation: 5,
shape: CircleBorder(),
backgroundColor: Color.fromRGBO(16, 124, 243, 1.0),
child: SizedBox(
width: 56,
height: 56,
child: Icon(Icons.shopping_cart,
size: 35, color: Colors.white)),
splashColor: Colors.yellow,
onPressed: () {
setState(() {
Navigator.pushNamed(context, '/shop');
});
},
heroTag: null)),
],
),
),
]),
)
]));
}
Any help will be great! Thanks
I read kaste list from a txt file:
List<String> kaste = [];
void readFileH() async {
final fileH = await findFileH();
List<String> contents = await fileH.readAsLines();
String kas;
for (int i = 0; i < contents.length; i++) {
kas = contents[i].substring(0, contents[i].indexOf("#"));
contents[i] = contents[i].replaceRange(0, contents[i].indexOf("#") + 1, "");
kaste.add(kas);
}
kaste.sort();
}
Hi the problem is that the data is null when flutter render the ListView because the data isn't loaded, you need to use a wrap your ListView into a future builder, while the data is loading you can put a image or a circular progress indicator, when the data is loaded you render the elements into a ListView

ListTile key not found in Flutter

I have a List defined as below and I'm trying to highlight one element of the list during the tutorial. I am currently using Tutorial Coach Mark. Every time I debug my app it shows me
KEY information could not be obtained
I don't know why this is happening as I've followed all the necessary steps for integration shown in the dependency.
This is my code:
class _SettingsState extends State<Settings> {
TutorialCoachMark tutorialCoachMark;
GlobalKey keyButton3 = GlobalKey();
List<TargetFocus> targets = List();
void initState() {
initTarget();
WidgetsBinding.instance.addPostFrameCallback(_afterLayouts);
super.initState();
}
void _afterLayouts(_) {
Future.delayed(Duration(milliseconds: 100), () {
showTutorial(context);
});
}
void showTutorial(context) {
tutorialCoachMark = TutorialCoachMark(context,
targets: targets,
colorShadow: Colors.red,
textSkip: "SKIP",
paddingFocus: 10,
opacityShadow: 0.8, onFinish: () {
print("finish");
}, onClickTarget: (target) {
print(target);
}, onClickSkip: () {
print("skip");
})
..show();
}
void initTarget() {
targets.add(
TargetFocus(
//claim reward
identify: "Target 2",
keyTarget: keyButton3,
color: Colors.purple,
contents: [
ContentTarget(
align: AlignContent.bottom,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Click here",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20.0),
),
],
),
))
],
shape: ShapeLightFocus.RRect,
radius: 6),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
iconTheme: IconThemeData(
color: Colors.white,
),
elevation: 0,
title: Text(
'Settings',
style: kTasksStyle,
),
backgroundColor: Color(0xff0C7368),
),
body: Stack(
children: [
Padding(
padding: const EdgeInsets.only(top: 8),
child: ListView.separated(
separatorBuilder: (context, index) => Divider(
height: 2,
color: Colors.grey.withOpacity(0.3),
),
itemCount: 5,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(5.0),
child: ListTile(
key: index == 0 ? keyButton3 : null,// to highlight the 0th index of the list only
title: Text(
"Hello",
style: kTasksStyle.copyWith(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.normal),
),
leading: Icon(
Icons.supervised_user_circle,
color: Color(0xff0C7368),
),
),
);
}),
)
],
));
}
}
I am trying to achieve something similar to this:

Change state from another widget in flutter?

I am trying to make a cart icon with a text of the number of items in the cart. This requires a state refresh when state refreshes in another widget. Even though not recommended, I tried setState(), but as warned the widget was not mounted so setState() was called on null.
Then I came to know about Value listenable from this post How to set state from another widget?
I tried this, but it says "NoSuchMethodError: the getter 'value' was called on null, maybe my implementation was wrong.
heres my code:
var menuJson = [];
var isLoading = true;
class CartIcon extends StatefulWidget {
const CartIcon({Key key2}) : super(key: key2);
#override
_CartIcon createState() => _CartIcon();
}
class _CartIcon extends State<CartIcon> {
#override
Widget build(BuildContext context) {
var filteredList = List();
for (var item in menuJson) {
if (item["quantity"] > 0) {
filteredList.add(item);
}
}
return Padding(
padding: const EdgeInsets.only(top: 35, right: 8),
child: Container(
width: AppBar().preferredSize.height - 12,
height: AppBar().preferredSize.height - 12,
color: Colors.pink,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(AppBar().preferredSize.height),
child: Stack(
children: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_cart,
color: Colors.white,
),
onPressed: null,
),
filteredList.length == 0
? Container()
: Positioned(
child: Stack(
children: <Widget>[
Icon(Icons.brightness_1,
size: 20.0, color: Colors.green[800]),
Positioned(
top: 3.0,
right: 4.0,
child: Text(
filteredList.length.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 11.0,
fontWeight: FontWeight.w500),
))
],
)),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CartPage()),
);
},
),
),
),
);
}
}
class Salads extends StatefulWidget {
const Salads({Key key2}) : super(key: key2);
#override
_Salads createState() => _Salads();
}
class _Salads extends State<Salads> {
final _counter = new ValueNotifier(0);
plus(index) {
var quant = menuJson[index]["quantity"];
quant++;
menuJson[index]["quantity"] = quant;
setState(() {});
}
minus(index) {
var quant = menuJson[index]["quantity"];
quant--;
if (quant < 0) {
quant = 0;
}
menuJson[index]["quantity"] = quant;
setState(() {});
}
#override
Widget build(BuildContext context) {
var filteredList = List();
for (var item in menuJson) {
if (item["category_name"] == "Salads") {
filteredList.add(item);
}
}
if (isLoading) {
return Center(
child: new CircularProgressIndicator(),
);
} else {
return Container(
color: Colors.green,
child: ListView.builder(
itemCount: filteredList.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0, left: 10.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.only(
left: 5, top: 5, bottom: 30),
child: Text(
filteredList[index]["dish_name"],
style: TextStyle(fontSize: 20),
textAlign: TextAlign.left,
),
),
Container(
padding: EdgeInsets.only(
right: 5, top: 5, bottom: 30),
child: Text(
'\u{20B9} ' +
filteredList[index]["price"]
.toString(),
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 20),
textAlign: TextAlign.right,
)),
]),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RawMaterialButton(
onPressed: () =>
plus(filteredList[index]["index"]),
child: new Icon(
Icons.add,
color: Colors.black,
),
fillColor: Colors.white,
shape: CircleBorder(),
),
Text(filteredList[index]["quantity"].toString(),
style: new TextStyle(fontSize: 40.0)),
RawMaterialButton(
onPressed: () =>
minus(filteredList[index]["index"]),
child: new Icon(
const IconData(0xe15b,
fontFamily: 'MaterialIcons'),
color: Colors.black,
),
fillColor: Colors.white,
shape: CircleBorder(),
padding: EdgeInsets.all(0),
)
])
],
)));
}),
);
}
}
}
Since cart icon is in the app bar, it is higher in the widget tree.
How can I make such that when + is pressed in 'Salads' the CartIcon state updates in the appbar? Right now it updates the state when i tap on the cart button.
Maybe use a Global Key?
GlobalKey<_CartIcon> cartKey = GlobalKey<_CartIcon>();
When making your CartIcon insert the globalKey.
Make a new Method inside _CartIcon:
refresh(){
setState((){})
}
and when you want to refresh your CartIcon call:
cartKey.currentState.refresh();

How to add item in a listview from one class to another in Flutter?

I am working on a project in which i have a class which has a row that has two children. Child one contains a TabView with a child class TabViewChild in which i am generating a gridview. On the other hand child two contains a listView. So the problem is, when i click on the gridview item i am passing that item's value to a static list and passing that list to a listview of other class. But i have no idea how to change the state of that class on item clicked or how can i achieve this task in a better way as i am new to Flutter. I want that when a person click on any gridview's item that item appears in the listview simultaneously.
class ItemMenus {
int id;
String code;
String name;
String salePrice;
String photo;
String categoryName;
String percentage;
int quantity;
ItemMenus({this.id, this.code, this.name, this.salePrice, this.photo,
this.categoryName, this.percentage, this.quantity});
ItemMenus.fromJson(Map<String, dynamic> json)
:
id = int.parse(json['id']),
code = json['code'],
name = json['name'],
salePrice = json['sale_price'],
photo = json['photo'],
categoryName = json['category_name'],
percentage = json['percentage'];
#override
String toString() {
return 'ItemMenus{id: $id, code: $code, name: $name, salePrice: $salePrice, photo: $photo, categoryName: $categoryName, percentage: $percentage}';
}
}
import 'package:food_app/model/mdl_item_menus.dart';
class ItemMenuList{
List<ItemMenus> _itmMenuLst = [];
ItemMenuList._();
static final ItemMenuList instanceItmMenuLst = ItemMenuList._();
static ItemMenuList get instance => instanceItmMenuLst;
void addItem(ItemMenus im){
_itmMenuLst.add(im);
}
List<ItemMenus> get list => _itmMenuLst;
#override
String toString() {
return 'ItemMenuList{_itmMenuLst: $_itmMenuLst}';
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_categories.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_categories.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/tab_bar_view.dart';
class EPos extends StatefulWidget{
#override
_EPosState createState() => _EPosState();
}
class _EPosState extends State<EPos> {
final categoryDBHelper = TblCategories.categoriesInstance;
final ItemMenuList instance2 = ItemMenuList.instance;
String _orderType = 'Dine-In', _info = 'Table No. 1', _userName = 'ZiaUddin';
List<Categories> catLst = [];
List<ItemMenus> itmLst = [];
Future getCategories() async {
catLst.clear();
var categories = await categoryDBHelper.getCategories();
categories.forEach((element) {
catLst.add(Categories(
id: element['id'],
categoryName: element['category_name'],
description: element['description'],
userId: element['user_id'],
companyId: element['company_id'],
delStatus: element['del_status']));
});
catLst.forEach((element) {
print(element);
});
return catLst;
}
#override
void initState() {
// TODO: implement initState
super.initState();
// itmLst = instance2.list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
//#region AppBar
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.15,
color: Colors.redAccent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(20),
color: Colors.red,
),
child: Row(
children: [
Icon(
Icons.arrow_back,
color: Colors.white,
size: 25,
),
Padding(
padding: const EdgeInsets.fromLTRB(4, 8, 10, 8),
child: Text(
_orderType,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.red,
),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 20, 8),
child: Text(
_info,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.amberAccent,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
),
Container(
margin: EdgeInsets.only(top: 15, right: 5),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(30),
color: Colors.red,
),
child: Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 8, 8, 8),
child: Text(
_userName,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
CircleAvatar(
backgroundColor: Colors.red,
radius: MediaQuery.of(context).size.height * 0.041,
child: CircleAvatar(
radius: MediaQuery.of(context).size.height * 0.04,
backgroundImage: AssetImage('assets/user.png'),
),
),
],
),
),
],
),
),
//endregion
Expanded(
child: Row(
children: [
//# region Menu
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.yellowAccent,
shape: BoxShape.rectangle,
),
child: Column(
children: [
Expanded(
child: Container(
color: Colors.white,
child: FutureBuilder(
future: getCategories(),
builder: (context, snapShot) {
if (snapShot.connectionState ==
ConnectionState.none &&
snapShot.hasData == null) {
return Center(
child: CircularProgressIndicator());
}
return MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: catLst.length,
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize:
Size.fromHeight(kToolbarHeight),
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.1,
child: TabBar(
indicatorColor:
Colors.amberAccent,
isScrollable: true,
tabs: catLst
.map<Widget>((Categories c) {
return Tab(
icon: Icon(
Icons.style,
color: Colors.amberAccent,
size: 15,
),
child: Text(
c.categoryName
.toUpperCase(),
style: TextStyle(
color: Colors.black,
fontWeight:
FontWeight.w400,
),
),
);
}).toList(),
),
),
),
body: TabBarView(
children: catLst.map((Categories c) {
return TabBarViewChild(categoryName:c.categoryName,
callback: (){
setState(() {
instance2.addItem(ItemMenus(name: c.categoryName));
itmLst = instance2.list;
print('I am Callback');
});
},);
}).toList(),
),
),
),
);
}),
),
),
],
),
),
),
//endregion
//# region OrderList
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
),
child: ListView.builder(
itemCount: itmLst.length,
itemBuilder: (context, index){
return ListTile(
title: Text(itmLst[index].name),
);
},
),
),
),
//endregion
],
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_item_menus.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/new_sale.dart';
class TabBarViewChild extends StatefulWidget {
String categoryName;
VoidCallback callback;
TabBarViewChild({Key key,#required this.categoryName, this.callback}) : super(key:key);
#override
_TabBarViewChildState createState() => _TabBarViewChildState();
}
class _TabBarViewChildState extends State<TabBarViewChild> {
final ItemMenuList instance1 = ItemMenuList.instance;
List<ItemMenus> itmLst = [];
final itemMenus = TblItemMenus.itemMenusInstance;
Future getSpecificItemMenus() async{
var items = await itemMenus.getSpecificItemMenus(widget.categoryName);
itmLst.clear();
items.forEach((e) {
itmLst.add(ItemMenus(id: e['id'], categoryName: e['category_name'], code: e['code'],
name: e['name'], percentage: e['percentage'], photo: e['photo'], quantity: e['quantity'],
salePrice: e['sale_price']));
});
for (var value in itmLst) {
print(value);
}
return itmLst;
}
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: FutureBuilder(
future: getSpecificItemMenus(),
builder: (context, snapShot) {
if (snapShot.connectionState == ConnectionState.none
&& snapShot.hasData == null) {
return Center(child: CircularProgressIndicator());
}
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
scrollDirection: Axis.vertical,
itemCount: itmLst.length,
itemBuilder: (context, index){
return Padding(
padding: const EdgeInsets.all(5.0),
child: InkWell(
child: Card(
elevation: 4,
color: Colors.amberAccent,
child: Center(
child: Text(
itmLst[index].name.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.red,
fontSize: 13,
fontWeight: FontWeight.w700,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
),
onTap: (){
// Provider.of<ProItemMenus>(context, listen: false).addNewItemInList(ItemMenus(name: itmLst[index].name.toUpperCase()));
instance1.addItem(ItemMenus(categoryName: itmLst[index].name.toUpperCase()));
print(itmLst[index].name.toUpperCase());
},
),
);
}
);
}
),
);
}
}
So the problem now, there are two stateful widgets.
And as we are going to share the data or the state between them, basically we need to have more one stateful Widget which will the parent of them.
This term of is this problem known as State Management.
Currently there are many reknown State Management , such as Provider and Bloc. Reference.
But personally, I recommend to use Provider, which has simple Syntaxes and Concept.

Flutter: Slider Gallery with overflow container

I've stuck with one problem.
I'm a novice with a flutter trying to figure out how to do a simple swipe-left/swipe-right gallery.
I'm looking for a widget that supports gestures and some kind of overflow.
So I want a container with a fixed(width/height which I can define) and everything outside of this container should be hidden and when user swipes inner content it should show the next slide. Can you please point me out what is the best way to implement this with a Flutter and what is the best kind of containers fit these goals. Thanks
UPD 1:
It shouldn't be a whole screen, but a specific container.
You just need to use the PageView widget for the viewpager functionality , you can use it horizontal or vertical as your requirement,As you want horizontal PageView so i have used the scrollDirection: Axis.horizontal for it. I have created the demo of it, please check it once
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class HomeScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _HomeScreen();
}
}
class _HomeScreen extends State<HomeScreen> {
static final GlobalKey<ScaffoldState> _scaffoldKey =
GlobalKey<ScaffoldState>();
///Page Controller for the PageView
final controller = PageController(
initialPage: 0,
);
#override
Widget build(BuildContext context) {
Size _screenSize = MediaQuery.of(context).size;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
centerTitle: true,
title: Text(
'Horizontal Viewpager',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,),
),
),
///A Page View with 3 children
body: PageView(
controller: controller,
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
pageSnapping: true,
children: <Widget>[
Container(
color: Colors.white,
child: Card(
color: Colors.lightBlue,
elevation: 4,
margin: EdgeInsets.all(24),
child: Center(
child: Text(
"Card 1",
style: TextStyle(
color: Colors.white,
fontSize: 24),
),
),
),
),
Container(
color: Colors.white,
child: Card(
color: Colors.purpleAccent,
elevation: 4,
margin: EdgeInsets.all(24),
child: Center(
child: Text(
"Card 2",
style: TextStyle(
color: Colors.white,
fontSize: 24),
),
),
),
),
Container(
color: Colors.white,
child: Card(
color: Colors.pink,
elevation: 4,
margin: EdgeInsets.all(24),
child: Center(
child: Text(
"Card 3",
style: TextStyle(
color: Colors.white,
fontSize: 24),
),
),
),
),
],
),
);
}
}
And output of above program as follow
You can check my another example where i have created the swipable with fixed height Click here
I am posting another example, as you need the indicator at the both side of the PagewView for it , you need to use the Row with Expaned as follow
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class HomeScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _HomeScreen();
}
}
class _HomeScreen extends State<HomeScreen> {
static final GlobalKey<ScaffoldState> _scaffoldKey =
GlobalKey<ScaffoldState>();
var selectedPage = 0;
PageController _controller = PageController(initialPage: 0, keepPage: true);
#override
Widget build(BuildContext context) {
Size _screenSize = MediaQuery
.of(context)
.size;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
centerTitle: true,
title: Text(
'Horizontal Viewpager',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,),
),
),
///A Page View with 3 children
body: Container(
child:Container(
height: MediaQuery.of(context).size.height*0.4,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child:
IconButton(
icon: Icon(Icons.arrow_back),
highlightColor: Colors.pink,
onPressed: () {
setState(() {
if (selectedPage > 0) {
selectedPage = selectedPage - 1;
_controller.jumpToPage(selectedPage);
print("VALUES==>>>>> $selectedPage");
}
});
},
),
), Expanded(
flex: 8,
child: PageView(
controller: _controller,
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
onPageChanged: (index)
{
selectedPage= index;
},
pageSnapping: true,
children: <Widget>[
Container(
color: Colors.white,
child: Card(
color: Colors.lightBlue,
elevation: 4,
margin: EdgeInsets.all(24),
child: Center(
child: Text(
"Card 1",
style: TextStyle(
color: Colors.white,
fontSize: 24),
),
),
),
),
Container(
color: Colors.white,
child: Card(
color: Colors.purpleAccent,
elevation: 4,
margin: EdgeInsets.all(24),
child: Center(
child: Text(
"Card 2",
style: TextStyle(
color: Colors.white,
fontSize: 24),
),
),
),
),
Container(
color: Colors.white,
child: Card(
color: Colors.pink,
elevation: 4,
margin: EdgeInsets.all(24),
child: Center(
child: Text(
"Card 3",
style: TextStyle(
color: Colors.white,
fontSize: 24),
),
),
),
),
],
),
),
Expanded(
flex: 1,
child:
IconButton(
icon: Icon(Icons.arrow_forward),
highlightColor: Colors.pink,
onPressed: () {
if (selectedPage <3) {
selectedPage = selectedPage + 1;
_controller.jumpToPage(selectedPage);
print("VALUES==>> $selectedPage");
}
},
),
)
],
),
)
,
)
,
);
}
}
Please check the below output of it
You can use carousel_slider 2.1.0 package.
It also has many customisation options.
https://pub.dev/packages/carousel_slider