我正在将ListView与简单容器一起使用,当您在列表视图中按容器时,它会更改选定容器的宽度和边框颜色,但是,当发生这种情况时,它也会在下面移动其他容器。我想得到的是,当您选择项目时,更改边框的宽度和颜色,并且不移动列表中的项目以及容器内部的项目。
请使用下面的代码重现该问题,谢谢!
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter border demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
}
List<int> values = [1, 2, 3];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Border demo'),
centerTitle: true,
),
body: Container(
child: ListView.builder(
itemCount: values.length,
itemBuilder: (BuildContext context, int index) =>
BorderContainer(value: values[index])),
));
}
}
class BorderContainer extends StatefulWidget {
final int value;
const BorderContainer({Key key, this.value}) : super(key: key);
@override
_BorderContainerState createState() => _BorderContainerState();
}
class _BorderContainerState extends State<BorderContainer> {
bool isTapped = false;
@override
Widget build(BuildContext context) {
return Container(
// height: 95, // if we add this rest of list items will not move however it will move items inside of container
child: GestureDetector(
onTapDown: (TapDownDetails details) => setState(() {
isTapped = true;
}),
onTapUp: (TapUpDetails details) => setState(() {
isTapped = false;
}),
child: Container(
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
width: isTapped ? 2.0 : 1.0,
//when pressing it moves other items because of width change
color:
isTapped ? Colors.grey : Colors.grey.withOpacity(0.3)),
borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Text('${widget.value}'),
Text('Another item in container number: ${widget.value}')
],
),
)),
),
);
}
}
好,我通过以下方法解决了问题:在边框较小的容器上方创建额外的边框较粗的容器,仅更改颜色不透明度。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter border demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
}
List<int> values = [1, 2, 3];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Border demo'),
centerTitle: true,
),
body: Container(
child: ListView.builder(
itemCount: values.length,
itemBuilder: (BuildContext context, int index) =>
BorderContainer(value: values[index])),
));
}
}
class BorderContainer extends StatefulWidget {
final int value;
const BorderContainer({Key key, this.value}) : super(key: key);
@override
_BorderContainerState createState() => _BorderContainerState();
}
class _BorderContainerState extends State<BorderContainer> {
bool isTapped = false;
@override
Widget build(BuildContext context) {
var innerBorder = Border.all(
width: 1.0,
color: isTapped
? Colors.grey.withOpacity(0)
: Colors.grey.withOpacity(0.3));
var outerBorder = Border.all(
width: 3.0, color: isTapped ? Colors.grey : Colors.grey.withOpacity(0));
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
border: outerBorder, borderRadius: BorderRadius.circular(16)),
child: GestureDetector(
onTapDown: (TapDownDetails details) => setState(() {
isTapped = true;
}),
onTapUp: (TapUpDetails details) => setState(() {
isTapped = false;
}),
child: Container(
decoration: BoxDecoration(
border: innerBorder, borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Text('${widget.value}'),
Text('Another item in container number: ${widget.value}')
],
),
)),
),
),
);
}
}