- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 ExpansionPanelList 的 ListTile 中,试用已经作为向下箭头给出,当 ListTile 展开时,箭头变为向上箭头。
但是,它的颜色很深。我添加了尾随:图标(blah blah)。这只是在标题和默认尾随按钮(向下箭头)之间添加了一个图标。
如何更改默认尾随按钮的颜色,同时保持其在框展开时变为向上箭头的多功能性?
我尝试将 ListTile 包裹在一个主题中,这是有人推荐的,但是向下箭头的颜色没有改变,如下所示:
Widget _buildPanel() {
return ExpansionPanelList.radio(
initialOpenPanelValue: 0,
children: _data.map<ExpansionPanelRadio>((Item item) {
return ExpansionPanelRadio(
backgroundColor: Colors.black,
canTapOnHeader: true,
value: item.id,
headerBuilder: (BuildContext context, bool isExpanded) {
return Theme(
data: Theme.of(context)
.copyWith(unselectedWidgetColor: Colors.white),
child: ListTile(
title: Text(item.headerValue,
...
最佳答案
如果您使用的是 ExpansionPanelList
,您只能通过主题亮度更改它的 ExpandIcon
(带有箭头的小部件)的颜色,这里是摘录ExpandIcon
中的代码:
switch(Theme.of(context).brightness) {
case Brightness.light:
return Colors.black54;
case Brightness.dark:
return Colors.white60;
}
此小部件还具有更改其扩展和禁用颜色的属性,但不幸的是 ExpansionPanelList
不会将这些自定义属性传递给 ExpandIcon
因此您将转到后备开关 I粘贴在上面。
一种解决方案是从框架中提取 ExpansionPanelList
并将属性 color,disabledColor,expandedColor,
添加到其构造函数中。我将类 ExpansionPanelList
重命名为 ColoredExpansionPanelList
并添加了之前的颜色属性以将它们传递给它的子级 ExpandIcon
。
// The following code is the same that is found inside the Flutter framework
//just adding the `color,disabledColor,expandedColor` for personalizing the `ExpandedIcon`
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
const double _kPanelHeaderCollapsedHeight = kMinInteractiveDimension;
const EdgeInsets _kPanelHeaderExpandedDefaultPadding = EdgeInsets.symmetric(
vertical: 64.0 - _kPanelHeaderCollapsedHeight,
);
class _SaltedKey<S, V> extends LocalKey {
const _SaltedKey(this.salt, this.value);
final S salt;
final V value;
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType)
return false;
return other is _SaltedKey<S, V>
&& other.salt == salt
&& other.value == value;
}
@override
int get hashCode => hashValues(runtimeType, salt, value);
@override
String toString() {
final String saltString = S == String ? "<'$salt'>" : '<$salt>';
final String valueString = V == String ? "<'$value'>" : '<$value>';
return '[$saltString $valueString]';
}
}
/// Signature for the callback that's called when an [ExpansionPanel] is
/// expanded or collapsed.
///
/// The position of the panel within an [ColoredExpansionPanelList] is given by
/// [panelIndex].
typedef ExpansionPanelCallback = void Function(int panelIndex, bool isExpanded);
/// Signature for the callback that's called when the header of the
/// [ExpansionPanel] needs to rebuild.
typedef ExpansionPanelHeaderBuilder = Widget Function(BuildContext context, bool isExpanded);
/// A material expansion panel. It has a header and a body and can be either
/// expanded or collapsed. The body of the panel is only visible when it is
/// expanded.
///
/// Expansion panels are only intended to be used as children for
/// [ColoredExpansionPanelList].
///
/// See [ColoredExpansionPanelList] for a sample implementation.
///
/// See also:
///
/// * [ColoredExpansionPanelList]
/// * <https://material.io/design/components/lists.html#types>
class ExpansionPanel {
/// Creates an expansion panel to be used as a child for [ColoredExpansionPanelList].
/// See [ColoredExpansionPanelList] for an example on how to use this widget.
///
/// The [headerBuilder], [body], and [isExpanded] arguments must not be null.
ExpansionPanel({
required this.headerBuilder,
required this.body,
this.isExpanded = false,
this.canTapOnHeader = false,
this.backgroundColor,
}) : assert(headerBuilder != null),
assert(body != null),
assert(isExpanded != null),
assert(canTapOnHeader != null);
/// The widget builder that builds the expansion panels' header.
final ExpansionPanelHeaderBuilder headerBuilder;
/// The body of the expansion panel that's displayed below the header.
///
/// This widget is visible only when the panel is expanded.
final Widget body;
/// Whether the panel is expanded.
///
/// Defaults to false.
final bool isExpanded;
/// Whether tapping on the panel's header will expand/collapse it.
///
/// Defaults to false.
final bool canTapOnHeader;
/// Defines the background color of the panel.
///
/// Defaults to [ThemeData.cardColor].
final Color? backgroundColor;
}
/// An expansion panel that allows for radio-like functionality.
/// This means that at any given time, at most, one [ExpansionPanelRadio]
/// can remain expanded.
///
/// A unique identifier [value] must be assigned to each panel.
/// This identifier allows the [ColoredExpansionPanelList] to determine
/// which [ExpansionPanelRadio] instance should be expanded.
///
/// See [ExpansionPanelList.radio] for a sample implementation.
class ExpansionPanelRadio extends ExpansionPanel {
/// An expansion panel that allows for radio functionality.
///
/// A unique [value] must be passed into the constructor. The
/// [headerBuilder], [body], [value] must not be null.
ExpansionPanelRadio({
required this.value,
required ExpansionPanelHeaderBuilder headerBuilder,
required Widget body,
bool canTapOnHeader = false,
Color? backgroundColor,
}) : assert(value != null),
super(
body: body,
headerBuilder: headerBuilder,
canTapOnHeader: canTapOnHeader,
backgroundColor: backgroundColor,
);
/// The value that uniquely identifies a radio panel so that the currently
/// selected radio panel can be identified.
final Object value;
}
/// A material expansion panel list that lays out its children and animates
/// expansions.
///
/// Note that [expansionCallback] behaves differently for [ColoredExpansionPanelList]
/// and [ExpansionPanelList.radio].
///
/// {@tool dartpad --template=stateful_widget_scaffold}
///
/// Here is a simple example of how to implement ExpansionPanelList.
///
/// ```dart preamble
/// // stores ExpansionPanel state information
/// class Item {
/// Item({
/// required this.expandedValue,
/// required this.headerValue,
/// this.isExpanded = false,
/// });
///
/// String expandedValue;
/// String headerValue;
/// bool isExpanded;
/// }
///
/// List<Item> generateItems(int numberOfItems) {
/// return List<Item>.generate(numberOfItems, (int index) {
/// return Item(
/// headerValue: 'Panel $index',
/// expandedValue: 'This is item number $index',
/// );
/// });
/// }
/// ```
///
/// ```dart
/// final List<Item> _data = generateItems(8);
///
/// @override
/// Widget build(BuildContext context) {
/// return SingleChildScrollView(
/// child: Container(
/// child: _buildPanel(),
/// ),
/// );
/// }
///
/// Widget _buildPanel() {
/// return ExpansionPanelList(
/// expansionCallback: (int index, bool isExpanded) {
/// setState(() {
/// _data[index].isExpanded = !isExpanded;
/// });
/// },
/// children: _data.map<ExpansionPanel>((Item item) {
/// return ExpansionPanel(
/// headerBuilder: (BuildContext context, bool isExpanded) {
/// return ListTile(
/// title: Text(item.headerValue),
/// );
/// },
/// body: ListTile(
/// title: Text(item.expandedValue),
/// subtitle: const Text('To delete this panel, tap the trash can icon'),
/// trailing: const Icon(Icons.delete),
/// onTap: () {
/// setState(() {
/// _data.removeWhere((Item currentItem) => item == currentItem);
/// });
/// }
/// ),
/// isExpanded: item.isExpanded,
/// );
/// }).toList(),
/// );
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [ExpansionPanel]
/// * [ExpansionPanelList.radio]
/// * <https://material.io/design/components/lists.html#types>
class ColoredExpansionPanelList extends StatefulWidget {
/// Creates an expansion panel list widget. The [expansionCallback] is
/// triggered when an expansion panel expand/collapse button is pushed.
///
/// The [children] and [animationDuration] arguments must not be null.
const ColoredExpansionPanelList({
Key? key,
this.children = const <ExpansionPanel>[],
this.expansionCallback,
this.animationDuration = kThemeAnimationDuration,
this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding,
this.dividerColor,
this.color,
this.disabledColor,
this.expandedColor,
this.elevation = 2,
}) : assert(children != null),
assert(animationDuration != null),
_allowOnlyOnePanelOpen = false,
initialOpenPanelValue = null,
super(key: key);
/// START OF CUSTOM CODE TO ADD COLOR TO EXPANDEDICON
///
///
///
/// The color of the icon.
///
/// Defaults to [Colors.black54] when the theme's
/// [ThemeData.brightness] is [Brightness.light] and to
/// [Colors.white60] when it is [Brightness.dark]. This adheres to the
/// Material Design specifications for [icons](https://material.io/design/iconography/system-icons.html#color)
/// and for [dark theme](https://material.io/design/color/dark-theme.html#ui-application)
final Color? color;
/// The color of the icon when it is disabled,
/// i.e. if [onPressed] is null.
///
/// Defaults to [Colors.black38] when the theme's
/// [ThemeData.brightness] is [Brightness.light] and to
/// [Colors.white38] when it is [Brightness.dark]. This adheres to the
/// Material Design specifications for [icons](https://material.io/design/iconography/system-icons.html#color)
/// and for [dark theme](https://material.io/design/color/dark-theme.html#ui-application)
final Color? disabledColor;
/// The color of the icon when the icon is expanded.
///
/// Defaults to [Colors.black54] when the theme's
/// [ThemeData.brightness] is [Brightness.light] and to
/// [Colors.white] when it is [Brightness.dark]. This adheres to the
/// Material Design specifications for [icons](https://material.io/design/iconography/system-icons.html#color)
/// and for [dark theme](https://material.io/design/color/dark-theme.html#ui-application)
final Color? expandedColor;
///END OF CUSTOM CODE TO ADD COLOR TO EXPANDEDICON
///
///
///
///
///
/// Creates a radio expansion panel list widget.
///
/// This widget allows for at most one panel in the list to be open.
/// The expansion panel callback is triggered when an expansion panel
/// expand/collapse button is pushed. The [children] and [animationDuration]
/// arguments must not be null. The [children] objects must be instances
/// of [ExpansionPanelRadio].
///
/// {@tool dartpad --template=stateful_widget_scaffold}
///
/// Here is a simple example of how to implement ExpansionPanelList.radio.
///
/// ```dart preamble
/// // stores ExpansionPanel state information
/// class Item {
/// Item({
/// required this.id,
/// required this.expandedValue,
/// required this.headerValue,
/// });
///
/// int id;
/// String expandedValue;
/// String headerValue;
/// }
///
/// List<Item> generateItems(int numberOfItems) {
/// return List<Item>.generate(numberOfItems, (int index) {
/// return Item(
/// id: index,
/// headerValue: 'Panel $index',
/// expandedValue: 'This is item number $index',
/// );
/// });
/// }
/// ```
///
/// ```dart
/// final List<Item> _data = generateItems(8);
///
/// @override
/// Widget build(BuildContext context) {
/// return SingleChildScrollView(
/// child: Container(
/// child: _buildPanel(),
/// ),
/// );
/// }
///
/// Widget _buildPanel() {
/// return ExpansionPanelList.radio(
/// initialOpenPanelValue: 2,
/// children: _data.map<ExpansionPanelRadio>((Item item) {
/// return ExpansionPanelRadio(
/// value: item.id,
/// headerBuilder: (BuildContext context, bool isExpanded) {
/// return ListTile(
/// title: Text(item.headerValue),
/// );
/// },
/// body: ListTile(
/// title: Text(item.expandedValue),
/// subtitle: const Text('To delete this panel, tap the trash can icon'),
/// trailing: const Icon(Icons.delete),
/// onTap: () {
/// setState(() {
/// _data.removeWhere((Item currentItem) => item == currentItem);
/// });
/// }
/// )
/// );
/// }).toList(),
/// );
/// }
/// ```
/// {@end-tool}
const ColoredExpansionPanelList.radio({
Key? key,
this.children = const <ExpansionPanelRadio>[],
this.expansionCallback,
this.animationDuration = kThemeAnimationDuration,
this.initialOpenPanelValue,
this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding,
this.dividerColor,
this.color,
this.disabledColor,
this.expandedColor,
this.elevation = 2,
}) : assert(children != null),
assert(animationDuration != null),
_allowOnlyOnePanelOpen = true,
super(key: key);
/// The children of the expansion panel list. They are laid out in a similar
/// fashion to [ListBody].
final List<ExpansionPanel> children;
/// The callback that gets called whenever one of the expand/collapse buttons
/// is pressed. The arguments passed to the callback are the index of the
/// pressed panel and whether the panel is currently expanded or not.
///
/// If ExpansionPanelList.radio is used, the callback may be called a
/// second time if a different panel was previously open. The arguments
/// passed to the second callback are the index of the panel that will close
/// and false, marking that it will be closed.
///
/// For ExpansionPanelList, the callback needs to setState when it's notified
/// about the closing/opening panel. On the other hand, the callback for
/// ExpansionPanelList.radio is simply meant to inform the parent widget of
/// changes, as the radio panels' open/close states are managed internally.
///
/// This callback is useful in order to keep track of the expanded/collapsed
/// panels in a parent widget that may need to react to these changes.
final ExpansionPanelCallback? expansionCallback;
/// The duration of the expansion animation.
final Duration animationDuration;
// Whether multiple panels can be open simultaneously
final bool _allowOnlyOnePanelOpen;
/// The value of the panel that initially begins open. (This value is
/// only used when initializing with the [ExpansionPanelList.radio]
/// constructor.)
final Object? initialOpenPanelValue;
/// The padding that surrounds the panel header when expanded.
///
/// By default, 16px of space is added to the header vertically (above and below)
/// during expansion.
final EdgeInsets expandedHeaderPadding;
/// Defines color for the divider when [ExpansionPanel.isExpanded] is false.
///
/// If `dividerColor` is null, then [DividerThemeData.color] is used. If that
/// is null, then [ThemeData.dividerColor] is used.
final Color? dividerColor;
/// Defines elevation for the [ExpansionPanel] while it's expanded.
///
/// This uses [kElevationToShadow] to simulate shadows, it does not use
/// [Material]'s arbitrary elevation feature.
///
/// The following values can be used to define the elevation: 0, 1, 2, 3, 4, 6,
/// 8, 9, 12, 16, 24.
///
/// By default, the value of elevation is 2.
final int elevation;
@override
State<StatefulWidget> createState() => _ColoredExpansionPanelListState();
}
class _ColoredExpansionPanelListState extends State<ColoredExpansionPanelList> {
ExpansionPanelRadio? _currentOpenPanel;
@override
void initState() {
super.initState();
if (widget._allowOnlyOnePanelOpen) {
assert(_allIdentifiersUnique(), 'All ExpansionPanelRadio identifier values must be unique.');
if (widget.initialOpenPanelValue != null) {
_currentOpenPanel =
searchPanelByValue(widget.children.cast<ExpansionPanelRadio>(), widget.initialOpenPanelValue);
}
}
}
@override
void didUpdateWidget(ColoredExpansionPanelList oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget._allowOnlyOnePanelOpen) {
assert(_allIdentifiersUnique(), 'All ExpansionPanelRadio identifier values must be unique.');
// If the previous widget was non-radio ExpansionPanelList, initialize the
// open panel to widget.initialOpenPanelValue
if (!oldWidget._allowOnlyOnePanelOpen) {
_currentOpenPanel =
searchPanelByValue(widget.children.cast<ExpansionPanelRadio>(), widget.initialOpenPanelValue);
}
} else {
_currentOpenPanel = null;
}
}
bool _allIdentifiersUnique() {
final Map<Object, bool> identifierMap = <Object, bool>{};
for (final ExpansionPanelRadio child in widget.children.cast<ExpansionPanelRadio>()) {
identifierMap[child.value] = true;
}
return identifierMap.length == widget.children.length;
}
bool _isChildExpanded(int index) {
if (widget._allowOnlyOnePanelOpen) {
final ExpansionPanelRadio radioWidget = widget.children[index] as ExpansionPanelRadio;
return _currentOpenPanel?.value == radioWidget.value;
}
return widget.children[index].isExpanded;
}
void _handlePressed(bool isExpanded, int index) {
widget.expansionCallback?.call(index, isExpanded);
if (widget._allowOnlyOnePanelOpen) {
final ExpansionPanelRadio pressedChild = widget.children[index] as ExpansionPanelRadio;
// If another ExpansionPanelRadio was already open, apply its
// expansionCallback (if any) to false, because it's closing.
for (int childIndex = 0; childIndex < widget.children.length; childIndex += 1) {
final ExpansionPanelRadio child = widget.children[childIndex] as ExpansionPanelRadio;
if (widget.expansionCallback != null &&
childIndex != index &&
child.value == _currentOpenPanel?.value)
widget.expansionCallback!(childIndex, false);
}
setState(() {
_currentOpenPanel = isExpanded ? null : pressedChild;
});
}
}
ExpansionPanelRadio? searchPanelByValue(List<ExpansionPanelRadio> panels, Object? value) {
for (final ExpansionPanelRadio panel in panels) {
if (panel.value == value)
return panel;
}
return null;
}
@override
Widget build(BuildContext context) {
assert(kElevationToShadow.containsKey(widget.elevation),
'Invalid value for elevation. See the kElevationToShadow constant for'
' possible elevation values.',
);
final List<MergeableMaterialItem> items = <MergeableMaterialItem>[];
for (int index = 0; index < widget.children.length; index += 1) {
if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1))
items.add(MaterialGap(key: _SaltedKey<BuildContext, int>(context, index * 2 - 1)));
final ExpansionPanel child = widget.children[index];
final Widget headerWidget = child.headerBuilder(
context,
_isChildExpanded(index),
);
Widget expandIconContainer = Container(
margin: const EdgeInsetsDirectional.only(end: 8.0),
child: ExpandIcon(
color: widget.color,
disabledColor: widget.disabledColor,
expandedColor: widget.expandedColor,
isExpanded: _isChildExpanded(index),
padding: const EdgeInsets.all(16.0),
onPressed: !child.canTapOnHeader
? (bool isExpanded) => _handlePressed(isExpanded, index)
: null,
),
);
if (!child.canTapOnHeader) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
expandIconContainer = Semantics(
label: _isChildExpanded(index)? localizations.expandedIconTapHint : localizations.collapsedIconTapHint,
container: true,
child: expandIconContainer,
);
}
Widget header = Row(
children: <Widget>[
Expanded(
child: AnimatedContainer(
duration: widget.animationDuration,
curve: Curves.fastOutSlowIn,
margin: _isChildExpanded(index) ? widget.expandedHeaderPadding : EdgeInsets.zero,
child: ConstrainedBox(
constraints: const BoxConstraints(minHeight: _kPanelHeaderCollapsedHeight),
child: headerWidget,
),
),
),
expandIconContainer,
],
);
if (child.canTapOnHeader) {
header = MergeSemantics(
child: InkWell(
onTap: () => _handlePressed(_isChildExpanded(index), index),
child: header,
),
);
}
items.add(
MaterialSlice(
key: _SaltedKey<BuildContext, int>(context, index * 2),
color: child.backgroundColor,
child: Column(
children: <Widget>[
header,
AnimatedCrossFade(
firstChild: Container(height: 0.0),
secondChild: child.body,
firstCurve: const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve: const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: _isChildExpanded(index) ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: widget.animationDuration,
),
],
),
),
);
if (_isChildExpanded(index) && index != widget.children.length - 1)
items.add(MaterialGap(key: _SaltedKey<BuildContext, int>(context, index * 2 + 1)));
}
return MergeableMaterial(
hasDividers: true,
dividerColor: widget.dividerColor,
elevation: widget.elevation,
children: items,
);
}
}
关于list - 在 ExpansionPanelList.radio 中更改 ListTile 后面的图标颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67855273/
SO亲爱的 friend 们: 2014 年 3 月 18 日。我正在处理一种情况,在使用 ng-repeat 时,数组内的元素(我从 Json 字符串中获取)更改了原始顺序。 需要明确的是,数组中的
有很多问题询问如何在 JavaScript 单击处理程序中更改 div 的类,例如,此处:Change Div style onclick .我理解得很好(只需更改 .className),并且它有效
我从access导入了一个数据库到mysql,但其中一个表的列名“股数”带有空格,但我尝试更改、替换甚至删除列名,但失败了。任何人都可以帮助解决这一问题 String UpdateQuary = "U
我正在做一个随机的学校元素。 目前,我有一个包含两个 CSS 的页面。一种用于正常 View ,一种用于残障人士 View 。 此页面还包括两个按钮,它们将更改使用的样式表。 function c
我需要使用 javascript 更改 HTML 元素中的文本,但我不知道该怎么做。 ¿有什么帮助吗? 我把它定义成这样: Text I want to change. 我正在尝试这样做: docum
我在它自己的文件 nav_bar.shtml 中有一个主导航栏,每个其他页面都包含该导航栏。这个菜单栏是一个 jQuery 菜单栏(ApyCom 是销售这些导航栏的公司的名称)。导航栏上的元素如何确定
我正在摆弄我的代码,并开始想知道这个变化是否来自: if(array[index] == 0) 对此: if(!array[index] != 0) 可能会影响任何代码,或者它只是做同样的事情而我不需
我一直在想办法调整控制台窗口的大小。这是我正在使用的函数的代码: #include #include #define WIDTH 70 #define HEIGHT 35 HANDLE wHnd;
我有很多情况会导致相同的消息框警报。 有没有比做几个 if 语句更简单/更好的解决方案? PRODUCTS BOX1 BOX2 BOX3
我有一个包含这些元素的 XELEMENT B Bob Petier 19310227 1 我想像这样转换前缀。 B Bob Pet
我使用 MySQL 5.6 遇到了这种情况: 此查询有效并返回预期结果: select * from some_table where a = 'b' and metadata->>"$.countr
我想知道是否有人知道可以检测 R 中日期列格式的任何中断的包或函数,即检测日期向量格式更改的位置,例如: 11/2/90 12/2/90 . . . 15/Feb/1990 16/Feb/1990 .
我希望能够在小部件显示后更改 GtkButton 的标签 char *ButtonStance == "Connect"; GtkWidget *EntryButton = gtk_button_ne
我正在使用 Altera DE2 FPGA 开发板并尝试使用 SD 卡端口和音频线路输出。我正在使用 VHDL 和 C 进行编程,但由于缺乏经验/知识,我在 C 部分遇到了困难。 目前,我可以从 SD
注意到这个链接后: http://www.newscientist.com/blogs/nstv/2010/12/best-videos-of-2010-progress-bar-illusion.h
我想知道在某些情况下,即使剧本任务已成功执行并且 ok=2,ansible 也会显示“changed=0”。使用 Rest API 和 uri 模块时会发生这种情况。我试图找到解释但没有成功。谁能告诉
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: add buttons to push notification alert 是否可以在远程通知显示的警报框中指定有
当您的 TabBarController 中有超过 5 个 View Controller 时,系统会自动为您设置一个“更多” View 。是否可以更改此 View 中导航栏的颜色以匹配我正在使用的颜
如何更改.AndroidStudioBeta文件夹的位置,默认情况下,该文件夹位于Windows中的\ .. \ User \ .AndroidStudioBeta,而不会破坏任何内容? /编辑: 找
我目前正在尝试将更具功能性的编程风格应用于涉及低级(基于 LWJGL)GUI 开发的项目。显然,在这种情况下,需要携带很多状态,这在当前版本中是可变的。我的目标是最终拥有一个完全不可变的状态,以避免状
我是一名优秀的程序员,十分优秀!