Why can't I keep scroll position although I use PageStorageKey? - flutter

I have used NestedScrollView and SliverAppBar to hide app bar when scrolling. In the body of NestedScrollView, I have CustomScrollView with a PageStorageKey but when I have switched back to events tab, scroll position is lost. I cannot understand it. Could you please help me?
home_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:liveitup/app/screens/HomeScreen/drawer_icon.dart';
import 'package:liveitup/app/screens/HomeScreen/drawer_page.dart';
import 'package:liveitup/app/screens/HomeScreen/tabs/bottom_navigation.dart';
import 'package:liveitup/app/screens/HomeScreen/tabs/tab_item.dart';
import 'package:liveitup/app/screens/HomeScreen/tabs/tab_navigators/event_tab_navigator.dart';
import 'package:liveitup/app/screens/HomeScreen/tabs/tab_navigators/message_tab_navigator.dart';
import 'package:liveitup/app/screens/HomeScreen/tabs/tab_navigators/notification_tab_navigator.dart';
import 'package:liveitup/blocs/UserBloc/bloc.dart';
import '../../../constants.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
var _currentTab = TabItem.events;
void _selectTab(TabItem tabItem) {
setState(() => _currentTab = tabItem);
}
#override
Widget build(BuildContext context) {
var scaffoldKey = GlobalKey<ScaffoldState>();
UserBloc _userBloc = BlocProvider.of<UserBloc>(context);
return Scaffold(
backgroundColor: Colors.blue,
drawer: DrawerPage(),
key: scaffoldKey,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 0,
pinned: false,
floating: true,
forceElevated: innerBoxIsScrolled,
backgroundColor: Colors.green,
leading: GestureDetector(
onTap: () => scaffoldKey.currentState?.openDrawer(),
child: const DrawerIcon()),
title: const Center(
child: Text(app_name),
),
actions: [
//Icon(Icons.search),
(_currentTab == TabItem.events)
? Icon(Icons.filter)
: Container(),
],
),
];
},
body: Builder(builder: (BuildContext context) {
if (_currentTab == TabItem.events) {
return CustomScrollView(
key: const PageStorageKey<TabItem>(TabItem.events),
slivers: [
SliverList(
delegate: SliverChildListDelegate([
for (var index = 1; index < 1000; index++)
Text(
index.toString(),
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 40.0,
letterSpacing: 2.0,
wordSpacing: 100.0,
),
),
])),
],
);
} else if (_currentTab == TabItem.messages) {
return const Center(
child: Text('message list'),
);
} else if (_currentTab == TabItem.notifications) {
return const Center(
child: Text('notitifcatiion list'),
);
}
return Text('notitifcatiion list');
}),
),
bottomNavigationBar: BottomNavigation(
currentTab: _currentTab,
onSelectTab: _selectTab,
),
);
}
}
tab_item.dart
import 'package:flutter/material.dart';
enum TabItem { events, messages, notifications }
const Map<TabItem, String> tabName = {
TabItem.events: 'events',
TabItem.messages: 'messages',
TabItem.notifications: 'notifications',
};
botom_navigation.dart
import 'package:flutter/material.dart';
import 'package:liveitup/app/screens/HomeScreen/tabs/tab_item.dart';
class BottomNavigation extends StatelessWidget {
BottomNavigation({required this.currentTab, required this.onSelectTab});
final TabItem currentTab;
final ValueChanged<TabItem> onSelectTab;
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: currentTab == TabItem.events ? Colors.black : Colors.grey,
),
label: tabName[TabItem.events],
),
BottomNavigationBarItem(
icon: Icon(
Icons.message,
color: currentTab == TabItem.messages ? Colors.black : Colors.grey,
),
label: tabName[TabItem.messages],
),
BottomNavigationBarItem(
icon: Icon(
Icons.notifications,
color: currentTab == TabItem.notifications
? Colors.black
: Colors.grey,
),
label: tabName[TabItem.notifications],
),
],
onTap: (index) => onSelectTab(
TabItem.values[index],
),
currentIndex: currentTab.index,
//selectedItemColor: Colors.black,
);
}
}

Related

Flutter- how to navigate different pages by curved navigation bar

i am creating a flutter app and want help on how to navigate to different pages. Also, when i tap on buttons of curved navigation bar nothing happens the icons not changing.
can u please help me out?
here is my code for the curved navigation bar
Thank u
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
class BAR extends StatefulWidget {
const BAR({super.key});
#override
State<BAR> createState() => _BARState();
}
class _BARState extends State<BAR> {
#override
Widget build(BuildContext context) {
return CurvedNavigationBar(
backgroundColor: HexColor("#F7ECCD"),
color: HexColor("#AE621C"),
items: [
Icon(
Icons.home,
color: Colors.white,
size: 30,
),
Icon(
Icons.favorite,
color: Colors.white,
size: 30,
),
Icon(
Icons.settings,
color: Colors.white,
size: 30,
)
],
onTap: (index){
setState(() {
if (index == 0) {
Navigator.pushNamed(context, '/');
}
if (index == 1) {
Navigator.pushNamed(context, '/one');
}
if (index == 2) {
Navigator.pushNamed(context, '/two');
}
});
},);
}
}
import 'package:flutter/cupertino.dart';
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.business),
title: Text('Business'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.school),
title: Text('School'),
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
backgroundColor: CupertinoColors.systemGrey,
activeColor: CupertinoColors.black,
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
builder: (BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: _widgetOptions.elementAt(index),
),
);
},
);
},
);
}
}

persistent bottom nav bar not working properly

I am trying to apply persistent_bottom_nav_bar but I keep getting error. I got similar answers and tried to follow https://pub.dev/packages/persistent_bottom_nav_bar
These are the errors that I keep getting.
The method '_BottomBarState' isn't defined for the type 'BottomBar'. & 1 positional argument(s) expected, but 0 found.
class BottomBar extends StatefulWidget {
const BottomBar({Key? key}) : super(key: key);
#override
State<BottomBar> createState() => _BottomBarState();
}
PersistentTabController _controller = PersistentTabController(initialIndex: 0);
//Screens for each nav items.
List<Widget> _NavScreens() {
return [
HomeScreen(),
const Text("History"),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_home_regular),
title: "Home",
activeColorPrimary: Colors.blueGrey,
),
PersistentBottomNavBarItem(
icon: Icon(Icons.favorite),
title: ("History"),
activeColorPrimary: CupertinoColors.activeGreen,
),
];
}
#override
Widget build(BuildContext context) {
return Center(
child: PersistentTabView(
controller: _controller,
screens: _NavScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white,
handleAndroidBackButtonPress: true,
resizeToAvoidBottomInset: true,
hideNavigationBarWhenKeyboardShows: true,
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
),
popAllScreensOnTapOfSelectedTab: true,
navBarStyle: NavBarStyle.style9,
),
);
}
This is the original bottom bar that I want to keep fixed in all screens
class _BottomBarState extends State<BottomBar> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
HomeScreen(),
const Text("History"),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
//print('Tapped index is: ${_selectedIndex}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions[_selectedIndex],
),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
...............................
items: const [
BottomNavigationBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_home_regular),
label: "Home"),
BottomNavigationBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_history_regular),
label: "History"),
],),],),);}}
How to apply presistent bottom bar to my project without changing the design? Why am I reciving this error and how to fix it.
persistent_bottom_nav_bar.dart
import 'package:flutter/material.dart';
import 'bottom_nav_bar.dart';
class MyPersistentBottomNavBar extends StatelessWidget {
const MyPersistentBottomNavBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Persistent Bottom Nav Bar',
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.deepPurple),
home: const BottomNavBar(),
);
}
}
bottom_nav_bar.dart :
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent-tab-view.dart';
import 'pages/home_page.dart';
import 'pages/explore_page.dart';
import 'pages/add_page.dart';
import 'pages/inbox_page.dart';
import 'pages/shopping_page.dart';
class BottomNavBar extends StatelessWidget {
const BottomNavBar({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
PersistentTabController controller;
controller = PersistentTabController(initialIndex: 0);
List<Widget> _buildScreens() {
return [
const HomePage(),
const ExplorePage(),
const AddPage(),
const InboxPage(),
const ShoppingPage(),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: const Icon(Icons.home),
title: ("Home"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.explore),
title: ("Explore"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.add, color: Colors.white),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.email),
title: ("Inbox"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
PersistentBottomNavBarItem(
icon: const Icon(Icons.shopping_bag),
title: ("Shop"),
activeColorPrimary: Colors.deepPurple,
inactiveColorPrimary: Colors.grey,
),
];
}
return PersistentTabView(
context,
controller: controller,
screens: _buildScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white, // Default is Colors.white.
handleAndroidBackButtonPress: true, // Default is true.
resizeToAvoidBottomInset:
true, // This needs to be true if you want to move up the screen when keyboard appears. Default is true.
stateManagement: true, // Default is true.
hideNavigationBarWhenKeyboardShows:
true, // Recommended to set 'resizeToAvoidBottomInset' as true while using this argument. Default is true.
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
colorBehindNavBar: Colors.white,
),
popAllScreensOnTapOfSelectedTab: true,
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: const ItemAnimationProperties(
// Navigation Bar's items animation properties.
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: const ScreenTransitionAnimation(
// Screen transition animation on change of selected tab.
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle:
NavBarStyle.style15, // Choose the nav bar style with this property.
);
}
}
Please see code for other pages from the GitHub URL below:
https://github.com/md-siam/package_of_the_day/tree/master/lib/51_persistent_bottom_nav_bar/pages
I have tried this code.It runs fine, can you please try?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:minawill/ui/home/home.dart';
class BottomBar extends StatefulWidget {
const BottomBar({Key? key}) : super(key: key);
#override
State<BottomBar> createState() => _BottomBarState();
}
class _BottomBarState extends State<BottomBar> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
HomeScreen(),
const Text("History"),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
//print('Tapped index is: ${_selectedIndex}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions[_selectedIndex],
),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.add),
label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.phone),
label: "History"),
],),],),);}
}
i have added a photo of my output.Please check

Why there is no index in navigation bar item?

This is the code without error messages:
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => BottomNavigation();
}
/// This is the private State class that goes with MyStatefulWidget.
class BottomNavigation extends State<MyStatefulWidget> {
int _selectedIndex = 0;
List<Widget> _widgetOptions= <Widget>[
Text('Home'),
Text('Message')
];
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
void _onItemTapped(int index) {
setState(() {
_selectedIndex=index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image:
AssetImage("assets/OptimizeYourFood/OptimizeYourFood2.png"),
fit: BoxFit.cover,
),
color: Colors.transparent)
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.local_dining),
label: 'Reduce',
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.recycle),
label: 'Reuse and recycle',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
[Nothing comes out of bottom navigation bar items][1]
..................................................................................................................................................................................................This is the end. This is the end. This is the end. This is the end. This is the end.
New Code
New Picture
You are changing the index but not the UI. use _widgetOptions on body. You can directly use body:_widgetOptions[_selectedIndex ] .
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => BottomNavigation();
}
/// This is the private State class that goes with MyStatefulWidget.
class BottomNavigation extends State<MyStatefulWidget> {
int _selectedIndex = 0;
List<Widget> _widgetOptions = <Widget>[Text('Home'), Text('Message')];
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
void _onItemTapped(int index) {
print("tapped $index");
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
),
body: Column(
children: [
_widgetOptions[_selectedIndex]
// Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image:
// AssetImage("assets/OptimizeYourFood/OptimizeYourFood2.png"),
// fit: BoxFit.cover,
// ),
// color: Colors.transparent)),
],
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.local_dining),
label: 'Reduce',
),
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
// Icon(FontAwesomeIcons.recycle),
label: 'Reuse and recycle',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
It will use the items array index.
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem( // <- index 0
icon: Icon(Icons.local_dining),
label: 'Reduce',
),
BottomNavigationBarItem( // <- index 1
icon: Icon(FontAwesomeIcons.recycle),
label: 'Reuse and recycle',
),
...
],

Flutter Menu Not Over Riding Main Menu When Navigate

I am using footer menu to navigate som page aside the main home page which already has AppBar with a title, I want it to be overridden.
I want it, if I navigate from Home page to meditation page, I want the menu to overridden to "MEDITATION".
Here's my footer menu:
class Footer extends StatefulWidget {
// Footer({Key? key}) : super(key: key);
#override
_FooterState createState() => _FooterState();
}
class _FooterState extends State<Footer> {
var _selectedIndex = 0;
final pages = [
Dashboard(),
Health(),
Meditation(),
Sleep(),
Sounds(),
];
#override
void initState() {
super.initState();
_selectedIndex = 0;
}
#override
Widget build(BuildContext context) {
// return GestureDetector(
return Scaffold(
bottomNavigationBar: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: dbShadowColor,
offset: Offset.fromDirection(3, 1),
spreadRadius: 1,
blurRadius: 5)
]),
child: Db5BottomNavigationBar(
items: <Db5BottomNavigationBarItem>[
Db5BottomNavigationBarItem(icon: db5_ic_home),
Db5BottomNavigationBarItem(icon: db5_ic_heart),
Db5BottomNavigationBarItem(icon: db5_ic_meditate),
Db5BottomNavigationBarItem(icon: db5_ic_sleep),
Db5BottomNavigationBarItem(icon: db5_ic_sounds),
],
currentIndex: _selectedIndex,
unselectedIconTheme: IconThemeData(color: db5_icon_color, size: 24),
selectedIconTheme: IconThemeData(color: db5_colorPrimary, size: 24),
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
type: Db5BottomNavigationBarType.fixed,
),
),
body: SafeArea(
child: pages[_selectedIndex],
),
);
// );
}
}
Here's my Meditation Page code:
class Meditation extends StatefulWidget {
Meditation({Key? key}) : super(key: key);
#override
_MeditationState createState() => _MeditationState();
}
class _MeditationState extends State<Meditation> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: appStore.scaffoldBackground,
centerTitle: true,
title: Text(
"Meditate",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20,
),
)),
body: Container(
alignment: Alignment.topLeft,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(),
child: text(
meditation_text_title,
),
)
],
),
),
),
);
}
}
This is how I rendered my footer on the main HOME PAGE:
return Scaffold(
appBar: AppBar(
backgroundColor: db5_white,
iconTheme: IconThemeData(color: sh_textColorPrimary),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
],
title: text(title,
textColor: sh_colorPrimary,
fontFamily: fontBold,
fontSize: textSizeNormal),
),
body: Stack(
children: <Widget>[
Dashboard(),
Footer(),
],
),
);
Am I doing it wrongly?
Here's how you should implement your screens.
// Name the class whatever you like
class ScreensController extends StatefulWidget {
const ScreensController({Key? key}) : super(key: key);
#override
_ScreensControllerState createState() => _ScreensControllerState();
}
class _ScreensControllerState extends State<ScreensController> {
int _selectedIndex = 0;
List<String> mainScreensTitles = [
'Dashboard',
'Health',
'Meditation',
'Sleep',
'Sounds'
];
List<Widget> screens= [
Dashboard(),
Health(),
Meditation(),
Sleep(),
Sounds(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
// Indexed stack is used to prevent page rebuilds when navigating between the
//screens
body: IndexedStack(
index: _selectedIndex,
children: screens,
),
bottomNavigationBar: BottomNavigationBar(
//Toggle these booleans if needed
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: (newScreenIndex) {
setState(() {
_selectedIndex = newScreenIndex;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
label: mainScreensTitles[0],
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite_outline),
label: mainScreensTitles[1],
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: mainScreensTitles[2],
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: mainScreensTitles[3],
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: mainScreensTitles[4],
),
],
currentIndex: _selectedIndex,
),
);
}
}
Implementation of some of your screens:
Dashboard & Meditation:
class Dashboard extends StatelessWidget {
const Dashboard({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
),
body: Center(child: Text('Dashboard coming soon')),
);
}
}
class Meditation extends StatelessWidget {
const Meditation({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Meditation'),
),
body: Center(child: Text('Meditation coming soon')),
);
}
}

Getting rid of divider when using onDismissed

I am semi new to flutter and am having a difficult time with this specific problem. I have listview.seperated widgets I am trying to delete.
return ListView.separated
(
separatorBuilder: (context, index) => Divider(),
padding: const EdgeInsets.all(5.0),
itemCount: siteName.length + 1,
itemBuilder: (context, i) {
if (i != siteName.length) {
return _buildRow(siteName[i], i);
}
else
return _lastRow();
}
so inside of _buildrow I use onDismissed which works however when I dismiss it the operator stays. Any help on exactly how I can get rid of it?
Widget _buildRow(String pair, int num) {
final bool isClicked = (clicked == num);
return Dismissible
(
key: Key(pair),
onDismissed: (direction) {
setState(() {
siteName.removeAt(num);
lines.removeAt(num);
});
},
background: Container
(
padding: EdgeInsets.only(right: 10.0),
alignment: AlignmentDirectional.centerEnd,
color: Colors.red,
child: Icon
(
Icons.delete,
color: Colors.white,
)
),
child: ListTile
(
title: Text
(
pair,
style: _biggerFont,
),
trailing: Icon
(
isClicked ? Icons.check_circle : Icons.check_circle_outline,
color: isClicked ? Colors.green : Colors.black,
),
onTap: () {
setState(() {
if (isClicked) {
clicked = null;
} else {
clicked = num;
}
});
}
)
);
}
You can copy paste run full code below
You can use List<bool> clickedList to control clicked element
code snippet
trailing: Icon(
clickedList[num]
? Icons.check_circle
: Icons.check_circle_outline,
color: clickedList[num] ? Colors.green : Colors.black,
),
onTap: () {
setState(() {
clickedList[num] = !clickedList[num];
});
}));
working demo
full code
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
final siteName = List<String>.generate(20, (i) => "Item ${i + 1}");
List<bool> clickedList = List<bool>.generate(20, (i) => false);
Widget _buildRow(String pair, int num) {
//final bool isClicked = (clicked == num);
return Dismissible(
key: Key(pair),
onDismissed: (direction) {
setState(() {
siteName.removeAt(num);
clickedList.removeAt(num);
//lines.removeAt(num);
});
},
background: Container(
padding: EdgeInsets.only(right: 10.0),
alignment: AlignmentDirectional.centerEnd,
color: Colors.red,
child: Icon(
Icons.delete,
color: Colors.white,
)),
child: ListTile(
title: Text(
pair,
//style: _biggerFont,
),
trailing: Icon(
clickedList[num]
? Icons.check_circle
: Icons.check_circle_outline,
color: clickedList[num] ? Colors.green : Colors.black,
),
onTap: () {
setState(() {
clickedList[num] = !clickedList[num];
});
}));
}
#override
Widget build(BuildContext context) {
final title = 'Dismissing Items';
return MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView.separated(
separatorBuilder: (context, index) => Divider(),
padding: const EdgeInsets.all(5.0),
itemCount: siteName.length,
itemBuilder: (context, i) {
return _buildRow(siteName[i], i);
},
),
),
);
}
}