chulwoo-park/timelines

Vertical align indicators with item content

frmatthew opened this issue · 5 comments

Thanks for the promising plugin. Is there any way to control vertical positioning of the indicators? For example, if I use larger titles, can I force the indicators down in order to line them up with the content titles better ? Here's the problem I'm facing:

Screenshot_20201209-081739

and my item builder:

            contentsBuilder: (context, index) => Padding(
            padding: const EdgeInsets.only(
              left: 30,
              bottom: 30,
              right: 30,
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Timeline Event $index',
                  textScaleFactor: 3,
                ),
                SizedBox(height: 10),
                Text('Nam libero tempore, cum soluta nobis...') // truncated for brevity here
              ],
            ),
          ),

But it's not clear to me how I can shift the indicators down, either all together, or individually, in order to line up with the titles better...? Thanks.

Of course! you can positioning indicator use this:

  • TimelineTheme.indicatorPosition
  • IndicatorTheme.position
  • TimelineNode.indicatorPosition
  • Indicator.position

If you want change whole position, then use Theme's position. Or if you want change each indicator position in the Node, then use TimelineNode's indicatorPosition or Indicator's position.

You can visually see how each value works here.

Check out how to use the theme here.

Thanks!

And there is a new feature that discussion on GitHub, so if you have another question, try this section. 😄

Oh I see. indicatorPosition works great if all items have the same extent. In my use case, the items extents are variable, and it's not feasible to calculate the item extent and try to reverse engineer indicatorPosition to line it up with the title text. But thanks anyway.

Oops, I misunderstood your question.
When my working hours are over, I'll look at your use case in more detail.

As you said, there is no way to place it exactly on Text. 😢

how about this?

It feels like workaround... but it works:

image

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Timeline.tileBuilder(
      theme: TimelineThemeData(
        color: Colors.grey,
        nodePosition: 0.0,
        indicatorTheme: IndicatorThemeData(),
        connectorTheme: ConnectorThemeData(
          space: 50.0,
        ),
      ),
      padding: EdgeInsets.symmetric(vertical: 100.0),
      builder: TimelineTileBuilder.connected(
        indicatorBuilder: (context, index) {
          if (index.isEven) {
            return Indicator.outlined(
              size: 25.0,
              borderWidth: 3.0,
            );
          } else {
            return Indicator.transparent();
          }
        },
        connectorBuilder: (context, index, type) {
          return Connector.solidLine(
            thickness: 3.0,
          );
        },
        contentsBuilder: (context, index) {
          var contents;
          if (index.isEven) {
            if (index == 0) {
              contents = Text(
                'Timeline Event ${index ~/ 2}\nMultiline Title',
                textScaleFactor: 2,
              );
            } else {
              contents = Text(
                'Timeline Event ${index ~/ 2}',
                textScaleFactor: 2,
              );
            }

            contents = Padding(
              padding: EdgeInsets.only(
                left: 30.0,
                right: 30.0,
              ),
              child: contents,
            );
          } else {
            contents = Padding(
              padding: EdgeInsets.all(30.0),
              child: Text(
                'Nam libero tempore, cum soluta nobis... Nam libero tempore, cum soluta nobis... Nam libero tempore, cum soluta nobis... Nam libero tempore, cum soluta nobis...Nam libero tempore, cum soluta nobis...',
              ),
            );
          }

          return contents;
        },
        itemCount: 30,
      ),
    ),
  );
}

I don't have any idea yet to make this kind of use case easier to implement. I'll think about it.
If you have a good idea, please new issue or PR!