MDC – Text field
前言
Angular Material 只有 Form field, 但 Material Design 有份 Text field 和 Form field, Form field 是给 checkbox 和 radio 用的, Text field 则是给 input, select 用的.
它就是一个框, 里头包含了 label 和 accessor (e.g. input, select, textarea 等)
封装了 floating label, error color, helper text 等等功能.
Input Text
先来一个最简单的 input text 的 field
Filled and Outlined
Material 3 中, 有 2 种 text field 设计, 一个是 filled 一个是 outlined, 下面以 outlined 作为例子.
HTML
<label class="mdc-text-field mdc-text-field--outlined">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span class="mdc-floating-label">Your Name</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<input type="text" name="firstName" class="mdc-text-field__input"/>
</label>
它包含了 3 给组件.
1. text-field
2. notched-outline (notch 是 缺口, 槽口, 凹槽的意思)
3. floating-label
Yarn add
有 3 个组件所以需要安装 3 给 module. MDC 把组件分的非常细.
yarn add @material/textfield
yarn add @material/notched-outline
yarn add @material/floating-label
Scss
@use '@material/floating-label/mdc-floating-label';
@use '@material/notched-outline/mdc-notched-outline';
@use '@material/textfield';
@include textfield.core-styles;
or CSS Link
<link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
也是三剑客一起上
TypeScript
import { MDCTextField } from '@material/textfield'; document.querySelectorAll('.mdc-text-field').forEach(element => {
new MDCTextField(element);
}); // 如果想通过 element 获取 instance, 也可以模仿 mdcAutoInit 的方式. 把 instance 放到 element 属性中
// document
// .querySelectorAll<Element & { MDCTextField: MDCTextField }>('.mdc-text-field')
// .forEach(element => {
// element.MDCTextField = new MDCTextField(element);
// });
记得, 绝大部分 MDC 的组件用法都是 HTML, Scss, TypeScript 三边都需要的 (除非没有交互才不需要 TypeScript)
效果
Autofill Floating Label Problem
Browser 会自动填写 password, 而 MDC 的 label 不会自动 floating...
解决方案应该是需要用到 :autofill CSS selector.
但我翻看了源码, 没有找到 autofill keyword, 唯一有关联的是在 changelog 的 issue1, issue2.
anyway, 目前我的 workaround 思路是, 通过 :-webkit-autofill 找到 input 再找到 MDCTextField
然后学它 focus 时 floating label 效果.
关键就是那 3 行代码.
const foundation: any = field.MDCTextField.getDefaultFoundation();
foundation.notchOutline(true);
foundation.adapter.floatLabel(true);
foundation.styleFloating(true);
foundation 没有公开所有 floating label 体验的接口. adapter 是 protected, styleFloating 是 private. 所以只能 any 来使用.
Disabled
如果 form 有 conditional field, 那么 disabled 经常会被用到.
文章里说需要添加 2 个地方
但其实只要在 input 添加 disabled 就可以了, text-field 的 class 会在 init 的时候自动被添加.
但是, 如果之后你通过 JS 修改 input 的 disabled. 它是不会同步的. 你会发现 MDCTextFiled.disabled 同步了, 但是却没有效果 (text-field 的 mdc-text-field--disabled 没有被移除)
原因是它的实现方式.
MDCTextFiled read disabled 是直接从 input 读的, 所以感觉是同步了.
但 set 的时候它还有一个过程去 set disabled style. 所以直接操作 input.disabled 是不行的. 必须操作 MDCTextField Instance 这个过程才会跑.
const textFiled = new MDCTextField(element);
textFiled.disabled = true;
textFiled.disabled = false;
如果你和我一样封装了 MDC (wrap 了一层), 要拿到 instance 可以参考 How to Get MDC Instance from Element
另一个方法是通过 MutationObserver 监听, 当 input attribute disabled 后去 set MDC 的 style. 这样的好处是可以封装起来. 但 MDC 的接口对扩展不是很友好
foundation 的 styleDisabled 是 private 方法, 而 setDisabled 则会去 set attribute. 虽然更新的值是一样的, 但 mutation 一样会触发, 这会导致死循环.
change event trigger > setDisabled() > update disabled > change event trigger again > setDisabled() > 死循环了.
所以需要另外做一个记入, 只有在真的发生值改变时才触发, 避开死循环.
代码大概长这样:
const textFieldInstance = new MDCTextField(element);
const input = element.querySelector<HTMLInputElement>('input')!; let prevDisabled = input.disabled;
const mo = new MutationObserver(() => {
if (prevDisabled !== input.disabled) {
textFieldInstance.disabled = input.disabled;
prevDisabled = input.disabled;
}
});
mo.observe(input, {
attributeFilter: ['disabled'],
}); setTimeout(() => {
input.disabled = false;
setTimeout(() => {
input.disabled = true;
}, 1000);
}, 3000);
Set Input Value
有时候我们会需要做 form value cache. 用户填写一半, refresh 后 value 依然存在.
如果我们直接操作 input.value = 'cache value'.
你会发现 label 不会 floating 起来.
解决方法和 disabled 差不多概念, 使用 MDCTextField instance.value = 'cache value' 就可以了.
但是如果你想 hack 它也是可以的.
input.value = 'hello world';
input.dispatchEvent(new Event('input'));
自己 dispatchEvent 就可以了. 因为 MDC 内部监听 input event 的.
另外还有一个小问题, dispatch input 也会导致 input 有 focus 的 style. 所以最后还要加多一个 blur
input.dispatchEvent(new Event('blur'));
如果是 select 的话,它需要的不是 input 而是 change event 哦
select.dispatchEvent(new Event('change'));
select.dispatchEvent(new Event('blur'));
Error Design
Material Design 的体验是 inline error, 就是说尽可能快的让用户知道它 invalid 了.
比如上面这个 input 是 required 的, 当用户 blur 以后马上就会变红色.
required
MDC 对游览器原生的 validation 都有做处理. 比如 required
<input type="text" class="mdc-text-field__input" required />
当 input 有 required 属性时, label 会自动加上星号 *, 当用户没有填写内容 unblur 后框框会变红色.
以下是相关源码, 来自 MDCTextFieldFoundation class
从第三段可以看出, MDC 是通过游览器 native validation 实现验证的. MDC 本身并没有任何验证逻辑.
Helper Text
Helper text 就是框框下面的一行提示. 可以用来提示用户如何填写资料 (比如格式, 例子等等).
它是 text field 下的另一个 module 负责
HTML
<label class="mdc-text-field mdc-text-field--outlined">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span class="mdc-floating-label">Your Name</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<input type="text" class="mdc-text-field__input" />
</label>
<div class="mdc-text-field-helper-line">
<div class="mdc-text-field-helper-text">helper text</div>
</div>
helper-line element 需要放到 text field 的 next sibling, 位置很重要哦
text field 是通过 nextElementSibling 去找到它对应的 helper text 的
提醒: helper text 是 sibling, 很容易就会破坏 Flex / Grid 布局, 最好是把它们 wrap 起来, wrap 起来后 label 是 inline, input 有 default width (also depend on on font-size), 所以要把 label set 成 block element 或者 width 100% 哦
Scss
@use '@material/textfield/helper-text';
@include helper-text.helper-text-core-styles;
TypeScript
import { MDCTextFieldHelperText } from '@material/textfield/helper-text'; document.querySelectorAll('.mdc-text-field-helper-text').forEach(element => {
new MDCTextFieldHelperText(element);
});
persistent
细看你会发现它默认的体验是: 当 focused, helper text 会出现, 当 blur 以后 helper text 会消失.
如果希望它一直出现, 可以加上 class "mdc-text-field-helper-text--persistent"
<div class="mdc-text-field-helper-text mdc-text-field-helper-text--persistent">helper text</div>
或用 TypeScript set
document.querySelectorAll('.mdc-text-field-helper-text').forEach(element => {
const helperText = new MDCTextFieldHelperText(element);
helperText.foundationForTextField.setPersistent(true);
});
效果
as error message
在 Material Design 手册中有说到, error message 和 helper text 是 share 同一个位置的.
也就是说当 error message 出现的时候 helper text 就必须被替换掉. MDC 没有直接提供这样的体验支持, 但是可以用 TS 动态 setup.
先看看没有 helper text 但是有 error message 的情况怎么写
<div class="mdc-text-field-helper-text mdc-text-field-helper-text--validation-msg">
Name is required
</div>
加上 class "mdc-text-field-helper-text--validation-msg"
或者 TypeScript set
helperText.foundationForTextField.setValidation(true);
效果
如果想同时处理 error message 和 helper text 需要直接操作 helperText 对象
document.querySelectorAll('.mdc-text-field-helper-text').forEach(element => {
const helperText = new MDCTextFieldHelperText(element);
helperText.foundationForTextField.setContent('helper text');
helperText.foundationForTextField.setPersistent(true);
// 监听 form-field attr 出现 invalid 的 class 就切换到 error message
helperText.foundationForTextField.setContent('Name is required');
helperText.foundationForTextField.setValidation(true);
});
关键就是监听到 invalid 时切换成 error message. 流程大概是
1. 找到对应的 form field (它们是 sibling 关系, 所以找的到)
2. 用 mutation 监听 class 的变化, invalid 时 text field 会有 class "mdc-text-field--invalid" (依赖这个比较稳定)
3. 操作 helperText 对象, 却换成 error message 或者切换回来.
如果有 2 个验证, 比如 required + email 想针对不同 validation 时输出正确的 error message 他也没有 build-in 的. 需要用 TS 去换 error message.
另外我也发现了, Angular Material 虽然用了 MDC 的 text field 但它没有用 helper text. 反而是自己实现了一套.
character counter & max length
helper text 还有一个常用的场景就是 max length 提示
它是搭配 input maxlength 一起使用的
helper text 不需要写任何内容, MDC 会自动填上.
另外, character counter 和 helper text 是不冲突的哦, 因为一个在左边一个在右边
<div class="mdc-text-field-helper-line">
<div class="mdc-text-field-helper-text">helper text</div>
<div class="mdc-text-field-character-counter"></div>
</div>
Leading & Trailing Icon
效果
通常是配搭 Material Icon 使用
Icon HTML
<i class="material-icons mdc-text-field__icon mdc-text-field__icon--leading" tabindex="0" role="button">event</i>
tabindex="0" role="button" 表示可点击, 如果不允许点击就把这 2 个 attributes 移除.
Scss
@use "@material/textfield/icon"; @include icon.icon-core-styles;
or CSS Link
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
TypeScript
import {MDCTextFieldIcon} from '@material/textfield/icon'; const icon = new MDCTextFieldIcon(document.querySelector('.mdc-text-field-icon'));
Text Field Leading icon
完整的 text field + leading icon
<label class="mdc-text-field mdc-text-field--outlined mdc-text-field--with-leading-icon">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span id="price" class="mdc-floating-label">Price</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<i class="material-icons mdc-text-field__icon mdc-text-field__icon--leading">attach_money</i>
<input class="mdc-text-field__input" type="text" aria-labelledby="price">
</label>
注: label 多了一个 class mdc-text-field--with-leading-icon
Scss 和 TypeScript 就把 TextField 和 Icon 两组都放就可以了.
Text Field Trailing icon (with SVG)
<label class="mdc-text-field mdc-text-field--outlined mdc-text-field--with-trailing-icon">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span id="password" class="mdc-floating-label">Password</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<input class="mdc-text-field__input" type="password" aria-labelledby="password">
<i style="font-size: 24px; color: rgba(0, 0, 0, 0.54)" class="mdc-text-field__icon mdc-text-field__icon--trailing" tabindex="0" role="button">
<svg style="width: 1em; height: 1em;" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960">
<path d="M480.118 726Q551 726 600.5 676.382q49.5-49.617 49.5-120.5Q650 485 600.382 435.5q-49.617-49.5-120.5-49.5Q409 386 359.5 435.618q-49.5 49.617-49.5 120.5Q310 627 359.618 676.5q49.617 49.5 120.5 49.5Zm-.353-58Q433 668 400.5 635.265q-32.5-32.736-32.5-79.5Q368 509 400.735 476.5q32.736-32.5 79.5-32.5Q527 444 559.5 476.735q32.5 32.736 32.5 79.5Q592 603 559.265 635.5q-32.736 32.5-79.5 32.5ZM480 856q-146 0-264-83T40 556q58-134 176-217t264-83q146 0 264 83t176 217q-58 134-176 217t-264 83Zm0-300Zm-.169 240Q601 796 702.5 730.5 804 665 857 556q-53-109-154.331-174.5-101.332-65.5-222.5-65.5Q359 316 257.5 381.5 156 447 102 556q54 109 155.331 174.5 101.332 65.5 222.5 65.5Z" />
</svg>
</i>
</label>
注: label 多了一个 class mdc-text-field--with-leading-icon
不想引入 material icon, 也可以用自己的 svg. 直接放进 i tag 里, 配上一些 size, color styling 就可以了.
Listening Icon Event
const textFieldIcon = new MDCTextFieldIcon(icon);
textFieldIcon.listen('click', () => console.log('Hello World'));
Textarea
text field 里面也可以放 textarea
<label class="mdc-text-field mdc-text-field--outlined mdc-text-field--textarea">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span class="mdc-floating-label">Your Name</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<span class="mdc-text-field__resizer">
<textarea class="mdc-text-field__input" rows="4" cols="40"></textarea>
</span>
</label>
和 input 的结构一样, 只是 text field 需要添加 class "mdc-text-field--textarea" 和里面使用一个 span wrap 着 textarea
这个 span wrapper 是为了让它支持 resize, 如果不需要 resize 可以省略掉这个 span
效果
有一个点需要注意, 它的 resize 是 apply 在 span 上, 而不是 textarea 哦
而且是双边 resize: both, 没有接口可以设置单边 resize, 只能通过 override 它的 style="resize: vertical"
Input Date
MDC 没有 datepicker, MWC 也没有 datepicker, 因为 Material Design 团队一直画不出他们满意的 datepicker 所以干脆就不画了.
一直等到 Material Design 3 才终于画出来了, 但是从稿到开发成型, 以 Material Design 团队的实力, 最少也需要 1 – 2 年的时间. 所以短期是肯定用不了的.
目前最好的方案是用原生的 input date 替代.
但是它也有许多问题哦. 我们来看看吧.
label missing
直接把 type 改成 date 就可以了
<input type="date" class="mdc-text-field__input" />
效果
第一个是正常的表现, 第二个的 label 不见了, 之所以会这样是因为
width = 0px 了, 相关代码如下
有点复杂, 我觉得大概率就是一个 bug 而已 (因为 Firefox 没有这个问题), 所以不用去理会它.
它应该是太早尝试获取 width 值了, 可能游览器还没有 render 好, 做一个 delay 是可以解决了
document.querySelectorAll('.mdc-text-field').forEach(element => {
const textField = new MDCTextField(element);
requestAnimationFrame(() => {
textField.layout();
});
});
icon mission
上面是原生 input date 的样子, Chrome 是有一个 icon 的. 因为它和 Firefox 的体验不同.
Chrome 只有点击 icon 才能召唤出 picker (在 laptop), Firefox 点击任何一个地方都会召唤出 picker.
也就是说使用 Chrome, 没有 icon = 没有 picker.
那为什么 MDC 没有 icon 呢?
因为这个 icon 会破坏 Material Design, 而且不容易用 CSS 去调整它, 加上它不属于 W3C 规范, 所以 MDC 果断把它给关了. stackoverflow – Hide the calendar icon in Google Chrome
所以, laptop 没有 picker 用, 体验就掉了. 怎么办呢?
stackoverflow – Method to show native datepicker in Chrome
可以通过原生 API, input.showPicker() 召唤出 picker. 但需要很新的 browser 才支持 Can I use – showPicker
Chrome 99 (2022 年 3 月发布的)
trailing icons
参考: Text field icon
有了这个 API, 那么解决思路就是搞一个 calendar trailing icons, 点击以后调用 show.picker()
HTML
<input type="date" class="mdc-text-field__input" />
<i
class="material-icons mdc-text-field__icon mdc-text-field__icon--leading"
tabindex="0"
role="button"
>event</i
>
放到 input 的后面, 注意: tabindex="0" 一定要放哦, 不然是无法点击的.
Scss
@use "@material/textfield/icon"; @include icon.icon-core-styles;
or icon link
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
TypeScript
const textFieldIcon = new MDCTextFieldIcon(document.querySelector('.mdc-text-field__icon')!);
textFieldIcon.listen('click', () => {
(
textFieldIcon.root.previousElementSibling! as unknown as { showPicker: () => void }
).showPicker();
});
效果
当发现游览器不支持
if ('showPicker' in HTMLInputElement.prototype) {
// showPicker() is supported.
}
可以直接把 icon hide 起来或者 pointer-event: none. 不然点击率没有反应很尴尬.
Label Always Floating
input date 的 label 总是 floating 的. 这个在手机体验会比较差. 因为手机不会显示 dd/mm/yyyy. 它就是空白, 但 label 却是 floating 的.
其原因是 MDC Foundation 就是这样实现的...如果不希望这样那就要大费周章的去 override Component 和 Founddation 了... 想想都累...
Select
安装 module
yarn add @material/list
yarn add @material/menu-surface
yarn add @material/menu
yarn add @material/select
HTML
<div class="mdc-select mdc-select--outlined demo-width-class my-demo-select">
<div class="mdc-select__anchor" aria-labelledby="outlined-select-label">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span id="outlined-select-label" class="mdc-floating-label">Pick a Food Group</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<span class="mdc-select__selected-text-container">
<span id="demo-selected-text" class="mdc-select__selected-text"></span>
</span>
<span class="mdc-select__dropdown-icon">
<svg class="mdc-select__dropdown-icon-graphic" viewBox="7 10 10 5" focusable="false">
<polygon
class="mdc-select__dropdown-icon-inactive"
stroke="none"
fill-rule="evenodd"
points="7 10 12 15 17 10"
></polygon>
<polygon
class="mdc-select__dropdown-icon-active"
stroke="none"
fill-rule="evenodd"
points="7 15 12 10 17 15"
></polygon>
</svg>
</span>
</div> <div class="mdc-select__menu mdc-menu mdc-menu-surface mdc-menu-surface--fullwidth">
<ul class="mdc-deprecated-list" role="listbox" aria-label="Food picker listbox">
<li
class="mdc-deprecated-list-item mdc-deprecated-list-item--selected"
aria-selected="true"
data-value=""
role="option"
>
<span class="mdc-deprecated-list-item__ripple"></span>
</li>
<li
class="mdc-deprecated-list-item"
aria-selected="false"
data-value="grains"
role="option"
>
<span class="mdc-deprecated-list-item__ripple"></span>
<span class="mdc-deprecated-list-item__text"> Bread, Cereal, Rice, and Pasta </span>
</li>
<li
class="mdc-deprecated-list-item mdc-deprecated-list-item--disabled"
aria-selected="false"
data-value="vegetables"
aria-disabled="true"
role="option"
>
<span class="mdc-deprecated-list-item__ripple"></span>
<span class="mdc-deprecated-list-item__text"> Vegetables </span>
</li>
<li
class="mdc-deprecated-list-item"
aria-selected="false"
data-value="fruit"
role="option"
>
<span class="mdc-deprecated-list-item__ripple"></span>
<span class="mdc-deprecated-list-item__text"> Fruit </span>
</li>
</ul>
</div>
</div>
注意: 用 mdc-deprecated-list 是因为当前 MDC 正在升级中...
Scss
@use '@material/list/mdc-list';
@use '@material/menu-surface/mdc-menu-surface';
@use '@material/menu/mdc-menu';
@use '@material/select/styles';
@use '@material/select'; .demo-width-class {
width: 400px;
}
.my-demo-select {
@include select.outlined-density(-2); /* 注: 我用的是 outlined */
}
docs 有说, 需要 set width
TypeScript
import {MDCSelect} from '@material/select'; const select = new MDCSelect(document.querySelector('.mdc-select')); select.listen('MDCSelect:change', () => {
alert(`Selected option at index ${select.selectedIndex} with value "${select.value}"`);
});
效果
icon 没有旋转 animation
下面这个是官网 demo 的样子
右边的 icon 会有一个 180° 旋转, 但是我们做出来的却没有.
我看了一下它的 HTML 发现它俩实现根本就不一样. 我们的 icon 有 2 个, 一个上, 一个下. 切换.
demo 的只有一个 icon, 不是切换是旋转. 也不知道哪个是正确的.
Use in Form
要在 form 使用 select 的话, 需要加上一个 input hidden 作为 submit value, MDC 会同步它
<div class="mdc-select mdc-select--filled demo-width-class">
<input type="hidden" name="demo-input">
<div class="mdc-select__anchor">
<!-- Rest of component omitted for brevity -->
</div>
</div>
Default Value
在 list 加上 selected
同时在 display value 加上相同的值
The Validation Problem
虽然 select 支持 required validation
但毕竟不是原生 validation, 所以无法真的搭配 form 来使用, 比如 submit 的时候, by right 有 invalid 是不能成功的, 但是 select 的 invalid 是无法通知 form 的, 所以 form 能 submit 成功.
native form 没有类似 Angular Form 那样支持扩展 accessor, 所以要实现的话非常麻烦.
思路:
拦截 form submit
检查 select 是否 valid
invalid 就 prevent default
focus to select anchor element (这个是 tabindex 0)
set invalid (为了让它变红色和出 error message)
太麻烦了, 所以建议用 native select 来实现.
Native Select
no support native select
以前 MDC 是支持 native select 的, 但后来由于 maintain 不来, 所以 remove 掉了.
参考: Github Issue – Remove support for native select from MDC Select
虽然没有 build-in 的, 但是自己做也不会太难
HTML
<label class="mdc-text-field mdc-text-field--outlined">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch">
<span class="mdc-floating-label">Full Name</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<select name="fullName" class="mdc-text-field__input" required>
<option value=""></option>
<option value="Dog">Dog</option>
<option value="Cat">Cat</option>
<option value="Banana">Banana</option>
</select>
</label>
用 text field 把 input 换成 select 就可以了 (注意: 虽然是 select, 但 class 依然要放 mdc-text-field__input 哦)
Scss 和 TypeScript
和 input 一样, 我就不写了
箭头的问题
MDC 把箭头 hide 起来了
可以通过 override 的方式叫它出来
select {
appearance: revert !important;
}
但它有缺陷, 颜色不美
不管什么情况下都是黑色, 如果体验要求不高的话, 可以算了.
我试过用 trailing icons 做 (类似上面做 datepicker 那样), 但 select 没有 showPicker 这个功能, 所以这个方向是错的.
正确的做法是 appearance: none, 然后用 background image 做箭头.
参考: stackoverflow – Select arrow style change
Theme
参考: Theming Guide
text field 框的颜色是依据 them 的 primary color
Material Design 默认的颜色是紫色
想换颜色官方给的方法是通过 SCSS 的 variable 把 primary 换了.
@use '@material/theme' with (
$primary: MediumBlue
);
效果
如果只是换 CSS Variable 会有意想不到的结果哦
原因是 label 的 Style 没有使用 CSS Variable, 它只是通过 SCSS Variable 生成
这种一半一半的做法, 也是醉了...
MDC – Text field的更多相关文章
- This text field does not specify an inputType or a hint
android开发过程中突然发现的warning,EditText 报出 “This text field does not specify an inputType or a hint” 原因: ...
- EditText html 出现提示 This text field does not specify an inputType or a hint
1 <EditText 2 android:layout_width="fill_parent" 3 android:layout_height="wrap_c ...
- 从零开始学ios开发(四):IOS控件(1),Image View、Text Field、Keyboard
长话短说,谢谢大家的关注,这篇写了好长时间,下面继续学习ios.我将用2到3篇的篇幅来学习iphone上的一些常用控件,包括Image View.Text Field.Keyboard.Slider等 ...
- 当开始输入文字以及完成文字输入时,变换text field的背景以及系统自带一键删除的 叉叉
当开始输入文字以及完成文字输入时,变换text field的背景. -(BOOL) textFieldShouldBeginEditing:(UITextField *)textField{ [tex ...
- <EditText /> This text field does not specify an inputType or a hint
我是一个警告,xml代码是: <EditText android:id="@+id/str_ipaddress" android:layout_width="wra ...
- 限制 Text Field 输入的内容类型:只允许输入数字
效果如下: ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController< ...
- 一行代码轻松修改 Text Field 和 Text View 的光标颜色 — By 昉
众所周知,Text Field 和 Text View 的光标颜色默认都是系统应用的那种蓝色,如图: 而在实际开发中为了让视觉效果更统一,我们可能会想把那光标的颜色设置成和界面色调一致的颜色.其实在 ...
- 问题; No label views point to this text field with an android:labelFor="@+id/@+id/editTextNumber1" attribute
设置完EditText的ID后老是报一个警告. 解决方法: 需要在EditText属性中添加inputType和labelFor两个属性.其中labelFor属性的值与id值相同即可
- 编辑控件的警告提示是:This text field does not specify an inputType or a hint
没有设置editText的inputtype属性,比如<android:inputtype="textpassword"> http://binuu.blog.51ct ...
- SQL Server text field里面有换行符的时候copy到excel数据会散乱
解决方法: select '"'+convert(varchar(8000),testField)+'"'astestField from testTable 这样虽然结果集里面有 ...
随机推荐
- adorner 使用示例
模块介绍 adorner 是一个现代轻量级的 Python 装饰器辅助模块. 目前该模块仅实现了 4 个类,对应着 4 个功能:制造装饰器.执行计时.函数缓存.捕获重试. 仓库地址:https://g ...
- 解锁网络无限可能:揭秘微软工程师力作——付费代理IP池深度改造与实战部署指南
基于付费代理的代理IP池 项目来源 此项目为微软某个工程师构建的代理IP池,我对此进行了改造.可以用于生产环境中的爬虫项目 阅读前建议 阅读我之前发布的爬虫基础的文章,了解代理如何获取.使用等. 分为 ...
- 在缩小浏览器宽度的时候,图片会超出li的宽度
要确保在缩小浏览器宽度时,图片不会超出 <li> 元素的宽度,您可以为描述文本添加一些样式,以便让图片适应于 <li> 元素.一种常见的方法是使用 CSS 中的 max-wid ...
- oeasy教您玩转vim - 90 - # 语法定义syntax
内容查找 grep 回忆 我们这次研究了一下配色方案 murphy虽然配色好看 但是对于java的支持并不好 我们对于murphy进行了修改 增加了String.StorageClass颜色的定义 ...
- 解决“网页源代码编码形式为utf-8,但爬虫代码设置为decode('utf-8')仍出现汉字乱码”的问题
为了用爬虫获取百度首页的源代码,检查了百度的源代码,显示编码格式为utf-8 但这样写代码,却失败了-.. (这里提示:不要直接复制百度的URL,应该是http,不是https!!!) # 获取百度首 ...
- Python 标准类库-因特网数据处理之Base64数据编码
该模块提供将二进制数据编码为可打印ASCII字符并将这种编码解码回二进制数据的功能.它为RFC 3548中指定的编码提供编码和解码功能.定义了Base16.Base32和Base64算法,以及事实上的 ...
- Spring Boot快速入门(二)搭建javaWeb项目
1.配置pom.xml 教程一创建的项目为maven项目,所以搭建一个Spring Boot的Web项目,先导入一下jar包:即在pom.xml以下依赖: 1 <dependencies> ...
- Nuxt.js必读:轻松掌握运行时配置与 useRuntimeConfig
title: Nuxt.js必读:轻松掌握运行时配置与 useRuntimeConfig date: 2024/7/29 updated: 2024/7/29 author: cmdragon exc ...
- 【Maxwell】02 Kafka配置
一.快速搭建Kafka环境 基于Docker容器创建(供参考): https://www.cnblogs.com/mindzone/p/15608984.html 这里简要写一下命令: # 拉取zk ...
- 【Web】 通过浏览器打开本地应用程序
首先需要编写注册表: 以Steam为例: "C:\Program Files (x86)\Steam\Steam.exe" 然后编写注册表: Windows Registry Ed ...