如何将小部件的索引值传递给父小部件



当前我的contentIndex成员变量在ResponseItem小部件中返回null。我得到一个无效参数错误。很清楚为什么会发生这种情况。。我需要CCD_ 4中的CCD_;有线的";(由于ResponseItemWidget中的for循环,contentIndex值应反映ResponseItem中的contentIndex值(到其父窗口小部件。我需要将索引值从子小部件拉到父小部件。。不知道该怎么做。。。。

import 'package:flutter/material.dart';

void main()
{
runApp(ResponseItem());
}
class Content{
String body;
String imgUrl;
Content({this.body,this.imgUrl});
}
class Response{
List<Content> content;
Response(this.content);

}
class Prax{
List<Response> responses;
Prax(this.responses);

}

class ResponseItem extends StatelessWidget {
final Prax prax;
final int index;
final contentIndex;
ResponseItem({this.prax,this.index,this.contentIndex});

@override
Widget build(BuildContext context) {
return ResponseItemWidget(body: (prax.responses[index].content.isNotEmpty) ? prax.responses[index].content[contentIndex]?.body : "", 
responseImgUrl: (prax.responses[index].content.isNotEmpty)?prax.responses[index].content[contentIndex].imgUrl:"", 
contentLength: prax.responses[index].content.length,
contentIndex: contentIndex);
}
}


class ResponseItemWidget extends StatelessWidget {

final contentLength;
final String body;
final String responseImgUrl;
int contentIndex;
ResponseItemWidget({
@required this.body,
@required this.responseImgUrl,
@required this.contentLength,
this.contentIndex,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.red,
),
padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
for (contentIndex = 0; contentIndex <= contentLength; contentIndex++)
ListView(children: [
if (contentLength != 0) Text(body[contentIndex] ?? ""),
SizedBox(height: 10),
if (contentLength != 0) Image.network(responseImgUrl[contentIndex]),
]),
],
),
);
}
}


//////////////////////////////

如果您的条目具有预定义的高度,您可以使用ScrollController.position来确定当前查看的条目。

如果不是这样,您可以使用包visibility_detector,如果其中一个项变得不可见,则递增contentIndex

还有一个名为scrollable_positioned_list的包,它为您实现了上述功能。

至于设置值本身,只需将一个函数传递给ValueChanged<int>类型的ResponseItemWidget(相当于void Function(int)(。使contentIndex成为final,不要在ResponseItemWidget中修改它。让家长负责管理状态。

使用此类功能的示例:https://www.dartpad.dev/3749e22cf82e0f1bf3f6d1901dfd3522?null_safety=true

DemoChild(
counter: counter,
onCounterChange: (newValue) => setState(() {
counter = newValue;
}),
);
class DemoChild extends StatelessWidget {
final int counter;
final ValueChanged<int> onCounterChange;
const DemoChild(
{Key? key, required this.counter, required this.onCounterChange})
: super(key: key);
// ...
}

此外,我已经看到您的代码无法工作。我说的是这个部分:

Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
for (contentIndex = 0; contentIndex <= contentLength; contentIndex++)
ListView(children: [
if (contentLength != 0) Text(body[contentIndex] ?? ""),
SizedBox(height: 10),
if (contentLength != 0) Image.network(responseImgUrl[contentIndex]),
]),
],
),

Column将溢出,因为它不关心可滚动性,而ListView将导致渲染问题,因为它从Column获得无限高度。将其更改为

ListView(
children: [
for (contentIndex = 0; contentIndex <= contentLength; contentIndex++)
...[
if (contentLength != 0) Text(body[contentIndex] ?? ""),
SizedBox(height: 10),
if (contentLength != 0) Image.network(responseImgUrl[contentIndex]),
]
],
),

理想情况下(将使您更容易计算当前查看的项目(:

ListView(
children: [
for (contentIndex = 0; contentIndex <= contentLength; contentIndex++)
ResponseListItem(
text: body[contentIndex] ?? "",
imageUrl: responseImgUrl[contentIndex],
)
],
),

最新更新