mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 08:46:18 +01:00
Add fade out effect also to nav bar settings page
This commit is contained in:
parent
78c02fd280
commit
058a8d38af
5 changed files with 171 additions and 116 deletions
118
app/lib/widget/fade_out_list.dart
Normal file
118
app/lib/widget/fade_out_list.dart
Normal file
|
@ -0,0 +1,118 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FadeOutListContainer extends StatefulWidget {
|
||||
const FadeOutListContainer({
|
||||
super.key,
|
||||
required this.scrollController,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _FadeOutListContainerState();
|
||||
|
||||
final ScrollController scrollController;
|
||||
final Widget child;
|
||||
}
|
||||
|
||||
class _FadeOutListContainerState extends State<FadeOutListContainer> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
widget.scrollController.addListener(_onScrollEvent);
|
||||
_ensureUpdateButtonScroll();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.scrollController.removeListener(_onScrollEvent);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ShaderMask(
|
||||
shaderCallback: (rect) {
|
||||
final colors = <Color>[];
|
||||
final stops = <double>[];
|
||||
if (_hasLeftContent) {
|
||||
colors.addAll([Colors.white, Colors.transparent]);
|
||||
stops.addAll([0, .1]);
|
||||
} else {
|
||||
colors.add(Colors.transparent);
|
||||
stops.add(0);
|
||||
}
|
||||
if (_hasRightContent) {
|
||||
colors.addAll([Colors.transparent, Colors.white]);
|
||||
stops.addAll([.9, 1]);
|
||||
} else {
|
||||
colors.add(Colors.transparent);
|
||||
stops.add(1);
|
||||
}
|
||||
return LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: colors,
|
||||
stops: stops,
|
||||
).createShader(rect);
|
||||
},
|
||||
blendMode: BlendMode.dstOut,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
|
||||
void _onScrollEvent() {
|
||||
_updateButtonScroll(widget.scrollController.position);
|
||||
}
|
||||
|
||||
bool _updateButtonScroll(ScrollPosition pos) {
|
||||
if (!pos.hasContentDimensions || !pos.hasPixels) {
|
||||
return false;
|
||||
}
|
||||
if (pos.pixels <= pos.minScrollExtent) {
|
||||
if (_hasLeftContent) {
|
||||
setState(() {
|
||||
_hasLeftContent = false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!_hasLeftContent) {
|
||||
setState(() {
|
||||
_hasLeftContent = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (pos.pixels >= pos.maxScrollExtent) {
|
||||
if (_hasRightContent) {
|
||||
setState(() {
|
||||
_hasRightContent = false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!_hasRightContent) {
|
||||
setState(() {
|
||||
_hasRightContent = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
_hasFirstScrollUpdate = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _ensureUpdateButtonScroll() {
|
||||
if (_hasFirstScrollUpdate || !mounted) {
|
||||
return;
|
||||
}
|
||||
if (widget.scrollController.hasClients) {
|
||||
if (_updateButtonScroll(widget.scrollController.position)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Timer(const Duration(milliseconds: 100), _ensureUpdateButtonScroll);
|
||||
}
|
||||
|
||||
var _hasFirstScrollUpdate = false;
|
||||
var _hasLeftContent = false;
|
||||
var _hasRightContent = false;
|
||||
}
|
|
@ -34,6 +34,7 @@ import 'package:nc_photos/widget/archive_browser.dart';
|
|||
import 'package:nc_photos/widget/collection_browser.dart';
|
||||
import 'package:nc_photos/widget/collection_grid_item.dart';
|
||||
import 'package:nc_photos/widget/enhanced_photo_browser.dart';
|
||||
import 'package:nc_photos/widget/fade_out_list.dart';
|
||||
import 'package:nc_photos/widget/handler/double_tap_exit_handler.dart';
|
||||
import 'package:nc_photos/widget/home_app_bar.dart';
|
||||
import 'package:nc_photos/widget/navigation_bar_blur_filter.dart';
|
||||
|
|
|
@ -20,15 +20,6 @@ class _NavigationBar extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _NavigationBarState extends State<_NavigationBar> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scrollController = ScrollController();
|
||||
_scrollController
|
||||
.addListener(() => _updateButtonScroll(_scrollController.position));
|
||||
_ensureUpdateButtonScroll();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
|
@ -42,32 +33,8 @@ class _NavigationBarState extends State<_NavigationBar> {
|
|||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ShaderMask(
|
||||
shaderCallback: (rect) {
|
||||
final colors = <Color>[];
|
||||
final stops = <double>[];
|
||||
if (_hasLeftContent) {
|
||||
colors.addAll([Colors.white, Colors.transparent]);
|
||||
stops.addAll([0, .1]);
|
||||
} else {
|
||||
colors.add(Colors.transparent);
|
||||
stops.add(0);
|
||||
}
|
||||
if (_hasRightContent) {
|
||||
colors.addAll([Colors.transparent, Colors.white]);
|
||||
stops.addAll([.9, 1]);
|
||||
} else {
|
||||
colors.add(Colors.transparent);
|
||||
stops.add(1);
|
||||
}
|
||||
return LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: colors,
|
||||
stops: stops,
|
||||
).createShader(rect);
|
||||
},
|
||||
blendMode: BlendMode.dstOut,
|
||||
child: FadeOutListContainer(
|
||||
scrollController: _scrollController,
|
||||
child: _BlocSelector(
|
||||
selector: (state) => state.navBarButtons,
|
||||
builder: (context, navBarButtons) {
|
||||
|
@ -112,56 +79,7 @@ class _NavigationBarState extends State<_NavigationBar> {
|
|||
}
|
||||
}
|
||||
|
||||
bool _updateButtonScroll(ScrollPosition pos) {
|
||||
if (!pos.hasContentDimensions || !pos.hasPixels) {
|
||||
return false;
|
||||
}
|
||||
if (pos.pixels <= pos.minScrollExtent) {
|
||||
if (_hasLeftContent) {
|
||||
setState(() {
|
||||
_hasLeftContent = false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!_hasLeftContent) {
|
||||
setState(() {
|
||||
_hasLeftContent = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (pos.pixels >= pos.maxScrollExtent) {
|
||||
if (_hasRightContent) {
|
||||
setState(() {
|
||||
_hasRightContent = false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!_hasRightContent) {
|
||||
setState(() {
|
||||
_hasRightContent = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
_hasFirstScrollUpdate = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _ensureUpdateButtonScroll() {
|
||||
if (_hasFirstScrollUpdate || !mounted) {
|
||||
return;
|
||||
}
|
||||
if (_scrollController.hasClients) {
|
||||
if (_updateButtonScroll(_scrollController.position)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Timer(const Duration(milliseconds: 100), _ensureUpdateButtonScroll);
|
||||
}
|
||||
|
||||
late final ScrollController _scrollController;
|
||||
var _hasFirstScrollUpdate = false;
|
||||
var _hasLeftContent = false;
|
||||
var _hasRightContent = false;
|
||||
final _scrollController = ScrollController();
|
||||
}
|
||||
|
||||
class _NavBarButtonIndicator extends StatelessWidget {
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
part of '../collections_nav_bar_settings.dart';
|
||||
|
||||
class _DemoView extends StatelessWidget {
|
||||
class _DemoView extends StatefulWidget {
|
||||
const _DemoView();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _DemoViewState();
|
||||
}
|
||||
|
||||
class _DemoViewState extends State<_DemoView> {
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _BlocSelector(
|
||||
|
@ -13,38 +24,42 @@ class _DemoView extends StatelessWidget {
|
|||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.only(left: 16 - 6),
|
||||
itemCount: buttons.length,
|
||||
itemBuilder: (context, i) {
|
||||
final btn = buttons[i];
|
||||
return my.Draggable<HomeCollectionsNavBarButtonType>(
|
||||
data: btn.type,
|
||||
feedback: _CandidateButtonDelegate(btn.type),
|
||||
onDropBefore: (data) {
|
||||
context.addEvent(_MoveButton.before(
|
||||
which: data,
|
||||
target: btn.type,
|
||||
));
|
||||
},
|
||||
onDropAfter: (data) {
|
||||
context.addEvent(_MoveButton.after(
|
||||
which: data,
|
||||
target: btn.type,
|
||||
));
|
||||
},
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
child: _DemoButtonDelegate(
|
||||
btn.type,
|
||||
isMinimized: btn.isMinimized,
|
||||
child: FadeOutListContainer(
|
||||
scrollController: _scrollController,
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.only(left: 16 - 6),
|
||||
itemCount: buttons.length,
|
||||
itemBuilder: (context, i) {
|
||||
final btn = buttons[i];
|
||||
return my.Draggable<HomeCollectionsNavBarButtonType>(
|
||||
data: btn.type,
|
||||
feedback: _CandidateButtonDelegate(btn.type),
|
||||
onDropBefore: (data) {
|
||||
context.addEvent(_MoveButton.before(
|
||||
which: data,
|
||||
target: btn.type,
|
||||
));
|
||||
},
|
||||
onDropAfter: (data) {
|
||||
context.addEvent(_MoveButton.after(
|
||||
which: data,
|
||||
target: btn.type,
|
||||
));
|
||||
},
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
child: _DemoButtonDelegate(
|
||||
btn.type,
|
||||
isMinimized: btn.isMinimized,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
@ -81,6 +96,8 @@ class _DemoView extends StatelessWidget {
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
final _scrollController = ScrollController();
|
||||
}
|
||||
|
||||
class _DemoButtonDelegate extends StatelessWidget {
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:nc_photos/exception_event.dart';
|
|||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/widget/draggable.dart' as my;
|
||||
import 'package:nc_photos/widget/fade_out_list.dart';
|
||||
import 'package:nc_photos/widget/home_collections.dart';
|
||||
import 'package:nc_photos/widget/page_visibility_mixin.dart';
|
||||
import 'package:np_codegen/np_codegen.dart';
|
||||
|
|
Loading…
Reference in a new issue