- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我们创建了一个 Chip object和 TextField
对象如下。如何添加 Chip
到内部TextField
?
new Chip(
label: new Text('Peyton Smith'),
)
new TextField(
)
TextField
添加
Chip
?
最佳答案
您要查找的内容实际上已在评论中提供。
这是一个使用 InputChip
的简单实现:
InputChip(
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade800,
child: Text('AB'),
),
label: Text('Aaron Burr'),
onPressed: () {
print('I am the one thing in life.');
}
)
A material design input chip.
Input chips represent a complex piece of information, such as anentity (person, place, or thing) or conversational text, in a compactform.
Input chips can be made selectable by setting
onSelected
,deletable by settingonDeleted
,and pressable like a button withonPressed
.They have alabel
,and they can have a leading icon (seeavatar
)and a trailing icon(deleteIcon
).Colors and padding can be customized.
InputChip
的简单解读:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: _toContainer(),
),
),
Divider(
color: Colors.blueGrey,
height: 10.0,
),
Align(
alignment: Alignment.centerLeft,
child: _subjectContainer(),
),
Divider(
color: Colors.blueGrey,
height: 10.0,
),
Align(
alignment: Alignment.centerLeft,
child: _messageContainer(),
),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _messageContainer() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Text(
'Message',
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
),
);
}
Widget _toContainer() {
return Wrap(
spacing: 5.0,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8.0, right: 8.0),
child: Container(
child: Text(
'To',
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
),
),
Container(
child: _profileChips("Scott Hill",
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80"),
),
],
);
}
Widget _subjectContainer() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Text(
'Subject',
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
),
);
}
Widget _profileChips(String myName, String myImage) {
return Material(
child: InputChip(
avatar: CircleAvatar(
backgroundColor: Colors.blueGrey,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(myImage),
)),
),
),
label: Text(myName),
labelStyle: TextStyle(
color: Colors.black, fontSize: 14.0, fontWeight: FontWeight.bold),
onPressed: () {},
onDeleted: () {},
),
);
}
}
输出:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// See: https://twitter.com/shakil807/status/1042127387515858949
// https://github.com/pchmn/MaterialChipsInput/tree/master/library/src/main/java/com/pchmn/materialchips
// https://github.com/BelooS/ChipsLayoutManager
void main() => runApp(ChipsDemoApp());
class ChipsDemoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.indigo,
accentColor: Colors.pink,
),
home: DemoScreen(),
);
}
}
class DemoScreen extends StatefulWidget {
@override
_DemoScreenState createState() => _DemoScreenState();
}
class _DemoScreenState extends State<DemoScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Material Chips Input'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: const InputDecoration(hintText: 'normal'),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ChipsInput<AppProfile>(
decoration: InputDecoration(
prefixIcon: Icon(Icons.search), hintText: 'Profile search'),
findSuggestions: _findSuggestions,
onChanged: _onChanged,
chipBuilder: (BuildContext context,
ChipsInputState<AppProfile> state, AppProfile profile) {
return InputChip(
key: ObjectKey(profile),
label: Text(profile.name),
avatar: CircleAvatar(
backgroundImage: NetworkImage(profile.imageUrl),
),
onDeleted: () => state.deleteChip(profile),
onSelected: (_) => _onChipTapped(profile),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
);
},
suggestionBuilder: (BuildContext context,
ChipsInputState<AppProfile> state, AppProfile profile) {
return ListTile(
key: ObjectKey(profile),
leading: CircleAvatar(
backgroundImage: NetworkImage(profile.imageUrl),
),
title: Text(profile.name),
subtitle: Text(profile.email),
onTap: () => state.selectSuggestion(profile),
);
},
),
),
),
],
),
);
}
void _onChipTapped(AppProfile profile) {
print('$profile');
}
void _onChanged(List<AppProfile> data) {
print('onChanged $data');
}
Future<List<AppProfile>> _findSuggestions(String query) async {
if (query.length != 0) {
return mockResults.where((profile) {
return profile.name.contains(query) || profile.email.contains(query);
}).toList(growable: false);
} else {
return const <AppProfile>[];
}
}
}
// -------------------------------------------------
const mockResults = <AppProfile>[
AppProfile('Stock Man', 'stock@man.com',
'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
AppProfile('Paul', 'paul@google.com',
'https://mbtskoudsalg.com/images/person-stock-image-png.png'),
AppProfile('Fred', 'fred@google.com',
'https://media.istockphoto.com/photos/feeling-great-about-my-corporate-choices-picture-id507296326'),
AppProfile('Bera', 'bera@flutter.io',
'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
AppProfile('John', 'john@flutter.io',
'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
AppProfile('Thomas', 'thomas@flutter.io',
'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
AppProfile('Norbert', 'norbert@flutter.io',
'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
AppProfile('Marina', 'marina@flutter.io',
'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
];
class AppProfile {
final String name;
final String email;
final String imageUrl;
const AppProfile(this.name, this.email, this.imageUrl);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AppProfile &&
runtimeType == other.runtimeType &&
name == other.name;
@override
int get hashCode => name.hashCode;
@override
String toString() {
return 'Profile{$name}';
}
}
// -------------------------------------------------
typedef ChipsInputSuggestions<T> = Future<List<T>> Function(String query);
typedef ChipSelected<T> = void Function(T data, bool selected);
typedef ChipsBuilder<T> = Widget Function(
BuildContext context, ChipsInputState<T> state, T data);
class ChipsInput<T> extends StatefulWidget {
const ChipsInput({
Key key,
this.decoration = const InputDecoration(),
@required this.chipBuilder,
@required this.suggestionBuilder,
@required this.findSuggestions,
@required this.onChanged,
this.onChipTapped,
}) : super(key: key);
final InputDecoration decoration;
final ChipsInputSuggestions findSuggestions;
final ValueChanged<List<T>> onChanged;
final ValueChanged<T> onChipTapped;
final ChipsBuilder<T> chipBuilder;
final ChipsBuilder<T> suggestionBuilder;
@override
ChipsInputState<T> createState() => ChipsInputState<T>();
}
class ChipsInputState<T> extends State<ChipsInput<T>>
implements TextInputClient {
static const kObjectReplacementChar = 0xFFFC;
Set<T> _chips = Set<T>();
List<T> _suggestions;
int _searchId = 0;
FocusNode _focusNode;
TextEditingValue _value = TextEditingValue();
TextInputConnection _connection;
String get text => String.fromCharCodes(
_value.text.codeUnits.where((ch) => ch != kObjectReplacementChar),
);
bool get _hasInputConnection => _connection != null && _connection.attached;
void requestKeyboard() {
if (_focusNode.hasFocus) {
_openInputConnection();
} else {
FocusScope.of(context).requestFocus(_focusNode);
}
}
void selectSuggestion(T data) {
setState(() {
_chips.add(data);
_updateTextInputState();
_suggestions = null;
});
widget.onChanged(_chips.toList(growable: false));
}
void deleteChip(T data) {
setState(() {
_chips.remove(data);
_updateTextInputState();
});
widget.onChanged(_chips.toList(growable: false));
}
@override
void initState() {
super.initState();
_focusNode = FocusNode();
_focusNode.addListener(_onFocusChanged);
}
void _onFocusChanged() {
if (_focusNode.hasFocus) {
_openInputConnection();
} else {
_closeInputConnectionIfNeeded();
}
setState(() {
// rebuild so that _TextCursor is hidden.
});
}
@override
void dispose() {
_focusNode?.dispose();
_closeInputConnectionIfNeeded();
super.dispose();
}
void _openInputConnection() {
if (!_hasInputConnection) {
_connection = TextInput.attach(this, TextInputConfiguration());
_connection.setEditingState(_value);
}
_connection.show();
}
void _closeInputConnectionIfNeeded() {
if (_hasInputConnection) {
_connection.close();
_connection = null;
}
}
@override
Widget build(BuildContext context) {
var chipsChildren = _chips
.map<Widget>(
(data) => widget.chipBuilder(context, this, data),
)
.toList();
final theme = Theme.of(context);
chipsChildren.add(
Container(
height: 32.0,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
text,
style: theme.textTheme.subtitle1.copyWith(
height: 1.5,
),
),
_TextCaret(
resumed: _focusNode.hasFocus,
),
],
),
),
);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
//mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: requestKeyboard,
child: InputDecorator(
decoration: widget.decoration,
isFocused: _focusNode.hasFocus,
isEmpty: _value.text.length == 0,
child: Wrap(
children: chipsChildren,
spacing: 4.0,
runSpacing: 4.0,
),
),
),
Expanded(
child: ListView.builder(
itemCount: _suggestions?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
return widget.suggestionBuilder(
context, this, _suggestions[index]);
},
),
),
],
);
}
@override
void updateEditingValue(TextEditingValue value) {
final oldCount = _countReplacements(_value);
final newCount = _countReplacements(value);
setState(() {
if (newCount < oldCount) {
_chips = Set.from(_chips.take(newCount));
}
_value = value;
});
_onSearchChanged(text);
}
int _countReplacements(TextEditingValue value) {
return value.text.codeUnits
.where((ch) => ch == kObjectReplacementChar)
.length;
}
@override
void performAction(TextInputAction action) {
_focusNode.unfocus();
}
void _updateTextInputState() {
final text =
String.fromCharCodes(_chips.map((_) => kObjectReplacementChar));
_value = TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length),
composing: TextRange(start: 0, end: text.length),
);
_connection.setEditingState(_value);
}
void _onSearchChanged(String value) async {
final localId = ++_searchId;
final results = await widget.findSuggestions(value);
if (_searchId == localId && mounted) {
setState(() => _suggestions = results
.where((profile) => !_chips.contains(profile))
.toList(growable: false));
}
}
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _TextCaret extends StatefulWidget {
const _TextCaret({
Key key,
this.duration = const Duration(milliseconds: 500),
this.resumed = false,
}) : super(key: key);
final Duration duration;
final bool resumed;
@override
_TextCursorState createState() => _TextCursorState();
}
class _TextCursorState extends State<_TextCaret>
with SingleTickerProviderStateMixin {
bool _displayed = false;
Timer _timer;
@override
void initState() {
super.initState();
_timer = Timer.periodic(widget.duration, _onTimer);
}
void _onTimer(Timer timer) {
setState(() => _displayed = !_displayed);
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return FractionallySizedBox(
heightFactor: 0.7,
child: Opacity(
opacity: _displayed && widget.resumed ? 1.0 : 0.0,
child: Container(
width: 2.0,
color: theme.primaryColor,
),
),
);
}
}
工作输出:
Flutter library for building input fields with InputChips as inputoptions.
关于dart - 向 Material 文本字段添加芯片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51147131/
我有一个相当冗长的命令行程序,它需要用户输入参数,然后使用这些参数进行处理。我想做的是将程序拆分为交互式和非交互式。我试图这样做,并打算让非交互式程序“调用”交互式程序并使用结果(参数),基于这些参数
谁能解释为什么我们在构造函数的参数中使用大括号。 class Cars { String carName; bool isAuto; // create the constructor
我想知道是否有Dart函数,例如PHP的 strrev()。如果没有,您能否请向我展示任何源代码如何自行实现? 谢谢。 最佳答案 我还没有在API中找到一个新的Dart用户(截至今天下午)。但是,以任
我有一个组件,我想根据一个 bool 值绑定(bind)一个不同的 css 类。我的组件代码中有以下内容: bindCssClass(div, "open", this, "task.isOpen")
我一直在研究如何在dart中播放.wav文件,并且已经能够通过dart:html库中定义的AudioElement成功完成此操作。但是,我对使用dart:web_audio库感兴趣,并且遇到了所有这些
Dart 是否旨在实现许多与 Haxe 相同的功能,以便能够针对其他语言和运行时?它是语言和工具的既定目标还是已知目标? 最佳答案 不。Dart 专门针对 web 应用程序开发(更具体地说,客户端 w
我正在尝试让 dart 正常工作。作为编辑器,我想使用 emacs dart-mode。我有两个关于在没有 dart 编辑器的情况下使用 dart 的问题: 1) 我是否需要手动调用 dart2js,
我正在使用列表来创建墨水瓶按钮。我想将列表放在一个单独的 dart 文件中,并将该文件导入到我使用列表的文件中。我不知道如何导入列表。 https://pastebin.com/mf0kvsGu 我制
我正在编写一个 flutter 应用程序,它通过蓝牙 (FlutterBlue) 向设备发送命令。该设备控制一些 LED。通信总体上运行良好,但是:在用户界面上,我有一个控制光强度的 slider 。
我正在使用来自 Get started: command-line and server apps | Dart 的说明.运行 dart --version 时,我得到: Dart VM versio
var c 返回 3 但 10/7=1.4285,其余为 0.4285,operator % 有错误? void main() { var a = 10; var b = 7; var c
如文档中所述: The const keyword isn’t just for declaring constant variables. You can also use it to create
在 Dart 中,我如何最好地编写相当于(不可变/值/非对象) 的代码输出或引用参数 ? 例如在 C#-ish 中,我可能会编码: function void example() { int re
Dart 支持的多重继承机制有哪些? 最佳答案 不,Dart 不支持多重实现继承。 Dart 具有接口(interface),并且与大多数其他类似语言一样,它具有多个接口(interface)继承。
我正在寻找有关如何制作可以采用位置子参数的 web 组件的资源。就像是: {{value}} // this could be any uneditable element {{value}
使用polymer.dart 的Dart 应用程序的pubspec.yaml 文件如下所示(来自Polymer.dart Code Lab): name: polymer_and_dart descr
今天我决定开始学习 Dart 语言,我从 Tour 开始,那里有一个例子: // These work in a const string. const aConstNum = 0; const aC
我正在查找字符串类和其他一些资源,试图了解如何格式化字符串。首先,我试图将数字填充到字符串中,但不是精度。 例子: int a = 0, b = 5, c = 15, d = 46; String
我知道的大部分是Javascript。我相信“列表”是 Dart 最接近数组的东西,但它们在技术上是一样的吗?将它们视为数组是错误的吗?同样, map 会被视为对象吗?我意识到可能存在差异,但进行这种
现在,白色背景刺痛了我的眼睛,因为这是一个looong的黑夜。是否可以从 Dart 编辑器 (v 0.1) 更改主题(更改为更暗的主题)?选择背景颜色和语法高亮怎么样? 最佳答案 是的,这是可能的,我
我是一名优秀的程序员,十分优秀!