gpt4 book ai didi

使用自定义 ScrollPhysics 使用动态边界 flutter PageView

转载 作者:IT王子 更新时间:2023-10-29 07:20:30 25 4
gpt4 key购买 nike

我正在尝试动态设置 PageView 边界。这是一个简化的示例,从第 10 页开始,左右边界由随机数生成器(leftEnd,rightEnd)设置。

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

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

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

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

@override
_MyTabbedPageState createState() => new _MyTabbedPageState();
}

class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
final leftEnd = Random().nextInt(5);
final rightEnd = 10 + Random().nextInt(5);
CustomScrollPhysics scrollPhysics = CustomScrollPhysics();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: PageView.builder(
controller: PageController(initialPage: 10),
physics: scrollPhysics,
itemBuilder: (context, index) {
scrollPhysics.leftEnd = (index <= leftEnd);
scrollPhysics.rightEnd = (index >= rightEnd);

// --------- print (1) ----------
print("is leftEnd: ${index <= leftEnd}");
print("is rightEnd: ${index >= rightEnd}");
print("scrollphysics.leftEnd: ${scrollPhysics.leftEnd}");
print("scrollphysics.rightEnd: ${scrollPhysics.rightEnd}");
return Center(
child: Text("Item $index"),
);
}
));
}
}

class CustomScrollPhysics extends ScrollPhysics {
CustomScrollPhysics({ScrollPhysics parent}) : super(parent: parent);

bool leftEnd = false;
bool rightEnd = false;
bool isGoingLeft = false;

@override
CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
return CustomScrollPhysics(parent: buildParent(ancestor));
}

@override
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
isGoingLeft = offset.sign < 0;
return offset;
}

@override
double applyBoundaryConditions(ScrollMetrics position, double value) {
//print("applyBoundaryConditions");
assert(() {
if (value == position.pixels) {
throw FlutterError(
'$runtimeType.applyBoundaryConditions() was called redundantly.\n'
'The proposed new position, $value, is exactly equal to the current position of the '
'given ${position.runtimeType}, ${position.pixels}.\n'
'The applyBoundaryConditions method should only be called when the value is '
'going to actually change the pixels, otherwise it is redundant.\n'
'The physics object in question was:\n'
' $this\n'
'The position object in question was:\n'
' $position\n');
}
return true;
}());
if (value < position.pixels && position.pixels <= position.minScrollExtent)
return value - position.pixels;
if (position.maxScrollExtent <= position.pixels && position.pixels < value)
// overscroll
return value - position.pixels;
if (value < position.minScrollExtent &&
position.minScrollExtent < position.pixels) // hit top edge

return value - position.minScrollExtent;

if (position.pixels < position.maxScrollExtent &&
position.maxScrollExtent < value) // hit bottom edge
return value - position.maxScrollExtent;

// --------- print (2) ----------
if (leftEnd) print("leftEnd");
if (rightEnd) print("rightEnd");
if (isGoingLeft) print("isGoingLeft");

if (leftEnd && !isGoingLeft) {
return value - position.pixels;
} else if (rightEnd && isGoingLeft) {
return value - position.pixels;
}
return 0.0;
}
}

scrollphysics.leftEnd/rightEnd 在 PageView.builder 中发生变化(基于 print (1)),但在 CustomScrollPhysics 中没有变化(没有 print (2))。

谁能解释一下这里发生了什么?这是为 PageView 设置动态边界的正确方法吗?

最佳答案

ScrollPhysics,您的 CustomScrollPhysics 从中扩展,被标记为不可变。即使您在 itemBuilder 中更改其 bool 值,实际的 bool 值也不会更改(如未在 中打印 leftEndrightEnd 所示应用边界条件)。我没有官方解释为什么你的 itemBuilder 中的 scrollPhysics.leftEnd 显示所需的更改 bool 值,而它在类本身中没有更改,但我猜是因为您没有将这些变量设置为 final,因为它们应该是这样,没有什么能阻止您更改它们,所以您的本地 scrollPhysics_MyTabbedPageState 正在显示这些更改,即使它们在内部没有更改。 isGoingLeft 之所以被打印出来,是因为它是在 CustomScrollPhysics 内部更改的,而不是从 itemBuilder 中看到的外部更改。

作为快速修复,我创建了另一个类:

class Status {
bool leftEnd = false;
bool rightEnd = false;
bool isGoingLeft = false;
}

稍微更改了您的CustomScrollPhysics:

class CustomScrollPhysics extends ScrollPhysics {
final Status status;

CustomScrollPhysics(this.status, {ScrollPhysics parent})
: super(parent: parent);

@override
CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
return CustomScrollPhysics(this.status, parent: buildParent(ancestor));
}

...

并在您所在状态的构造函数调用中添加了一个 Status 实例:

CustomScrollPhysics scrollPhysics = CustomScrollPhysics(Status());

将所有更改应用于 CustomScrollPhysics 内的 this.status。现在它应该按预期工作。

关于使用自定义 ScrollPhysics 使用动态边界 flutter PageView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55947158/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com