Optimize proxies expansion panel 2

Fix android scan qrcode error
This commit is contained in:
chen08209
2024-06-27 17:23:59 +08:00
parent 5e3b0e4929
commit 713e83d9d8
7 changed files with 122 additions and 104 deletions

View File

@@ -150,7 +150,6 @@ class ApplicationState extends State<Application> {
builder: (lightDynamic, darkDynamic) { builder: (lightDynamic, darkDynamic) {
_updateSystemColorSchemes(lightDynamic, darkDynamic); _updateSystemColorSchemes(lightDynamic, darkDynamic);
return MaterialApp( return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: globalState.navigatorKey, navigatorKey: globalState.navigatorKey,
localizationsDelegates: const [ localizationsDelegates: const [
AppLocalizations.delegate, AppLocalizations.delegate,

View File

@@ -7,7 +7,6 @@ class Android {
init() async { init() async {
app?.onExit = () { app?.onExit = () {
clashCore.shutdown(); clashCore.shutdown();
print("adsadda==>");
exit(0); exit(0);
}; };
} }

View File

@@ -359,7 +359,9 @@ class AppController {
} }
addProfileFormURL(String url) async { addProfileFormURL(String url) async {
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst); if (globalState.navigatorKey.currentState?.canPop() ?? false) {
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
}
toProfiles(); toProfiles();
final commonScaffoldState = globalState.homeScaffoldKey.currentState; final commonScaffoldState = globalState.homeScaffoldKey.currentState;
if (commonScaffoldState?.mounted != true) return; if (commonScaffoldState?.mounted != true) return;
@@ -421,18 +423,17 @@ class AppController {
}); });
} }
List<Proxy> _sortOfName(List<Proxy> proxies) { List<Proxy> _sortOfName(List<Proxy> proxies) {
return List.of(proxies) return List.of(proxies)
..sort( ..sort(
(a, b) => other.sortByChar(a.name, b.name), (a, b) => other.sortByChar(a.name, b.name),
); );
} }
List<Proxy> _sortOfDelay(List<Proxy> proxies) { List<Proxy> _sortOfDelay(List<Proxy> proxies) {
return proxies = List.of(proxies) return proxies = List.of(proxies)
..sort( ..sort(
(a, b) { (a, b) {
final aDelay = appState.getDelay(a.name); final aDelay = appState.getDelay(a.name);
final bDelay = appState.getDelay(b.name); final bDelay = appState.getDelay(b.name);
if (aDelay == null && bDelay == null) { if (aDelay == null && bDelay == null) {
@@ -449,11 +450,11 @@ class AppController {
); );
} }
List<Proxy> getSortProxies(List<Proxy> proxies){ List<Proxy> getSortProxies(List<Proxy> proxies) {
return switch(config.proxiesSortType){ return switch (config.proxiesSortType) {
ProxiesSortType.none => proxies, ProxiesSortType.none => proxies,
ProxiesSortType.delay => _sortOfDelay(proxies), ProxiesSortType.delay => _sortOfDelay(proxies),
ProxiesSortType.name =>_sortOfName(proxies), ProxiesSortType.name => _sortOfName(proxies),
}; };
} }
} }

View File

@@ -25,7 +25,9 @@ class AddProfile extends StatelessWidget {
final url = await Navigator.of(context) final url = await Navigator.of(context)
.push<String>(MaterialPageRoute(builder: (_) => const ScanPage())); .push<String>(MaterialPageRoute(builder: (_) => const ScanPage()));
if (url != null) { if (url != null) {
_handleAddProfileFormURL(url); WidgetsBinding.instance.addPostFrameCallback((_){
_handleAddProfileFormURL(url);
});
} }
} }

View File

@@ -437,16 +437,16 @@ class _ProfileItemState extends State<ProfileItem> {
label: appLocalizations.update, label: appLocalizations.update,
iconData: Icons.sync, iconData: Icons.sync,
), ),
CommonPopupMenuItem(
action: ProfileActions.delete,
label: appLocalizations.delete,
iconData: Icons.delete,
),
CommonPopupMenuItem( CommonPopupMenuItem(
action: ProfileActions.view, action: ProfileActions.view,
label: appLocalizations.view, label: appLocalizations.view,
iconData: Icons.visibility, iconData: Icons.visibility,
), ),
CommonPopupMenuItem(
action: ProfileActions.delete,
label: appLocalizations.delete,
iconData: Icons.delete,
),
], ],
onSelected: (ProfileActions? action) async { onSelected: (ProfileActions? action) async {
switch (action) { switch (action) {

View File

@@ -230,17 +230,6 @@ class ProxiesExpansionPanelFragment extends StatefulWidget {
class _ProxiesExpansionPanelFragmentState class _ProxiesExpansionPanelFragmentState
extends State<ProxiesExpansionPanelFragment> { extends State<ProxiesExpansionPanelFragment> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Selector2<AppState, Config, ProxiesSelectorState>( return Selector2<AppState, Config, ProxiesSelectorState>(
@@ -259,6 +248,7 @@ class _ProxiesExpansionPanelFragmentState
itemBuilder: (_, index) { itemBuilder: (_, index) {
final groupName = state.groupNames[index]; final groupName = state.groupNames[index];
return ProxyGroupView( return ProxyGroupView(
key: PageStorageKey(groupName),
groupName: groupName, groupName: groupName,
type: ProxiesType.expansion, type: ProxiesType.expansion,
); );
@@ -291,6 +281,7 @@ class ProxyGroupView extends StatefulWidget {
class _ProxyGroupViewState extends State<ProxyGroupView> { class _ProxyGroupViewState extends State<ProxyGroupView> {
var isLock = false; var isLock = false;
final isBoundaryNotifier = ValueNotifier<bool>(false); final isBoundaryNotifier = ValueNotifier<bool>(false);
final scrollController = ScrollController();
var isEnd = false; var isEnd = false;
String get groupName => widget.groupName; String get groupName => widget.groupName;
@@ -384,28 +375,49 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
} }
Widget _androidExpansionHandle(Widget child) { Widget _androidExpansionHandle(Widget child) {
return NotificationListener<ScrollNotification>( // return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) { // onNotification: (ScrollNotification notification) {
if (notification is ScrollEndNotification) { // if (notification is ScrollEndNotification) {
if (notification.metrics.atEdge) { // if (notification.metrics.atEdge) {
isEnd = notification.metrics.pixels == // isEnd = notification.metrics.pixels ==
notification.metrics.maxScrollExtent; // notification.metrics.maxScrollExtent;
isBoundaryNotifier.value = true; // isBoundaryNotifier.value = true;
} // }
// }
// return false;
// },
// child: Listener(
// onPointerMove: (details) {
// double yOffset = details.delta.dy;
// final isEnd = scrollController.position.maxScrollExtent == scrollController.position.pixels;
// final isTop = scrollController.position.minScrollExtent == scrollController.position.pixels;
// if(isEnd || isTop){
// isBoundaryNotifier.value = true;
// } else if (yOffset > 0 && scrollController.position.maxScrollExtent == scrollController.position.pixels) {
// isBoundaryNotifier.value = false;
// } else if (yOffset < 0 && !isEnd) {
// isBoundaryNotifier.value = false;
// }
// },
// child: child,
// ),
// );
return Listener(
onPointerMove: (details) {
double yOffset = details.delta.dy;
final isEnd = scrollController.position.maxScrollExtent ==
scrollController.position.pixels;
final isTop = scrollController.position.minScrollExtent ==
scrollController.position.pixels;
if (isEnd && yOffset < 0) {
isBoundaryNotifier.value = true;
} else if (isTop && yOffset > 0) {
isBoundaryNotifier.value = true;
} else {
isBoundaryNotifier.value = false;
} }
return false;
}, },
child: Listener( child: child,
onPointerMove: (details) {
double yOffset = details.delta.dy;
if (yOffset > 0 && isEnd) {
isBoundaryNotifier.value = false;
} else if (yOffset < 0 && !isEnd) {
isBoundaryNotifier.value = false;
}
},
child: child,
),
); );
} }
@@ -422,7 +434,8 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
final itemHeight = _getItemHeight(proxyCardType); final itemHeight = _getItemHeight(proxyCardType);
final innerHeight = context.appSize.height - 200; final innerHeight = context.appSize.height - 200;
final lines = (sortedProxies.length / columns).ceil(); final lines = (sortedProxies.length / columns).ceil();
final minLines = innerHeight >= 200 ? (innerHeight / itemHeight).floor() : 3; final minLines =
innerHeight >= 200 ? (innerHeight / itemHeight).floor() : 3;
final hasScrollable = lines > minLines; final hasScrollable = lines > minLines;
final height = (itemHeight + 8) * min(lines, minLines) - 8; final height = (itemHeight + 8) * min(lines, minLines) - 8;
return Selector<Config, Set<String>>( return Selector<Config, Set<String>>(
@@ -430,6 +443,7 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
builder: (_, currentUnfoldSet, __) { builder: (_, currentUnfoldSet, __) {
return CommonCard( return CommonCard(
child: ExpansionTile( child: ExpansionTile(
childrenPadding: const EdgeInsets.all(8),
initiallyExpanded: currentUnfoldSet.contains(groupName), initiallyExpanded: currentUnfoldSet.contains(groupName),
iconColor: context.colorScheme.onSurfaceVariant, iconColor: context.colorScheme.onSurfaceVariant,
onExpansionChanged: (value) { onExpansionChanged: (value) {
@@ -527,12 +541,6 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
collapsedShape: const RoundedRectangleBorder( collapsedShape: const RoundedRectangleBorder(
side: BorderSide.none, side: BorderSide.none,
), ),
childrenPadding: const EdgeInsets.only(
top: 8,
bottom: 8,
left: 8,
right: 8,
),
children: [ children: [
SizedBox( SizedBox(
height: height, height: height,
@@ -541,62 +549,70 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: isBoundaryNotifier, valueListenable: isBoundaryNotifier,
builder: (_, isBoundary, child) { builder: (_, isBoundary, child) {
return GridView.builder( return Scrollbar(
physics: isBoundary || !hasScrollable thickness: 6,
? const NeverScrollableScrollPhysics() interactive: true,
: const AlwaysScrollableScrollPhysics(), radius: const Radius.circular(6),
gridDelegate: child: GridView.builder(
SliverGridDelegateWithFixedCrossAxisCount( key: widget.key,
crossAxisCount: columns, controller: scrollController,
mainAxisSpacing: 8, physics: isBoundary || !hasScrollable
crossAxisSpacing: 8, ? const NeverScrollableScrollPhysics()
mainAxisExtent: _getItemHeight(proxyCardType), : const AlwaysScrollableScrollPhysics(),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: columns,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
mainAxisExtent: _getItemHeight(proxyCardType),
),
itemCount: sortedProxies.length,
itemBuilder: (_, index) {
final proxy = sortedProxies[index];
return _currentProxyNameBuilder(
builder: (value) {
return ProxyCard(
style: CommonCardType.filled,
type: proxyCardType,
isSelected: value == proxy.name,
key: ValueKey('$groupName.${proxy.name}'),
proxy: proxy,
groupName: groupName,
);
});
},
), ),
itemCount: sortedProxies.length,
itemBuilder: (_, index) {
final proxy = sortedProxies[index];
return _currentProxyNameBuilder(
builder: (value) {
return ProxyCard(
style: CommonCardType.filled,
type: proxyCardType,
isSelected: value == proxy.name,
key: ValueKey('$groupName.${proxy.name}'),
proxy: proxy,
groupName: groupName,
);
});
},
); );
}, },
), ),
) )
: GridView.builder( : GridView.builder(
physics: !hasScrollable key: widget.key,
? const NeverScrollableScrollPhysics() controller: scrollController,
: const AlwaysScrollableScrollPhysics(), physics: !hasScrollable
gridDelegate: ? const NeverScrollableScrollPhysics()
SliverGridDelegateWithFixedCrossAxisCount( : const AlwaysScrollableScrollPhysics(),
crossAxisCount: columns, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 8, crossAxisCount: columns,
crossAxisSpacing: 8, mainAxisSpacing: 8,
mainAxisExtent: _getItemHeight(proxyCardType), crossAxisSpacing: 8,
), mainAxisExtent: _getItemHeight(proxyCardType),
itemCount: sortedProxies.length, ),
itemBuilder: (_, index) { itemCount: sortedProxies.length,
final proxy = sortedProxies[index]; itemBuilder: (_, index) {
return _currentProxyNameBuilder(builder: (value) { final proxy = sortedProxies[index];
return ProxyCard( return _currentProxyNameBuilder(builder: (value) {
style: CommonCardType.filled, return ProxyCard(
type: proxyCardType, style: CommonCardType.filled,
isSelected: value == proxy.name, type: proxyCardType,
key: ValueKey('$groupName.${proxy.name}'), isSelected: value == proxy.name,
proxy: proxy, key: ValueKey('$groupName.${proxy.name}'),
groupName: groupName, proxy: proxy,
); groupName: groupName,
}); );
}, });
), },
),
), ),
], ],
), ),
@@ -609,6 +625,7 @@ class _ProxyGroupViewState extends State<ProxyGroupView> {
void dispose() { void dispose() {
super.dispose(); super.dispose();
isBoundaryNotifier.dispose(); isBoundaryNotifier.dispose();
scrollController.dispose();
} }
@override @override

View File

@@ -1,7 +1,7 @@
name: fl_clash name: fl_clash
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free. description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
publish_to: 'none' publish_to: 'none'
version: 0.8.29 version: 0.8.30
environment: environment:
sdk: '>=3.1.0 <4.0.0' sdk: '>=3.1.0 <4.0.0'