Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for drag interactions on the alphabet list widget #2

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/src/sectionView.dart
Expand Up @@ -194,7 +194,7 @@ class _SectionViewState<T, N> extends State<SectionView> {
alphabetAlign: ownWidget.alphabetAlign,
alphabetInset: ownWidget.alphabetInset,
key: sectionViewAlphabetListKey,
onTap: <T>(item) {
onSelect: <T>(item) {
if (alphabetTipKey.currentState != null) {
alphabetTipKey.currentState!.tipData = item.headerData;
}
Expand Down
46 changes: 39 additions & 7 deletions lib/src/sectionViewAlphabetList.dart
@@ -1,18 +1,19 @@
import 'dart:math';
import 'sectionViewModel.dart';
import 'package:flutter/material.dart';

class SectionViewAlphabetList<T> extends StatefulWidget {
const SectionViewAlphabetList(
{required this.headerToIndexMap,
required this.onTap,
required this.onSelect,
required this.alphabetAlign,
required this.alphabetInset,
this.alphabetBuilder,
Key? key})
: super(key: key);
final SectionViewAlphabetBuilder<T>? alphabetBuilder;
final List<AlphabetModel<T>> headerToIndexMap;
final AlphabetItemOnTap<AlphabetModel<T>> onTap;
final AlphabetItemOnTap<AlphabetModel<T>> onSelect;
final Alignment alphabetAlign;
final EdgeInsets alphabetInset;

Expand All @@ -22,6 +23,8 @@ class SectionViewAlphabetList<T> extends StatefulWidget {
}

class SectionViewAlphabetListState<T> extends State<SectionViewAlphabetList> {
final List<GlobalKey> itemKeys = [];

/// It is top item on viewport, the headerData can be used to tracking
/// current alphabet
SectionViewData? _topItem;
Expand All @@ -46,8 +49,30 @@ class SectionViewAlphabetListState<T> extends State<SectionViewAlphabetList> {
}
}

void onDrag(double yPosition) {
double checkedHeight = 0;
int? index;

// To determine which widget is selected add the height of every alphabet item one by one
// Until the height is in range of the drag position
// At that point we have determined the index of the header item and trigger the callback with that item
for (var i = 0; i < ownWidget.headerToIndexMap.length; i++) {
double itemHeight = itemKeys[i].currentContext?.size?.height ?? 0;
checkedHeight += itemHeight;
if (checkedHeight >= yPosition) {
index = i;
break;
}
}

if (index != null) {
ownWidget.onSelect(ownWidget.headerToIndexMap[index]);
}
}

@override
Widget build(BuildContext context) {
itemKeys.clear();
if (ownWidget.alphabetBuilder == null) {
return const SizedBox(
width: 0,
Expand All @@ -56,17 +81,20 @@ class SectionViewAlphabetListState<T> extends State<SectionViewAlphabetList> {
} else {
List<Widget> alphabetWidgets = [];
for (var header in ownWidget.headerToIndexMap) {
final globalKey = GlobalKey();
var _alphabetWidget = ownWidget.alphabetBuilder!(
context,
header.headerData,
header.headerIndex == _topItem?.headerIndex,
header.headerIndex);
alphabetWidgets.add(GestureDetector(
key: globalKey,
onTap: () {
ownWidget.onTap(header);
ownWidget.onSelect(header);
},
behavior: HitTestBehavior.opaque,
child: _alphabetWidget));
itemKeys.add(globalKey);
}
return Positioned(
top: 0,
Expand All @@ -76,10 +104,14 @@ class SectionViewAlphabetListState<T> extends State<SectionViewAlphabetList> {
alignment: ownWidget.alphabetAlign,
child: Padding(
padding: ownWidget.alphabetInset,
child: (Column(
mainAxisSize: MainAxisSize.min,
children: alphabetWidgets,
)),
child: GestureDetector(
onVerticalDragDown: (details) => onDrag(details.localPosition.dy),
onVerticalDragUpdate: (details) => onDrag(details.localPosition.dy),
child: (Column(
mainAxisSize: MainAxisSize.min,
children: alphabetWidgets,
)),
),
),
));
}
Expand Down