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

Flip panel doesn't repaint while in background #18

Open
klisiewicz opened this issue Nov 26, 2019 · 0 comments
Open

Flip panel doesn't repaint while in background #18

klisiewicz opened this issue Nov 26, 2019 · 0 comments

Comments

@klisiewicz
Copy link

klisiewicz commented Nov 26, 2019

Hello,

I've created a simple page with FlipPanel that uses streams to display to countdown timer value:

Zrzut ekranu 2019-11-26 o 17 21 10

I've also created another page which is a full screen dialog that covers the main page:

Zrzut ekranu 2019-11-26 o 17 21 26

whenever I go back to the main page the FlipPanel doesn't repaints properly in accordance to the events that took place while it was in the background:

Zrzut ekranu 2019-11-26 o 17 21 34

Only when a foreground event takes place the FlipPanel repaints properly:

Zrzut ekranu 2019-11-26 o 17 21 40

The whole application code:

import 'package:flip_panel/flip_panel.dart';
import 'package:flutter/material.dart';
import 'package:rxdart/subjects.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CountdownProvider(
      child: MaterialApp(
        title: 'Flip Panel Demo',
        theme: ThemeData(primarySwatch: Colors.lightGreen),
        home: MainPage(),
      ),
    );
  }
}

class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final countdown = CountdownProvider.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Main Page'),
      ),
      body: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              TimeFlipDigit(
                stream: countdown.tensSecondDigitStream,
                initial: countdown.tensSecondDigit,
              ),
              SizedBox(width: 10),
              TimeFlipDigit(
                stream: countdown.onesSecondDigitStream,
                initial: countdown.onesSecondDigit,
              ),
            ],
          ),
          StreamBuilder(
            stream: countdown.stream,
            builder: (context, snapshot) {
              return snapshot.hasData
                  ? Text(snapshot.data.toString())
                  : SizedBox();
            },
          ),
          RaisedButton(
            color: Theme.of(context).accentColor,
            child: Text('Navigate to other page'),
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  fullscreenDialog: true,
                  builder: (context) => SubPage(),
                ),
              );
            },
          )
        ],
      ),
    );
  }
}

class SubPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final countdown = CountdownProvider.of(context);
    return Scaffold(
      appBar: AppBar(title: Text('Sub page')),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          StreamBuilder(
            stream: countdown.stream,
            builder: (context, snapshot) {
              return snapshot.hasData
                  ? Text(snapshot.data.toString())
                  : SizedBox();
            },
          ),
          Text('Wait for tens second to change then go back'),
        ],
      ),
    );
  }
}

class CountdownProvider extends InheritedWidget {
  CountdownProvider({
    Key key,
    @required Widget child,
  })  : assert(child != null),
        super(key: key, child: child) {
    _subject.addStream(Countdown(Duration(seconds: 59)).stream);

    _tensSecondDigitSubject
        .addStream(_subject.map<int>((d) => (d.inSeconds % 60) ~/ 10));
    _onesSecondDigitSubject
        .addStream(_subject.map<int>((d) => (d.inSeconds % 60) % 10));
  }

  final _subject = BehaviorSubject<Duration>();
  final _tensSecondDigitSubject = BehaviorSubject<int>();
  final _onesSecondDigitSubject = BehaviorSubject<int>();

  Stream<Duration> get stream => _subject.stream;

  Stream<int> get tensSecondDigitStream => _tensSecondDigitSubject.stream;

  Stream<int> get onesSecondDigitStream => _onesSecondDigitSubject.stream;

  int get tensSecondDigit => _tensSecondDigitSubject.value ?? 0;

  int get onesSecondDigit => _tensSecondDigitSubject.value ?? 0;

  static CountdownProvider of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(CountdownProvider);

  @override
  bool updateShouldNotify(InheritedWidget _) => false;
}

class Countdown {
  Countdown(
    this.duration, {
    this.frequency = const Duration(seconds: 1),
  });

  final Duration duration;
  final Duration frequency;

  Duration _remaining;

  Duration get remaining => _remaining;

  Stream<Duration> get stream async* {
    _remaining = duration;
    while (_remaining >= const Duration()) {
      yield _remaining;
      _remaining -= frequency;
      await Future.delayed(frequency);
    }
  }
}

class TimeFlipDigit extends StatelessWidget {
  final Stream<int> stream;
  final int initial;

  const TimeFlipDigit({
    Key key,
    @required this.stream,
    this.initial = 0,
  })  : assert(stream != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return FlipPanel<int>.stream(
      itemStream: stream,
      initValue: initial,
      direction: FlipDirection.down,
      itemBuilder: (context, value) {
        return Container(
          width: 46,
          height: 72,
          decoration: BoxDecoration(
            color: Colors.lightGreen,
            borderRadius: BorderRadius.horizontal(
              left: Radius.circular(3),
              right: Radius.circular(3),
            ),
          ),
          child: Center(
            child: Text(
              '$value',
              style: Theme.of(context).textTheme.display2,
              textAlign: TextAlign.center,
            ),
          ),
        );
      },
    );
  }
}
@klisiewicz klisiewicz changed the title Flip panel doen't refresh properly when in background Flip panel doen't repaint while in background Nov 26, 2019
@klisiewicz klisiewicz changed the title Flip panel doen't repaint while in background Flip panel doesn't repaint while in background Nov 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant