我试图在使用bloc
滚动时隐藏Floating Action button
,但不起作用。
这是下面的bloc
类:
class AppCubit extends Cubit<AppStates> {
AppCubit() : super(AppInitialState());
static AppCubit get(context) => BlocProvider.of(context);
int currentIndex = 0;
List<Widget> screens = [
FeedsScreen(),
ChatsScreen(),
UsersScreen(),
SettingsScreen(),
];
List<String> titles = [
'Home',
'Chats',
'Users',
'Settings',
];
ScrollController scrollController =
ScrollController(); // set controller on scrolling
bool show = true;
void hideBottomWidget() {
show = false;
}
void showBottomWidget() {
show = true;
}
void handleScroll() async {
scrollController.addListener(() {
if (scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
hideBottomWidget();
}
if (scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
showBottomWidget();
}
});
}
}
这是我的以下布局屏幕:
class SocialLayout extends StatelessWidget {
const SocialLayout({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocConsumer<AppCubit, AppStates>(
listener: (context, state) {},
builder: (context, state) {
var cubit = AppCubit.get(context);
return Scaffold(
appBar: AppBar(
title: Text(
cubit.titles[cubit.currentIndex],
),
actions: [
IconButton(
onPressed: () {},
icon: Icon(IconBroken.Notification),
),
IconButton(
onPressed: () {},
icon: Icon(IconBroken.Search),
),
],
),
body: cubit.screens[cubit.currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: cubit.currentIndex,
onTap: (index) {
cubit.changeBottomNavIndex(index);
},
items: [
BottomNavigationBarItem(
icon: Icon(IconBroken.Home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(IconBroken.Chat), label: 'Chat'),
BottomNavigationBarItem(
icon: Icon(IconBroken.Location), label: 'Location'),
BottomNavigationBarItem(
icon: Icon(IconBroken.Setting), label: 'Settings'),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Visibility(
visible: cubit.show,
child: FloatingActionButton(
onPressed: () { },
tooltip: 'Post',
child: Icon(IconBroken.Paper_Upload, color: Colors.white,),
elevation: 2.0,
),
),
);
},
);
}
}
在这里,我包装了visibility
小部件并添加了visible
状态。
下面对包含ListView.separated()
的屏幕进行编码
class FeedsScreen extends StatelessWidget {
const FeedsScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var responsive = MediaQuery.of(context).size;
return BlocConsumer<AppCubit, AppStates>(
listener: (context, state) {},
builder: (context, state) {
var cubit = AppCubit.get(context);
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
children: [
Card(...),
],
),
),
ListView.separated(
controller: cubit.scrollController,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => buildPostItem(context),
separatorBuilder: (context, index) => SizedBox(height: 10,),
itemCount: 10,
),
SizedBox(
height: 8.0,
),
],
),
);
},
);
}
Widget buildPostItem(context) => Card(....);,
);
}
如您所见,我在ListView
中调用了controller: cubit.scrollController,
这是我在BlocProvider()
中调用handleScroll
方法的main下面的代码:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
Bloc.observer = MyBlocObserver();
DioHelper.init();
await CacheHelper.init();
Widget widget;
uId = CacheHelper.getData(key: 'uId');
if (uId != null) {
widget = SocialLayout();
} else {
widget = LoginScreen();
}
runApp(MyApp(
startWidget: widget,
));
}
class MyApp extends StatelessWidget {
final Widget startWidget;
MyApp({
this.startWidget,
});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) => AppCubit()..getUserData()..handleScroll(),
child: BlocConsumer<AppCubit, AppStates>(
listener: (context, state) {},
builder: (context, state) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: lightTheme,
themeMode: ThemeMode.light,
home: startWidget,
);
},
),
);
}
}
发布于 2021-05-13 22:22:31
这就是解决方案,我要在下面的方法中添加emit,然后将emit添加到那里,就像下面的代码一样:
void hideBottomWidget() {
show = false;
emit(AppHideBottomWidgetState());
}
void showBottomWidget() {
show = true;
emit(AppShowBottomWidgetState());
}
void handleScroll() async {
scrollController.addListener(() {
if (scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
hideBottomWidget();
emit(AppHandleReverseHideBottomWidgetState());
}
if (scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
showBottomWidget();
emit(AppHandleForwardHideBottomWidgetState());
}
});
}
https://stackoverflow.com/questions/67526406
复制相似问题