I have a ListView
that contains ListTile
s that change color when selected. However, in the code below when there is an intermediate Container
or SizedBox
between the ListView
and the Scaffold
, SelectedTileColor
does not work.
I followed this issue and I wrapped my ListView
with Ink
and still does not work.
In the code below, if you remove the intermediate BottomPanel
widget by replacing BottomPanel
in line 20 with VehicleTypePanel
then it will work.
What is going wrong? why is BottomPanel
preventing SelectedTileColor
to take place?
https://dartpad.dev/?id=ddb60a7657ddb0cc30b4bdd0d86754cd
import 'package:flutter/material.dart';
import 'dart:math';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: BottomPanel(),
),
),
);
}
}
class BottomPanel extends StatelessWidget {
BottomPanel({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
return SizedBox(
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 10,
spreadRadius: 5)
]),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: VehicleTypePanel(),
layoutBuilder: (currentChild, previousChildren) => Stack(
children: [
...previousChildren,
if (currentChild != null) currentChild,
],
)),
),
height: mediaQuery.size.height,
width: mediaQuery.size.width,
);
}
}
List<Map<String, String>> vehicles = [
{"type": "car", 'seats': '4', 'image': 'assets/car.jpeg'},
];
class VehicleTypePanel extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const VehicleItem(
type: "car",
seats: "4",
image: 'assets/car.jpeg',
index: 0,
selectedIndex: 0),
const Divider(),
const VehicleItem(
type: "van",
seats: "6",
image: 'assets/van.jpeg',
index: 1,
selectedIndex: 0),
const Divider(),
//drop down textbutton with icon
FractionallySizedBox(widthFactor: .8, child: PaymentMethod()),
const SizedBox(height: 10),
FractionallySizedBox(
widthFactor: .8, // means 100%, you can change this to 0.8 (80%)
child: ElevatedButton(
style: ElevatedButton.styleFrom(
fixedSize: const Size.fromHeight(50),
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
onPressed: () {},
child: const Text('Select Vehicle'),
),
),
],
);
}
}
class PaymentMethod extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Icon(Icons.person),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: const TextSpan(
children: [
TextSpan(
style: TextStyle(color: Colors.black),
text: "Payment Method",
),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(Icons.arrow_drop_down, size: 18),
),
],
),
),
const Text("Cash"),
],
),
],
);
}
}
class VehicleItem extends StatelessWidget {
final String type;
final String seats;
final String image;
final int index;
final int selectedIndex;
//final Function(GooglePlace, bool) onPlaceSelected;
const VehicleItem(
{Key? key,
required this.type,
required this.seats,
required this.image,
required this.index,
required this.selectedIndex})
: super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
onTap: () {},
selected: index == selectedIndex,
selectedTileColor: Colors.amber,
selectedColor: Colors.deepOrange,
title: Text(type),
subtitle: RichText(
text: TextSpan(
style: const TextStyle(color: Colors.deepOrange),
children: [
const WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(Icons.person, size: 18),
),
TextSpan(
text: "$seats seats",
),
],
),
),
trailing: const Text("10\$"),
);
}
}
CodePudding user response:
In the ListTile
documentation,
The tileColor, selectedTileColor, focusColor, and hoverColor are not painted by the list tile itself but by the material widget ancestor. This generally has no effect. However, if an opaque widget, like Container(color: Colors.white), is included in between the ListTile and its Material ancestor, then the opaque widget will obscure the material widget and its background tileColor, etc. If this a problem, one can wrap a material widget around the list tile
So just replace VehicleTypePanel()
with Material(type: MaterialType.transparency, child: VehicleTypePanel())
.