Вставьте складной календарь перед списком, похожим на календарь Google во флаттере - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь создать страницу, похожую на дневной вид Календаря Google во Флаттере.

Пример Календаря Google

Вот упрощенный исполняемый файл версия моего текущего кода (в качестве дополнительной зависимости требуется "table_calendar: ^ 0.1.3"):

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math';
import 'package:table_calendar/table_calendar.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [const Locale('en')],
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MonthPage(),
    );
  }
}

class MonthPage extends StatefulWidget {
  MonthPage({key}) : super(key: key);
  State<MonthPage> createState() => MonthPageState();
}

class MonthPageState extends State<MonthPage> with TickerProviderStateMixin {
  CalendarController _calendarController;
  ScrollController _scrollController;
  DateTime _selectedDate;
  bool _isExpanded;
  double _rotationDegree;

  @override
  void initState() {
    _isExpanded = false;
    _rotationDegree = 0;
    _selectedDate = DateTime.now();
    _calendarController = CalendarController();
    _scrollController = ScrollController();
    _scrollController.addListener(_scrollListner);
    super.initState();
  }

  void _scrollListner() {
    setState(() {
      if (_isExpanded) {
        double rotationDegree = pi * _scrollController.offset / 212;
        if (rotationDegree >= pi) {
          _rotationDegree = 0;
          _isExpanded = !_isExpanded;
        } else {
          _rotationDegree = rotationDegree;
        }
      }
    });
  }

  @override
  void dispose() {
    _calendarController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  _toogleExpand() {
    setState(() {
      _isExpanded = !_isExpanded;
    });
  }

  Widget GetAppBarTitle() {
    return Row(
      children: <Widget>[
        Text("${_selectedDate}"),
        Transform.rotate(
            angle: _rotationDegree,
            child: IconButton(
              icon: Icon(
                  _isExpanded ? Icons.arrow_drop_up : Icons.arrow_drop_down),
              onPressed: () {
                _toogleExpand();
              },
            )),
      ],
    );
  }

  Widget ShowCalendar() {
    if (_isExpanded) {
      return TableCalendar(
        rowHeight: 37,
        locale: "de_DE",
        calendarStyle: CalendarStyle(
            contentPadding: EdgeInsets.only(top: 7),
            weekdayStyle: TextStyle(
              fontSize: 12,
            ),
            weekendStyle: TextStyle(fontSize: 12)),
        calendarController: _calendarController,
        startingDayOfWeek: StartingDayOfWeek.monday,
        headerVisible: false,
        onVisibleDaysChanged: (first, last, format) {
          setState(() {
            _selectedDate = last;
          });
        },
        onDaySelected: (date, events) {
          setState(() {
            _selectedDate = date;
          });
        },
      );
    } else {
      return SizedBox.shrink();
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: CustomScrollView(
        controller: _scrollController,
        slivers: <Widget>[
          SliverAppBar(pinned: true, title: GetAppBarTitle()),
          SliverToBoxAdapter(child: ShowCalendar()),
          SliverToBoxAdapter(
              child: Container(height: 0.1, child: Material(child: Divider()))),
          SliverPadding(
              padding: EdgeInsets.only(top: 10),
              sliver: SliverList(
                delegate: SliverChildBuilderDelegate(
                    (context, index) =>
                        InkWell(child: Text("My list item ${index}")),
                    childCount: 70),
              ))
        ],
      ),
    );
  }
}


Теперь у меня есть следующая проблема :

Когда пользователь прокручивает страницу вниз и открывает календарь (выпадающий значок), календарь должен быть виден и соответствующая позиция списка должна сохраняться. В настоящее время календарь отображается за пределами области, видимой пользователю перед списком.

Я уже пытался вставить календарь в SliverAppBar в качестве фона в FlexibleSpace, но затем календарь пересекается с заголовком при прокрутке вверх.

Я благодарен за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...