Text Fields

概述

文本控件允许用户在你的app中打字。它可以是单行的,也可以是多行的。触摸文本控件所占的空间会显示光标并且自动弹出软键盘。除了打字之外,文本控件允许各种其它活动,如文本选择(剪切,复制,黏贴)和由自动完成功能( auto-completion. )提供的数据查询。
通过包含   EditText  对象, 在你的布局文件中添加一个文本控件,也可以在你的xml布局文件中添加 <EditText>  元素来添加。

指定软键盘类型

文本控件有许多不同的输入类型,如数字,日期,密码或邮箱地址。输入类型决定了何种字符被允许键入文本内,如果频繁使用字符,可以优化虚拟键盘的布局。
你可以指定软键盘的类型,在 EditText  对象中的   android:inputType  属性。例如,如果你想要用户输入的是邮箱地址,你可以使用 textEmailAddress  输入类型:
   
<EditText
android:id="@+id/email_address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/email_hint"
android:inputType="textEmailAddress" />
这里有一些可以在不同情况下使用的输入类型。你可以在   android:inputType . 文件中找到它们。
小技巧:为允许用户输入换行符以输入长字符串,使用 "textMultiLine"  类型。默认,一个 EditText对象是只限制于一行文本的,当它超过一行时将需要滑动查看。

控制其它行为

  android:inputType 也允许你指定某些确切的软件盘行为,如是否能够利用所有的新词或者自动拼写和建议。
 android:inputType 属性也允许按位组合(用|操作符来连接多个值),这样你就可以一次性 同时指定键盘布局和 一个或多个行为。例如,下面展示的代码可以允许你收集邮箱地址,利用每一个单词,并且禁用文本建议。
   
<EditText
android:id="@+id/postal_address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/postal_address_hint"
android:inputType="textPostalAddress|
textCapWords|
textNoSuggestions" />
详细的行为可以查看   android:inputType  文件。

指定键盘操作

除了改变键盘的输入类型,安卓允许你指定一个当用户完成他们的输入时执行的操作。被指定操作的按钮会出现并替代回车键和它要做出的动作,例如“查找”或“发送”
你可以通过设置   android:imeOptions  属性来指定操作。例如,这段代码指定了一个Send操作:
   
<EditText
android:id="@+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/search_hint"
android:inputType="text"
android:imeOptions="actionSend" />
如果你并没有明确的指出一个输入动作,  系统会尝试确定是否 之后有包含 android:focusable的(文本)字段。 如果在这之后找到了任何可聚焦的(文本)字段,系统就会提供一个 actionNext 操作来移出 EditText  ,这样用户将可以选择Next来移动到下一个(文本)字段。如果没有,系统提供 "actionDone" 操作。你可以通过设置 android:imeOptions   属性为任何其它的值 来覆盖该操作 ,如 "actionSend"  or  "actionSearch" ,或者使用默认的 "actionNone"  行为。

响应操作按钮事件

如果你使用   android:imeOptions  属性指定了一个键盘操作(如 "actionSend" ),你可以通过使用 TextView.OnEditorActionListener . 来监听这个操作事件。 TextView.OnEditorActionListener接口提供了一个回掉函数   onEditorAction()  ,用操作ID来标明每一个操作类型,如 IME_ACTION_SEND  or  IME_ACTION_SEARCH .。
例如,这段代码展示你如何去监听用户点击Send按钮时的事件:
   
EditText editText = (EditText) findViewById(R.id.search);
editText.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND) {
// Send the user message
handled = true;
}
return handled;
}
});

设置自定义操作按钮标签

如果键盘太大而不能合理的占用应用下方的空间时(如,当手机设备处于横向时)就会开启全屏。在该模式下(全屏),一个被标记的操作按钮显示在了输入框的旁边。你可以自定义这个按钮上的文本,通过设置 android:imeActionLabel  属性。
   
<EditText
android:id="@+id/launch_codes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/enter_launch_codes"
android:inputType="number"
android:imeActionLabel="@string/launch" />

添加其它键盘标志

另外的一些操作可以通过 android:imeOptions  属性指定,你可以添加额外的标志来指定其它键盘行为。所有可用的标志都在文件   android:imeOptions 中列出。
例如,图5展示了如何使系统全屏显示文本字段,当手机处于横向(或屏幕空间受限)。你可以禁用全屏输入模式,通过   android:imeOptions属性的 flagNoExtractUi  值,如图6所示。

提供自动补全建议

如果你想给用户的输入提供一些建议,你可以使用   EditText  的子类  AutoCompleteTextView . 为了实现自动补全,你必须指定一个提供建议文本的适配器。有许多现成的适配器可供使用,取决于数据的来源,如来自于数据库或数组。
下面的一段展示了如何设置 AutoCompleteTextView  从数组中提供建议,使用数组适配器 ArrayAdapter :
  1. 在你的布局中添加AutoCompleteTextView  下面这个布局中仅有一个文本字段
         
    <?xml version="1.0" encoding="utf-8"?>
    <AutoCompleteTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/autocomplete_country"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
  2. 定义包含所有建议文本的数组。例如,下面有一组在XML资源文件下的定义的数组 (res/values/strings.xml),包含国家名。
         
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <string-array name="countries_array">
    <item>Afghanistan</item>
    <item>Albania</item>
    <item>Algeria</item>
    <item>American Samoa</item>
    <item>Andorra</item>
    <item>Angola</item>
    <item>Anguilla</item>
    <item>Antarctica</item>
    ...
    </string-array>
    </resources>
  3.  在你的Activity 或 Fragment,使用如下的代码来指定适配器来提高建议。
         
    // Get a reference to the AutoCompleteTextView in the layout
    AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_country);
    // Get the string array
    String[] countries = getResources().getStringArray(R.array.countries_array);
    // Create the adapter and set it to the AutoCompleteTextView
    ArrayAdapter<String> adapter =
    new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, countries);
    textView.setAdapter(adapter);

    这里,一个新的 ArrayAdapter 被初始化,为 每一个TextView绑定了每一个国家字符串,这个TextView  存在于simple_list_item_1 布局中(该布局是由安卓提供的,它的作用是提供显示一个标准的文本列表)

    然后,通过调用 setAdapter().来为 AutoCompleteTextView 绑定这个适配器。

<think> 嗯,用户需要解决Elasticsearch中text字段默认禁用Fielddata的问题。根据提供的所有引用内容,核心问题在于:text类型字段默认关闭fielddata功能,但用户又需要用它来做排序、聚合等操作。 用户可能是Elasticsearch的中级使用者,遇到了业务中需要对文本字段进行聚合的需求。从引用[3]看,用户很可能在日志里看到了经典的错误提示"Fielddata is disabled on text fields by default",这确实是ES开发中的常见痛点。 引用[1][2][5]都强调了fielddata的两个关键特性:一是会消耗大量堆内存,二是加载过程昂贵。这说明解决方案需要平衡功能和资源消耗。引用[4]给出的示例非常实用,展示了具体操作步骤,包括修改mapping设置fielddata=true的完整流程。 考虑到用户可能面临的实际场景,需要重点提醒风险:引用[4]明确提到"启用fielddata通常没有任何意义,因为它非常耗费内存",除非确实需要。而引用[3]的解决方案其实提供了两种路径——要么开启fielddata,要么改用keyword字段,后者可能是更优解。 用户没有说明具体使用场景,但根据引用[4]的提示,如果是全文搜索为主的应用就不需要开启。这提示我需要补充询问场景的步骤,避免用户盲目开启。另外,聚合频次也是关键因素,偶尔聚合和高频聚合对内存的影响完全不同。 在整理解决方案时,应该把更安全的keyword方案放在前面,因为引用[3][4]都推荐了这个做法。而开启fielddata的方案需要配套内存监控建议,这点引用[1][5]都提到了堆空间风险。示例代码最好保留引用[4]的DSL,但改用更简洁的test_index名称避免混淆。 </think> 针对Elasticsearch中text字段默认禁用Fielddata的问题,以下是完整解决方案及注意事项: ### 一、问题原因 Elasticsearch默认禁用text字段的Fielddata,主要因其**内存消耗大**且**加载成本高**(引用[2][5]): 1. Fielddata会将文本字段数据加载到堆内存中 2. 高基数文本字段(如日志消息)可能消耗GB级内存 3. 加载过程导致查询延迟(尤其大字段) 4. 数据在分段生命周期内常驻内存不可释放 ### 二、解决方案 #### ✅ 方案1:启用fielddata(谨慎使用) 在mapping中显式开启fielddata: ```json PUT your_index/_mapping { "properties": { "your_text_field": { "type": "text", "fielddata": true // 关键设置 } } } ``` **适用场景**: - 必须对原始分词后的文本进行聚合/排序 - 内存资源充足且字段基数低(如<1000个唯一词项) #### ✅ 方案2:使用keyword多字段(推荐) 通过multi-fields同时保留text和keyword类型: ```json PUT your_index { "mappings": { "properties": { "content": { "type": "text", // 用于全文搜索 "fields": { "keyword": { // 用于聚合/排序 "type": "keyword" } } } } } } ``` 查询时使用`content.keyword`进行聚合/排序: ```json GET your_index/_search { "aggs": { "top_keywords": { "terms": { "field": "content.keyword" // 使用keyword子字段 } } } } ``` **优势**: - 避免内存爆炸(keyword字段使用doc_values,非堆内存) - 支持精确值操作(如排序、聚合) - 保留全文搜索能力(引用[4]) ### 三、关键注意事项 1. **内存监控**: ```json GET _nodes/stats/indices/fielddata?fields=* ``` 定期检查fielddata内存使用,防止OOM(引用[5]) 2. **资源限制**: ```json PUT _cluster/settings { "persistent": { "indices.breaker.fielddata.limit": "40%" // 堆内存占比≤40% } } ``` 3. **替代方案**: - 对无需分词的字段直接用`keyword`类型 - 冷数据聚合使用`doc_values`(默认开启) 4. **重建索引**: 修改mapping后需用`_reindex`迁移数据(引用[4]示例) > ⚠️ **警示**:仅在必须使用分词结果进行聚合时才开启fielddata(如词云生成),多数场景应优先采用keyword多字段方案(引用[4]强调"启用fielddata通常没有任何意义")。 ### 四、典型错误场景 尝试聚合text字段时抛出异常: ```log Fielddata is disabled on text fields by default. Set fielddata=true on [your_field]... (引用[3]) ``` 此时按上述方案二修改查询字段为`your_field.keyword`即可解决。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值