Hhorn
Hhorn

Reputation: 223

Calendar weekview in flutter

I am trying to program a weekview like in the google calendar for flutter. I want to display a timetable where the events begin and end at individual times (e.g. 9:34, 17:11) and at exactly the times they should be displayed in the calendar. So not rounded up or down to the full hour as I currently implemented it with a table widget.

What would be the best way to achieve such an view. I don't know where to start. The horizontal scrolling itself isn't so important. But the vertical one is my problem. How do I place these event widgets at a specific position in a scrollable list?

I appreciate every kind of answer. It would help me very much.

Example of weekview in calendar

Upvotes: 3

Views: 7867

Answers (2)

Skyost
Skyost

Reputation: 1536

I'm a bit late here but I've created a library that can offer you exactly what you want :

It's called FlutterWeekView and here are some links if you're still interested :

Preview :

Upvotes: 0

boformer
boformer

Reputation: 30103

Here is a poor mans version, using a CustomScrollView and simple Stacks with Positioned children.

Things are getting more difficult if you also want horizontal scrolling. For really complex layouts with animations, you may need a custom layout.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Playground',
      home: TestPage(),
    );
  }
}

class TestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Calendar'),
      ),
      body: WeekView(),
    );
  }
}

const headerHeight = 50.0;
const hourHeight = 100.0;

class WeekView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: <Widget>[
        SliverPersistentHeader(
          delegate: WeekViewHeaderDelegate(),
          pinned: true,
        ),
        SliverToBoxAdapter(
          child: _buildGrid(),
        )
      ],
    );
  }

  Widget _buildGrid() {
    return SizedBox(
      height: hourHeight * 24,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: List.generate(7, (d) => _buildColumn(d)),
      ),
    );
  }

  Widget _buildColumn(int d) {
    return Expanded(
      child: Stack(
        children: <Widget>[
          Positioned(
            left: 0.0,
            top: d * 25.0,
            right: 0.0,
            height: 50.0 * (d + 1),
            child: Container(
              margin: EdgeInsets.symmetric(horizontal: 2.0),
              color: Colors.orange[100 + d * 100],
            ),
          )
        ],
      ),
    );
  }
}

class WeekViewHeaderDelegate extends SliverPersistentHeaderDelegate {
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: Colors.red.withOpacity(0.5),
      child: Center(
        child: Text('HEADER'),
      ),
    );
  }

  @override
  double get maxExtent => headerHeight;

  @override
  double get minExtent => headerHeight;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return false;
  }
}

Upvotes: 6

Related Questions