-
Notifications
You must be signed in to change notification settings - Fork 148
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
Pressing an Individual Node #57
Comments
I was able to add In order to add the This is a brute force method but it may be helpful in a hack-y way: import 'package:flutter/material.dart';
import 'package:timelines/timelines.dart';
/// Custom TimelineTileBuilder created to add GestureDetector to the original TimelineTileBuilder
/// Reuses code from the original with parameters based on TimelineTileBuilder.connected() factory
class CustomTimelineTileBuilder implements TimelineTileBuilder {
CustomTimelineTileBuilder(
{required this.itemCount,
ContentsAlign contentsAlign = ContentsAlign.basic,
ConnectionDirection connectionDirection = ConnectionDirection.after,
NullableIndexedWidgetBuilder? contentsBuilder,
NullableIndexedWidgetBuilder? oppositeContentsBuilder,
NullableIndexedWidgetBuilder? indicatorBuilder,
ConnectedConnectorBuilder? connectorBuilder,
WidgetBuilder? firstConnectorBuilder,
WidgetBuilder? lastConnectorBuilder,
double? itemExtent,
IndexedValueBuilder<double>? itemExtentBuilder,
IndexedValueBuilder<double>? nodePositionBuilder,
IndexedValueBuilder<double>? indicatorPositionBuilder,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
Function? onTap,
Function? onLongPress}) {
assert(
itemExtent == null || itemExtentBuilder == null,
'Cannot provide both a itemExtent and a itemExtentBuilder.',
);
final startConnectorBuilder = _createConnectedStartConnectorBuilder(
connectionDirection: connectionDirection,
firstConnectorBuilder: firstConnectorBuilder,
connectorBuilder: connectorBuilder,
);
final endConnectorBuilder = _createConnectedEndConnectorBuilder(
connectionDirection: connectionDirection,
lastConnectorBuilder: lastConnectorBuilder,
connectorBuilder: connectorBuilder,
itemCount: itemCount,
);
final effectiveContentsBuilder = _createAlignedContentsBuilder(
align: contentsAlign,
contentsBuilder: contentsBuilder,
oppositeContentsBuilder: oppositeContentsBuilder,
);
final effectiveOppositeContentsBuilder = _createAlignedContentsBuilder(
align: contentsAlign,
contentsBuilder: oppositeContentsBuilder,
oppositeContentsBuilder: contentsBuilder,
);
_builder = (context, index) {
final tile = GestureDetector(
onTap: () => onTap?.call(index),
onLongPress: () => onLongPress?.call(index),
child: TimelineTile(
mainAxisExtent: itemExtent ?? itemExtentBuilder?.call(context, index),
node: TimelineNode(
indicator: indicatorBuilder?.call(context, index) ?? Indicator.transparent(),
startConnector: startConnectorBuilder?.call(context, index),
endConnector: endConnectorBuilder?.call(context, index),
position: nodePositionBuilder?.call(context, index),
indicatorPosition: indicatorPositionBuilder?.call(context, index),
),
contents: effectiveContentsBuilder(context, index),
oppositeContents: effectiveOppositeContentsBuilder(context, index),
),
);
return tile;
};
}
late IndexedWidgetBuilder _builder;
@override
int itemCount;
@override
Widget build(BuildContext context, int index) {
return _builder(context, index);
}
static NullableIndexedWidgetBuilder _createConnectedStartConnectorBuilder({
ConnectionDirection? connectionDirection,
WidgetBuilder? firstConnectorBuilder,
ConnectedConnectorBuilder? connectorBuilder,
}) =>
(context, index) {
if (index == 0) {
if (firstConnectorBuilder != null) {
return firstConnectorBuilder.call(context);
} else {
return null;
}
}
if (connectionDirection == ConnectionDirection.before) {
return connectorBuilder?.call(context, index, ConnectorType.start);
} else {
return connectorBuilder?.call(context, index - 1, ConnectorType.start);
}
};
static NullableIndexedWidgetBuilder _createConnectedEndConnectorBuilder({
ConnectionDirection? connectionDirection,
WidgetBuilder? lastConnectorBuilder,
ConnectedConnectorBuilder? connectorBuilder,
required int itemCount,
}) =>
(context, index) {
if (index == itemCount - 1) {
if (lastConnectorBuilder != null) {
return lastConnectorBuilder.call(context);
} else {
return null;
}
}
if (connectionDirection == ConnectionDirection.before) {
return connectorBuilder?.call(context, index + 1, ConnectorType.end);
} else {
return connectorBuilder?.call(context, index, ConnectorType.end);
}
};
static NullableIndexedWidgetBuilder _createAlignedContentsBuilder({
required ContentsAlign align,
NullableIndexedWidgetBuilder? contentsBuilder,
NullableIndexedWidgetBuilder? oppositeContentsBuilder,
}) {
return (context, index) {
switch (align) {
case ContentsAlign.alternating:
if (index.isOdd) {
return oppositeContentsBuilder?.call(context, index);
}
return contentsBuilder?.call(context, index);
case ContentsAlign.reverse:
return oppositeContentsBuilder?.call(context, index);
case ContentsAlign.basic:
default:
return contentsBuilder?.call(context, index);
}
};
}
}
With this you'd get a callback to the index that was tapped or long pressed and use that information to change the theme details via changes in view state. Please let me know if there's a better way to do this. Still getting used to Function being a first-class datatype. |
Is there a way to change the colour of a node when it's pressed? I can't seem to see any onTap or onPress methods for a specific node.
The text was updated successfully, but these errors were encountered: