我需要继承自定义ListTile上的主题。
我创建了一个没有继承自定义列表的自定义ListTile,只是一个全状态的小部件。如何使它继承ListTile的所有主题?
通常,我通常会在单个窗口小部件上实现这一目标,并将特定值设置为Theme.of(context).whateverTheme.whateverValue
。到目前为止,它一直没有任何问题,但是现在我看到即使list_tile.dart拥有.ListViewTheme
或.ListTileTheme
也没有使用。它可能没有暴露。
这使我怀疑自己这是否是正确的方法。
在代码中查找<= I want here
class CustomMenuTile extends StatefulWidget {
CustomMenuTile({Key key, this.selected, this.icon, this.text, this.routePage})
: super(key: key);
final bool selected;
final IconData icon;
final String text;
final Widget routePage;
@override
_CustomMenuTileState createState() => _CustomMenuTileState();
}
class _CustomMenuTileState extends State<CustomMenuTile> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
constraints: BoxConstraints.expand(height: 48),
child: Material(
color: widget.selected ? kPrimarySwatch[400].withAlpha(100) : null,
borderRadius: BorderRadius.all(Radius.circular(4)),
child: InkWell(
splashColor: Colors.grey.withAlpha(64),
highlightColor: Colors.grey.withAlpha(64),
borderRadius: BorderRadius.all(Radius.circular(4)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 24),
child: Icon(widget.icon,
color: widget.selected
? Theme.of(context).accentColor
: null, <= I want here Theme.of(context).ListViewTheme.iconColor
)),
Text(widget.text,
style: TextStyle(
fontWeight: FontWeight.bold,
color: widget.selected
? Theme.of(context).accentColor
: null)),
],
),
),
onTap: () {
Navigator.pop(context);
Navigator.of(context)
.pushReplacement(_createFadeRoute(widget.routePage));
}),
),
);
}
}
答案 0 :(得分:1)
您可以使用ListTileTheme.of(context).textColor
或ListTileTheme
的任何属性。
如果应用未定义ListTileTheme
,则所有属性均返回null
。在这种情况下,ListTile
定义它自己的值。您可以查看默认值ListTile
并使用,如果ListTileTheme
的属性为null
答案 1 :(得分:0)
我认为null
确实使用默认值。您可能正在寻找textTheme
属性。
Text(widget.text,
style: TextStyle(
fontWeight: FontWeight.bold,
color: widget.selected
? Theme.of(context).accentColor
: Theme.of(context).textTheme.body.color),
答案 2 :(得分:0)
在list_tile.dart内部查看似乎该颜色正在从ListTileTheme中获取颜色,但是一旦您不将代码包装在ListTileTheme小部件中,该应用程序就会表现为它实际上没有该代码是真的。
在这种情况下,它只适用于硬编码的颜色Colors.black45,但这仅适用于ListTile的图标,而不是常规的Icon小部件。
Color _iconColor(ThemeData theme, ListTileTheme tileTheme) {
if (!enabled)
return theme.disabledColor;
if (selected && tileTheme?.selectedColor != null)
return tileTheme.selectedColor;
if (!selected && tileTheme?.iconColor != null)
return tileTheme.iconColor;
switch (theme.brightness) {
case Brightness.light:
return selected ? theme.primaryColor : Colors.black45;
case Brightness.dark:
return selected ? theme.accentColor : null; // null - use current icon theme color
}
assert(theme.brightness != null);
return null;
}
在github上有一个关于ThemeData上缺少的TileListTheme的公开问题。 https://github.com/flutter/flutter/issues/31247
以下是解决方法的完整示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListTileTheme(
iconColor: Colors.blue,
child: MaterialApp(
title: 'Flutter 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
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ListTileTheme example"),
),
body: ListView(
children: <Widget>[
ListTile(
title: Text("ListTile IS inheriting the color"),
leading: Icon(Icons.list),
),
Row(
children: <Widget>[
Icon(Icons.list),
Text("Other Icon is NOT inheriting the color..."),
],
),
Row(
children: <Widget>[
Icon(Icons.list, color: ListTileTheme.of(context).iconColor),
Text("...unless you use ListTileTheme.of(context).iconColor"),
],
),
],
),
);
}
}
此代码将产生以下结果: