Skip to content

Commit

Permalink
Replace expandable dependency with custom implementation to avoid dup…
Browse files Browse the repository at this point in the history
…lication when copying
  • Loading branch information
AlienKevin committed Jan 31, 2024
1 parent ec4d094 commit d64222f
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 297 deletions.
306 changes: 157 additions & 149 deletions lib/widgets/entry/entry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,172 +128,180 @@ class _EntryWidgetState extends State<EntryWidget>
.expand((x) => x)
.toList();

return Column(children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: ListViewObserver(
controller: _observerController,
autoTriggerObserveTypes: const [
ObserverAutoTriggerObserveType.scrollUpdate,
],
triggerOnObserveType: ObserverTriggerOnObserveType.directly,
onObserve: (resultModel) {
// debugPrint('visible -- ${resultModel.visible}');
// debugPrint('firstChild.index -- ${resultModel.firstChild?.index}');
// debugPrint('displaying -- ${resultModel.displayingChildIndexList}');
return Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: ListViewObserver(
controller: _observerController,
autoTriggerObserveTypes: const [
ObserverAutoTriggerObserveType.scrollUpdate,
],
triggerOnObserveType: ObserverTriggerOnObserveType.directly,
onObserve: (resultModel) {
// debugPrint('visible -- ${resultModel.visible}');
// debugPrint('firstChild.index -- ${resultModel.firstChild?.index}');
// debugPrint('displaying -- ${resultModel.displayingChildIndexList}');

// for (var item in resultModel.displayingChildModelList) {
// debugPrint(
// 'item - ${item.index} ${item.leadingMarginToViewport} ${item.trailingMarginToViewport} ${item.displayPercentage}');
// }
// for (var item in resultModel.displayingChildModelList) {
// debugPrint(
// 'item - ${item.index} ${item.leadingMarginToViewport} ${item.trailingMarginToViewport} ${item.displayPercentage}');
// }

if (!isScrollingToTarget &&
resultModel.displayingChildModelList.isNotEmpty) {
final RenderSliverMultiBoxAdaptor list =
resultModel.sliverList;
List<
({
RenderIndexedSemantics child,
ListViewObserveDisplayingChildModel? displayingChild
})> items = [];
list.visitChildren((child) {
if (child is! RenderIndexedSemantics) {
return;
}
final displayingChild = resultModel
.displayingChildModelList
.firstWhereOrNull((displayingChild) =>
displayingChild.renderObject == child);
items.add(
(child: child, displayingChild: displayingChild));
});
if (!isScrollingToTarget &&
resultModel.displayingChildModelList.isNotEmpty) {
final RenderSliverMultiBoxAdaptor list =
resultModel.sliverList;
List<
({
RenderIndexedSemantics child,
ListViewObserveDisplayingChildModel? displayingChild
})> items = [];
list.visitChildren((child) {
if (child is! RenderIndexedSemantics) {
return;
}
final displayingChild = resultModel
.displayingChildModelList
.firstWhereOrNull((displayingChild) =>
displayingChild.renderObject == child);
items.add(
(child: child, displayingChild: displayingChild));
});

final targetEntryIndex = groupBy(
items,
(item) => defIndexRanges.indexWhere((entryRange) =>
item.child.index >= entryRange.$1 &&
item.child.index < entryRange.$2))
.map((defIndex, items) {
final entryDisplayingHeight = items
.map((item) => (item.displayingChild == null)
? 0
: item.displayingChild!.displayPercentage *
item.displayingChild!.mainAxisSize)
.reduce((entryHeight, defHeight) =>
entryHeight + defHeight);
final entryTotalHeight = items
.map((item) => item.child.size.height)
.reduce((entryHeight, defHeight) =>
entryHeight + defHeight);
return MapEntry(defIndex,
entryDisplayingHeight / entryTotalHeight);
})
.entries
.fold(
(tallestEntryIndex: -1, tallestEntryHeight: -1.0),
(tallestEntry, entryHeight) =>
tallestEntry.tallestEntryHeight >=
final targetEntryIndex = groupBy(
items,
(item) => defIndexRanges.indexWhere(
(entryRange) =>
item.child.index >= entryRange.$1 &&
item.child.index < entryRange.$2))
.map((defIndex, items) {
final entryDisplayingHeight = items
.map((item) => (item.displayingChild == null)
? 0
: item.displayingChild!
.displayPercentage *
item.displayingChild!.mainAxisSize)
.reduce((entryHeight, defHeight) =>
entryHeight + defHeight);
final entryTotalHeight = items
.map((item) => item.child.size.height)
.reduce((entryHeight, defHeight) =>
entryHeight + defHeight);
return MapEntry(defIndex,
entryDisplayingHeight / entryTotalHeight);
})
.entries
.fold(
(
tallestEntryIndex: -1,
tallestEntryHeight: -1.0
),
(tallestEntry, entryHeight) => tallestEntry
.tallestEntryHeight >=
entryHeight.value
? tallestEntry
: (
tallestEntryIndex: entryHeight.key,
tallestEntryHeight: entryHeight.value
))
.tallestEntryIndex;
.tallestEntryIndex;

debugPrint("targetEntryIndex: $targetEntryIndex");
debugPrint("targetEntryIndex: $targetEntryIndex");
setState(() {
_tabController.animateTo(targetEntryIndex);
});
}
},
child: SelectionArea(
child: ListView.separated(
controller: _scrollController,
padding: const EdgeInsets.all(10),
itemCount: items.length,
cacheExtent: double.maxFinite,
separatorBuilder: (context, index) => SizedBox(
height: defIndexRanges.firstWhereOrNull(
(range) => range.$2 - 1 == index) !=
null
? (MediaQuery.of(context).size.width >
wideScreenThreshold
? 40
: 20)
: 10,
),
itemBuilder: (context, index) => items[index],
),
)))),
Row(children: [
Visibility(
visible: Navigator.of(context).canPop(),
child: IconButton(
icon: Icon(
isMaterial(context)
? Icons.arrow_back
: CupertinoIcons.chevron_left,
color: Theme.of(context).textTheme.bodyMedium!.color!),
onPressed: () {
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
},
),
),
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: Material(
elevation: 2,
child: TabBar(
controller: _tabController,
onTap: (newIndex) async {
if (newIndex != entryIndex) {
// context.read<PlayerState>().stop();
setState(() {
entryIndex = newIndex;
isScrollingToTarget = true;
});
final targetDefIndex = getStartDefIndex(newIndex);
await _observerController.animateTo(
index: targetDefIndex,
duration: const Duration(milliseconds: 500),
curve: Curves.easeIn,
);
setState(() {
_tabController.animateTo(targetEntryIndex);
isScrollingToTarget = false;
});
}
},
child: ListView.separated(
controller: _scrollController,
padding: const EdgeInsets.all(10),
itemCount: items.length,
cacheExtent: double.maxFinite,
separatorBuilder: (context, index) => SizedBox(
height: defIndexRanges.firstWhereOrNull(
(range) => range.$2 - 1 == index) !=
null
? (MediaQuery.of(context).size.width >
wideScreenThreshold
? 40
: 20)
: 10,
),
itemBuilder: (context, index) => items[index],
isScrollable: true,
// Required
labelColor: lineTextStyle.color,
unselectedLabelColor: lineTextStyle.color,
// Other tabs color
labelPadding: const EdgeInsets.symmetric(horizontal: 30),
// Space between tabs
indicator: BubbleTabIndicator(
indicatorHeight:
Theme.of(context).textTheme.bodyMedium!.fontSize! * 1.5,
indicatorColor: Theme.of(context).splashColor,
tabBarIndicatorSize: TabBarIndicatorSize.label,
),
))),
Row(children: [
Visibility(
visible: Navigator.of(context).canPop(),
child: IconButton(
icon: Icon(
isMaterial(context)
? Icons.arrow_back
: CupertinoIcons.chevron_left,
color: Theme.of(context).textTheme.bodyMedium!.color!),
onPressed: () {
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
},
),
),
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: Material(
elevation: 2,
child: TabBar(
controller: _tabController,
onTap: (newIndex) async {
if (newIndex != entryIndex) {
// context.read<PlayerState>().stop();
setState(() {
entryIndex = newIndex;
isScrollingToTarget = true;
});
final targetDefIndex = getStartDefIndex(newIndex);
await _observerController.animateTo(
index: targetDefIndex,
duration: const Duration(milliseconds: 500),
curve: Curves.easeIn,
);
setState(() {
isScrollingToTarget = false;
});
}
},
isScrollable: true,
// Required
labelColor: lineTextStyle.color,
unselectedLabelColor: lineTextStyle.color,
// Other tabs color
labelPadding: const EdgeInsets.symmetric(horizontal: 30),
// Space between tabs
indicator: BubbleTabIndicator(
indicatorHeight:
Theme.of(context).textTheme.bodyMedium!.fontSize! * 1.5,
indicatorColor: Theme.of(context).splashColor,
tabBarIndicatorSize: TabBarIndicatorSize.label,
tabAlignment: TabAlignment.start,
padding: const EdgeInsets.symmetric(vertical: 6),
tabs: widget.entryGroup
.asMap()
.entries
.map((entry) => Tab(
text:
"${entry.key + 1} ${entry.value.poses.map((pos) => translatePos(pos, localizationContext)).join("/")}"))
.toList(),
),
tabAlignment: TabAlignment.start,
padding: const EdgeInsets.symmetric(vertical: 6),
tabs: widget.entryGroup
.asMap()
.entries
.map((entry) => Tab(
text:
"${entry.key + 1} ${entry.value.poses.map((pos) => translatePos(pos, localizationContext)).join("/")}"))
.toList(),
),
),
)),
]),
]);
)),
]),
],
);
}

showDef(int entryIndex, int index, lineTextStyle, linkColor, rubyFontSize) {
Expand Down
Loading

0 comments on commit d64222f

Please sign in to comment.