Skip to content

Commit

Permalink
feat: using existedChildren instead of autoWrap.
Browse files Browse the repository at this point in the history
  • Loading branch information
endless7 committed Sep 16, 2022
1 parent 9495f7a commit 1521a10
Show file tree
Hide file tree
Showing 10 changed files with 935 additions and 22 deletions.
6 changes: 4 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import 'package:example/pages/life_cycle_page.dart';
import 'package:example/pages/loadMore_page.dart';
import 'package:example/pages/position_page.dart';
import 'package:example/pages/jump_page.dart';
import 'package:example/pages/scroll_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
Expand Down Expand Up @@ -31,8 +32,9 @@ class MyApp extends StatelessWidget {
class HomePage extends StatelessWidget {

final Map<String, Widget> m = {
"Position": const PositionedListPage(),
"JumpTo": const JumpToPage(),
"loadMore": const LoadMorePage(),
"ScrollTo": const ScrollToPage(),
"LifeCycle": const LifeCyclePage()
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ const scrollDuration = Duration(seconds: 2);

const randomMax = 1 << 32;

class PositionedListPage extends StatefulWidget {
const PositionedListPage({Key? key}) : super(key: key);
class JumpToPage extends StatefulWidget {
const JumpToPage({Key? key}) : super(key: key);

@override
_ScrollablePositionedListPageState createState() =>
_ScrollablePositionedListPageState();
}

class _ScrollablePositionedListPageState
extends State<PositionedListPage> {
extends State<JumpToPage> {

late List<double> itemHeights;
late List<Color> itemColors;
Expand Down Expand Up @@ -64,7 +64,7 @@ class _ScrollablePositionedListPageState
children: <Widget>[
Column(
children: <Widget>[
scrollControlButtons,
// scrollControlButtons,
jumpControlButtons,
// alignmentControl,
],
Expand Down Expand Up @@ -133,16 +133,6 @@ class _ScrollablePositionedListPageState
);
}

Widget get scrollControlButtons => Row(
children: <Widget>[
const Text('scroll to'),
scrollButton(0),
scrollButton(5),
scrollButton(10),
scrollButton(30),
],
);

Widget get jumpControlButtons => Row(
children: <Widget>[
const Text('jump to'),
Expand Down
189 changes: 189 additions & 0 deletions example/lib/pages/scroll_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file may have been modified by Bytedance Inc.(“Bytedance Inc.'s
// Modifications”). All Bytedance Inc.'s Modifications are Copyright (2022)
// Bytedance Inc..

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:scroll_kit/scroll_kit.dart';

const numberOfItems = 5001;
const minItemHeight = 20.0;
const maxItemHeight = 150.0;
const scrollDuration = Duration(seconds: 2);

const randomMax = 1 << 32;

class ScrollToPage extends StatefulWidget {
const ScrollToPage({Key? key}) : super(key: key);

@override
_ScrollablePositionedListPageState createState() =>
_ScrollablePositionedListPageState();
}

class _ScrollablePositionedListPageState
extends State<ScrollToPage> {

late List<double> itemHeights;
late List<Color> itemColors;
bool reversed = false;

/// The alignment to be used next time the user scrolls or jumps to an item.
double alignment = 0;

@override
void initState() {
super.initState();
final heightGenerator = Random(328902348);
final colorGenerator = Random(42490823);
itemHeights = List<double>.generate(
numberOfItems,
(int _) =>
heightGenerator.nextDouble() * (maxItemHeight - minItemHeight) +
minItemHeight);
itemColors = List<Color>.generate(numberOfItems,
(int _) => Color(colorGenerator.nextInt(randomMax)).withOpacity(1));
}

@override
Widget build(BuildContext context) => Material(
child: OrientationBuilder(
builder: (context, orientation) => Column(
children: <Widget>[
Expanded(
child: list1(),
// child: list(orientation),
),
Container(
height: 100,
child: Row(
children: <Widget>[
Column(
children: <Widget>[
scrollControlButtons,
],
),
],
)
)
],
),
),
);

Widget get alignmentControl => Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
const Text('Alignment: '),
SizedBox(
width: 100,
child: SliderTheme(
data: SliderThemeData(
showValueIndicator: ShowValueIndicator.always,
),
child: Slider(
value: alignment,
label: alignment.toStringAsFixed(2),
onChanged: (double value) => setState(() => alignment = value),
),
),
),
],
);

late SKPositionController controller;

List<int> data = () {
List<int> data = <int>[];
for (var i = 0; i < 50; i++) {
data.add(i);
}
return data;
}();

Widget list1() {

controller = SKPositionController(
viewportBoundaryGetter: () =>
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: Axis.vertical
);

return SKPositionedList(
controller: controller,
delegate: SKSliverChildBuilderDelegate(
(context, index) {
return Container(
height: 80,
color: Colors.grey,
child: Center(
child: Text(data[index].toString()),
),
);
},
childCount: data.length,
reuseIdentifier: (i)=>""
),
);
}

Widget get scrollControlButtons => Row(
children: <Widget>[
const Text('scroll to'),
scrollButton(0),
scrollButton(5),
scrollButton(10),
scrollButton(30),
],
);

final _scrollButtonStyle = ButtonStyle(
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
),
minimumSize: MaterialStateProperty.all(Size.zero),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
);

Widget scrollButton(int value) => TextButton(
key: ValueKey<String>('Scroll$value'),
onPressed: () => scrollTo(value),
child: Text('$value'),
style: _scrollButtonStyle,
);

Widget jumpButton(int value) => TextButton(
key: ValueKey<String>('Jump$value'),
onPressed: () async {
await jumpTo(value);
},
child: Text('$value'),
style: _scrollButtonStyle,
);

Future<void> scrollTo(int index) {
return controller.scrollTo(index);
}

Future<void> jumpTo(int index) {
return controller.jumpTo(index);
}

/// Generate item number [i].
Widget item(int i, Orientation orientation) {
return SizedBox(
height: orientation == Orientation.portrait ? itemHeights[i] : null,
width: orientation == Orientation.landscape ? itemHeights[i] : null,
child: Container(
color: itemColors[i],
child: Center(
child: Text('Item $i'),
),
),
);
}
}
4 changes: 4 additions & 0 deletions lib/src/adaptor/ro.dart
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ abstract class SKRenderSliverMultiBoxAdaptor extends RenderSliver
void _createOrObtainChild(int index, { required RenderBox? after }) {
invokeLayoutCallback<SliverConstraints>((SliverConstraints constraints) {
assert(constraints == this.constraints);
existChildren.add(index);
if (_keepAliveBucket.containsKey(index)) {
final RenderBox child = _keepAliveBucket.remove(index)!;
final SKSliverMultiBoxAdaptorParentData childParentData = child.parentData! as SKSliverMultiBoxAdaptorParentData;
Expand All @@ -257,6 +258,7 @@ abstract class SKRenderSliverMultiBoxAdaptor extends RenderSliver

void _destroyOrCacheChild(RenderBox child) {
final SKSliverMultiBoxAdaptorParentData childParentData = child.parentData! as SKSliverMultiBoxAdaptorParentData;
existChildren.remove(indexOf(child));
if (childParentData.keepAlive) {
assert(!childParentData._keptAlive);
remove(child);
Expand All @@ -274,6 +276,8 @@ abstract class SKRenderSliverMultiBoxAdaptor extends RenderSliver

final List<int> _exposedChildren = [];

final List<int> existChildren = [];

final SKLifeCycleManager _lifeCycleManager;

void handleLifeCycle({required SliverConstraints constraints, double? extent}) {
Expand Down
6 changes: 5 additions & 1 deletion lib/src/adaptor/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
import 'package:scroll_kit/scroll_kit.dart';
import 'package:scroll_kit/src/utils/auto_scroll.dart';

import 'element.dart';
import 'ro.dart';
Expand All @@ -18,11 +19,14 @@ abstract class SKSliverMultiBoxAdaptorWidget extends SliverWithKeepAliveWidget {
const SKSliverMultiBoxAdaptorWidget({
super.key,
required this.delegate,
this.forwardRefreshCount
this.forwardRefreshCount,
this.scrollController
}) : assert(delegate != null);

final int? forwardRefreshCount;

final AutoScrollController? scrollController;

/// {@template flutter.widgets.SliverMultiBoxAdaptorWidget.delegate}
/// The delegate that provides the children for this widget.
///
Expand Down
3 changes: 1 addition & 2 deletions lib/src/refresh/smart_refresher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@

import 'dart:async';

import 'package:scroll_to_index/scroll_to_index.dart';
import '../utils/auto_scroll.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart' hide RefreshIndicator, RefreshIndicatorState;
import 'package:flutter/physics.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/foundation.dart';
import 'package:scroll_kit/src/refresh/internals/slivers.dart';
Expand Down
3 changes: 2 additions & 1 deletion lib/src/sk_positioned_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:scroll_kit/src/sk_sliver_list.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'utils/auto_scroll.dart';
import 'sk_child_delegate.dart';

// ignore: must_be_immutable
Expand Down Expand Up @@ -98,6 +98,7 @@ class _SKPositionedListState extends State<SKPositionedList>
SKSliverList(
delegate: widget.delegate,
forwardRefreshCount: forwardRefreshCount,
scrollController: widget.controller.scrollController,
)
],
);
Expand Down
6 changes: 5 additions & 1 deletion lib/src/sk_sliver_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:scroll_kit/src/utils/auto_scroll.dart';
import 'sk_child_delegate.dart';
import 'adaptor/widget.dart';
import 'adaptor/element.dart';
Expand All @@ -20,6 +21,7 @@ class SKSliverList extends SKSliverMultiBoxAdaptorWidget {
super.key,
required super.delegate,
super.forwardRefreshCount,
super.scrollController
});

@override
Expand All @@ -30,8 +32,10 @@ class SKSliverList extends SKSliverMultiBoxAdaptorWidget {
SKRenderSliverList createRenderObject(BuildContext context) {
final SKSliverMultiBoxAdaptorElement element =
context as SKSliverMultiBoxAdaptorElement;
return SKRenderSliverList(
final renderList = SKRenderSliverList(
childManager: element, lifeCycleManager: delegate);
scrollController?.adaptor = renderList;
return renderList;
}
}

Expand Down
Loading

0 comments on commit 1521a10

Please sign in to comment.