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) {
_updateSystemColorSchemes(lightDynamic, darkDynamic);
return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: globalState.navigatorKey,
localizationsDelegates: const [
AppLocalizations.delegate,

View File

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

View File

@@ -359,7 +359,9 @@ class AppController {
}
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();
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
if (commonScaffoldState?.mounted != true) return;
@@ -421,18 +423,17 @@ class AppController {
});
}
List<Proxy> _sortOfName(List<Proxy> proxies) {
return List.of(proxies)
..sort(
(a, b) => other.sortByChar(a.name, b.name),
(a, b) => other.sortByChar(a.name, b.name),
);
}
List<Proxy> _sortOfDelay(List<Proxy> proxies) {
return proxies = List.of(proxies)
..sort(
(a, b) {
(a, b) {
final aDelay = appState.getDelay(a.name);
final bDelay = appState.getDelay(b.name);
if (aDelay == null && bDelay == null) {
@@ -449,11 +450,11 @@ class AppController {
);
}
List<Proxy> getSortProxies(List<Proxy> proxies){
return switch(config.proxiesSortType){
List<Proxy> getSortProxies(List<Proxy> proxies) {
return switch (config.proxiesSortType) {
ProxiesSortType.none => 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)
.push<String>(MaterialPageRoute(builder: (_) => const ScanPage()));
if (url != null) {
_handleAddProfileFormURL(url);
WidgetsBinding.instance.addPostFrameCallback((_){
_handleAddProfileFormURL(url);
});
}
}

View File

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

View File

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

View File

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