Reputation: 646
I'm using ListView with simple containers, when you press container in list view it changes selected container width and colour of border, however when this happens it also moves other containers below. What I would like to get is when you select item, change the width and colour of border and don't move items in list as well as items inside of the container.
Please use code below to reproduce the problem, thanks!
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}')
],
),
)),
),
);
}
}
Upvotes: 1
Views: 2411
Reputation: 646
Okay i solved it following way: create extra container with thicker border above container with smaller border and only change colour opacity.
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}')
],
),
)),
),
),
);
}
}
Upvotes: 1