mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Now a RenderBox is considered hit if one of its children are hit or it itself decides that it's hit. In particular, empty space inside a flex won't be hit because none of the children are located there and a RenderFlex doesn't consider itself hittable. Fixes #53 Fixes #1221
79 lines
2.1 KiB
Dart
79 lines
2.1 KiB
Dart
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/animation.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
|
|
import 'binding.dart';
|
|
import 'box.dart';
|
|
import 'object.dart';
|
|
import 'proxy_box.dart';
|
|
|
|
typedef void ValueChanged<T>(T value);
|
|
|
|
const Duration _kToggleDuration = const Duration(milliseconds: 200);
|
|
|
|
// RenderToggleable is a base class for material style toggleable controls with
|
|
// toggle animations. It handles storing the current value, dispatching
|
|
// ValueChanged on a tap gesture and driving a changed animation. Subclasses are
|
|
// responsible for painting.
|
|
abstract class RenderToggleable extends RenderConstrainedBox {
|
|
RenderToggleable({
|
|
bool value,
|
|
Size size,
|
|
this.onChanged
|
|
}) : _value = value,
|
|
super(additionalConstraints: new BoxConstraints.tight(size)) {
|
|
_performance = new ValuePerformance<double>(
|
|
variable: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeIn, reverseCurve: Curves.easeOut),
|
|
duration: _kToggleDuration,
|
|
progress: _value ? 1.0 : 0.0
|
|
)..addListener(markNeedsPaint);
|
|
}
|
|
|
|
bool get value => _value;
|
|
bool _value;
|
|
void set value(bool value) {
|
|
if (value == _value)
|
|
return;
|
|
_value = value;
|
|
performance.play(value ? AnimationDirection.forward : AnimationDirection.reverse);
|
|
}
|
|
|
|
ValueChanged<bool> onChanged;
|
|
|
|
ValuePerformance<double> get performance => _performance;
|
|
ValuePerformance<double> _performance;
|
|
|
|
double get position => _performance.value;
|
|
|
|
TapGestureRecognizer _tap;
|
|
|
|
void attach() {
|
|
super.attach();
|
|
_tap = new TapGestureRecognizer(
|
|
router: FlutterBinding.instance.pointerRouter,
|
|
onTap: _handleTap
|
|
);
|
|
}
|
|
|
|
void detach() {
|
|
_tap.dispose();
|
|
_tap = null;
|
|
super.detach();
|
|
}
|
|
|
|
void handleEvent(InputEvent event, BoxHitTestEntry entry) {
|
|
if (event.type == 'pointerdown' && onChanged != null)
|
|
_tap.addPointer(event);
|
|
}
|
|
|
|
void _handleTap() {
|
|
if (onChanged != null)
|
|
onChanged(!_value);
|
|
}
|
|
|
|
bool hitTestSelf(Point position) => true;
|
|
}
|