Android AutoCompleteTextView实现自动补全

2023-11-20

辛苦堆砌,转载请注明出处,谢谢!

最近工作用到了自动补全,这里做一个简单记录,首先上我们的布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp"
    tools:context="com.yjp.autocompletetextviewdemo.MainActivity">

    <AutoCompleteTextView
        android:id="@+id/auto_complete_text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:completionThreshold="2"
        android:layout_gravity="top" />
</FrameLayout>
只有我们的主角,这样更能突出主题,需要注意的是我们通过android:completionThreshold设置了只有输入两个以上文字,才会弹出自动补全框。其他属性可以从官方文档了解一下。


我们的示例主要通过在SQLite中模糊搜索来实现自动补全功能,先看看我们的SQLiteHelper

package com.yjp.autocompletetextviewdemo;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbHelper extends SQLiteOpenHelper {

    //大学表
    public static final String SCHOOLS_TABLE_NAME = "table_schools";
    public static final String COL_SCHOOL_NAME = "school_name";

    private static final String DB_NAME = "auto_complete_text_view_app_db";
    private static final int DB_VERSION = 1;

    private static final String STRING_CREATE_SCHOOL_TABLE =
            "CREATE TABLE " + SCHOOLS_TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
            + COL_SCHOOL_NAME + " TEXT);";

    public DbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(STRING_CREATE_SCHOOL_TABLE);

        //伪造一些数据
        ContentValues cv = new ContentValues(1);
        cv.put(COL_SCHOOL_NAME, "大连理工大学");
        db.insert(SCHOOLS_TABLE_NAME, COL_SCHOOL_NAME, cv);

        cv.put(COL_SCHOOL_NAME, "太原理工大学");
        db.insert(SCHOOLS_TABLE_NAME, COL_SCHOOL_NAME, cv);

        cv.put(COL_SCHOOL_NAME, "天津理工大学");
        db.insert(SCHOOLS_TABLE_NAME, COL_SCHOOL_NAME, cv);

        cv.put(COL_SCHOOL_NAME, "河北工业大学");
        db.insert(SCHOOLS_TABLE_NAME, COL_SCHOOL_NAME, cv);

        cv.put(COL_SCHOOL_NAME, "天津大学");
        db.insert(SCHOOLS_TABLE_NAME, COL_SCHOOL_NAME, cv);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + STRING_CREATE_SCHOOL_TABLE);
    }
}
一个很简单的例子,数据库除了_id列只有一列,表示大学,而且我们伪造了一些数据。


然后看看我们需要一个CursorAdapter来给我们的AutoCompleteTextView使用,如下所示

package com.yjp.autocompletetextviewdemo;

import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;

public class AutoCompleteAdapter extends CursorAdapter {

    public AutoCompleteAdapter(Context context) {
        super(context, null, 0);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(context);
        TextView view = (TextView) inflater.inflate(
                android.R.layout.simple_dropdown_item_1line, parent, false);
        return view;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ((TextView) view).setText(cursor.getString(cursor.getColumnIndex(DbHelper.COL_SCHOOL_NAME)));
    }
}
依然很简单,我们使用了Android提供的布局,显示我们自动补全的弹出框的行,这也是AutoCompleteTextView默认使用的,如果应用场景不像我这里描述的复杂,只要AutoCompleteTextView调用setAdapter设置一个ArrayAdapter即可,ArrayAdapter关联的数据就会显示在弹出框中。


最后,看看我们的MainActivity

package com.yjp.autocompletetextviewdemo;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.FilterQueryProvider;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private AutoCompleteTextView mAutoCompleteTextView;

    //一定要使用一个成员变量,不然DbHelper内存回收会导致DB无法使用
    private DbHelper mDbHelper;
    private SQLiteDatabase mDb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.auto_complete_text_view);

        //实际上设置的是弹出的列表的OnItemClickListener
        //另外千万注意,不要使用OnItemSelectedListener
        //看源码中该监听器虽然可以设置,但是没有用到
        mAutoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //这里设置文本值,否则默认显示赋值的文本是Cursor的toString()
                TextView textView = (TextView) view;
                mAutoCompleteTextView.setText(textView.getText());
            }
        });

        AutoCompleteAdapter adapter = new AutoCompleteAdapter(this);

        //这里设置FilterQueryProvider可以自定义自己的Cursor创建逻辑
        //而不是使用默认设置给Adapter的Cursor,实现动态处理
        adapter.setFilterQueryProvider(new FilterQueryProvider() {
            @Override
            public Cursor runQuery(CharSequence constraint) {
                if (constraint == null || constraint.length() == 0) {
                    return null;
                }

                //模糊查找,千万加入_id列,否则无法正常使用
                return mDb.rawQuery("SELECT _id," + DbHelper.COL_SCHOOL_NAME
                        + " FROM " + DbHelper.SCHOOLS_TABLE_NAME
                        + " WHERE " + DbHelper.COL_SCHOOL_NAME
                        + " LIKE \'%" + constraint.toString() +"%\'", null);
            }
        });
        mAutoCompleteTextView.setAdapter(adapter);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mDbHelper = new DbHelper(this);

        //使用getWritableDatabase,如果表不存在会自动创建
        mDb = mDbHelper.getWritableDatabase();
    }

    @Override
    protected void onStop() {
        super.onStop();

        //资源回收
        mDb.close();
        mDbHelper.close();
    }
}
注释已经尽可能详细了,大家可以看一下,这样,我们就实现了AutoCompleteTextView的自动补全。如下图所示

可以看到,实现了我们最初的设想,另外,从这次使用中,也总结了一些经验,遇到问题,查看官方文档,有些文档中没有写的,自己去尝试。当时遇到问题,点选提示框中的一项时,发现没有显示提示框条目中的内容,而是显示了Cursor的地址信息,很显然是Cursor的toString的结果,所以想到,需要对点选之后的内容进行转换,当时尝试设置OnItemSelectedListener,但是发现没有用处,之后查看AutoCompleteTextView源码才发现,这个监听器,实现中使用一个成员变量保存了,但是没有任何地方调用,不过发现OnItemClickListener被调用,因此改而使用OnItemClickListener。






本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android AutoCompleteTextView实现自动补全 的相关文章

  • 如何做Android - 滑动抽屉从左到右滑动..?

    如何将android滑动抽屉从LTR滑动 使用时android orientation horizontal 它从 RTL 滑出 我该如何进行 LTR 谢谢 我找到了答案表格 Here http blog sephiroth it 2011
  • java.lang.IllegalArgumentException:此组件要求您指定有效的 android:textAppearance 属性

    我的布局文件之一中有一个 com google android material button MaterialButton 组件 当我使用最新版本的 Material Components 库 com google android mat
  • 在 Android 上通话结束时启动活动

    我想在通话结束时启动一项活动 找不到任何对此的参考 我该怎么做 我还没有尝试过这个 但我假设你可以运行一些服务 始终在后台运行 它利用电话状态监听器 http developer android com reference android
  • 如何在android中实现触摸平滑图像橡皮擦?

    我已经从 API 演示中看到了finturePaint java 我想实现触摸平滑橡皮擦 通过在android中触摸移动来擦除部分图像 FingerPaint 告诉我要实现这个 mPaint setXfermode new PorterDu
  • Android 中多个蓝牙连接的自定义 UUID

    我有一个 Android 设备作为服务器连接到多个蓝牙 Android 客户端 我了解 UUID 的概念以及它的独特之处 我的问题是 我可以为连接到我的服务器的所有客户端使用相同的 UUID 吗 如果没有 我如何以编程方式为我的客户端生成
  • gradle更新后无法找到方法(无法编译项目)

    我尝试将项目中的 gradle 版本更新为 4 1 milestone 1 以下这些说明 https developer android com studio build gradle plugin 3 0 0 migration html
  • Xamarin Android Webview Javascript

    我正在尝试通过 Xamarin for Android 创建一个移动应用程序 它有一个显示网站的 WebView 问题是正常按钮会触发 但 javascript 事件不会触发 我已经启用了 Javascript 但没有运气 如何在 Andr
  • 如何使用 Google Maps for Android V2 处理地图移动结束?

    我想在地图中心更改后立即对地址进行地理编码 如何使用新的 Android 版 Google 地图 V2 处理地图移动 我说的是用户用手指拖动地图的情况 查看新的地图 API Override public void onMapReady G
  • 将现有 VARCHAR 列与 Room 结合使用

    我正在尝试将现有的数据库与 Android Room 一起使用 但是 我的一个表有一个 VARCHAR 列 Room 似乎只支持 TEXT 不支持 VARCHAR 而且 sqlite 不允许修改列类型 那么 有没有办法使用Room中现有的带
  • Android 初学者:Android gridview 中的触摸事件

    我正在使用以下代码来使用 gridview 执行操作 稍作修改http developer android com resources tutorials views hello gridview html http developer a
  • 自定义首选项中的android首选项水平分隔线?

    我创建了自己的自定义首选项对象来扩展首选项 我创建它们只是因为这些自定义数据类型没有首选项 一切正常 但我的自定义首选项没有相同的外观 因为它们缺少系统首选项对象具有的水平分隔线 我已经查找了创建水平分隔线的代码 但我找不到它是在哪里完成的
  • Android 手机作为 GSM 调制解调器在 PC 上发送/接收短信?

    是否可以将 Android 移动设备用作 PC 上的 GSM 调制解调器 我正在 net下开发应用程序来发送 接收短信等 现在我想通过 USB 将我的 Android 设备连接到我的 PC 并将其用作 GSM 调制解调器来与其通信 这里是参
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • OnLongClickListener 不工作

    我有一个ImageView 我需要使用onLongClickListener对于图像视图 当我使用这段代码时 什么也没有发生 Code gallery Gallery findViewById R id gall1 gallery setA
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 在 Samsung Galaxy S5 Android 5.0 上使用 MediaPlayer 加载音频流需要超过 10 秒

    由于更新至 Android 5 0 MediaPlayer 在 Samsung Galaxy S5 上无法正常工作 启动音频流后加载时间超过 10 秒 示例代码 MediaPlayer mPlayer new MediaPlayer Str
  • 上网本上可以进行Android开发吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想使用我的上网本进行 Android 开发 但是当我尝试使用 Eclipse 运行 SDK 时 没有加载任何内容 上网本对于 Android 开发来
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • 我的应用程序中的后退按钮出现问题[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想在手机关闭时清除共享首选项值 你

随机推荐

  • C++STL总结笔记(二)——仿函数(函数对象)

    文章目录 一 概念 总结 一 概念 仿函数又称函数对象 即重载了函数调用运算符 的类的对象 优势 1 仿函数对象的内部可以有自己的状态 可以实现一些其他的功能 2 函数对象可以作为参数进行传递 当仿函数类内重载的返回值是bool类型被称为谓
  • Python爬虫网易云音乐--JS逆向-补充笔记

    课程地址 https www bilibili com video BV1Mi4y147Yb up主省略掉的 用报错信息来一一回溯的方式把js文件补全的过程 主要把握的几个点 把以下部分代码找到粘贴到js中即可补全并顺利运行 CryptoJ
  • 《数据库系统概论》重点整理

    Word文档链接 https wenku baidu com view 063d7656f9c75fbfc77da26925c52cc58bd69088 第一章 数据模型的三个要素 数据结构 数据操作 完整性约束 数据库领域常用的逻辑模型
  • minikube start启动集群失败Unable to find image gcr.io/k8s-minikube/kicbase:v0.0.10

    配套视频教程 minikube带你玩转k8s集群 1 minikube启动集群 minikube start vm driver docker image mirror country cn image repository registr
  • Intel CPU5种不同的CPU频率标定方式

    作者 cici xiang 链接 https www zhihu com question 271509706 answer 364246338 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 Intel C
  • G - Ginger的NB数(二分)

    G Ginger的NB数 SDUT OnlineJudge include
  • pyopencv基础操作指南

    个人学习整理 欢迎指正 实验版本 python版本 3 6 13 opencv版本 2 4 9 1 opencv简介 官网 http docs opencv org 3 0 beta doc py tutorials py tutorial
  • python无法导入自定义类

    问题描述是python3环境 在C Python36 Lib site packages mekk xmind目录下有 init py document py id gen py和xmlutil py四个文件 但是在引入mekk xmind
  • Linux 版本的 SQL Server 快速安装

    SQL Server 2017 版本已经支持 Linux 安装了 出来了很长时间 我还没有实现过在 Linux 上面的应用 包括安装和高可用配置 本文就先尝试完成 Linux 版 SQL Server 的安装 经常在 Windows 下安装
  • VLC for unity 插件如何使用

    VLC for unity 插件如何使用 先去下载一个VLC播放器 安装完成后 然后导入插件链接https download csdn net my 这个插件我的另一个上传资源里有 或者到商店去下载 这个插件链接下载完是一个txt文档 里面
  • settings.json是什么?VS Code的“用户”和“工作区”

    setting json settings json是VS Code众多配置文件中的一个 可以对VS Code进行页面风格 代码格式 字体颜色大小等的编辑设置 比如可能编辑器默认的一个tab为4个空格 用户可以在setting json里面
  • C++11-14 第10讲 template template parameter(模板模板参数)

    template
  • QML类型——ListModel

    正文 列表数据Model 可以自定义格式 详细说明 ListModel是定义ListElement的容器 内容可以动态定义 也可以在QML中明确定义 可以通过count属性获得模型中数据的数量 可以使用模型的setProperty 方法来操
  • 【Linux/C++:modebus通信示例】(带初习配置概括)

    以modbus RTU为例 模拟modbus简单通信原理的代码实现 首先需要配置串口 这里使用的为Configure Virtual Serial Port Driver虚拟串口调试工具 创建COM1 COM2虚拟端口 或另创建一对串口互作
  • JAVA自学之路

    JAVA自学之路 一 学会选择 为了就业 不少同学参加各种各样的培训 决心做软件的 大多数人选的是java 或是 net 也有一些选择了手机 嵌入式 游戏 3G 测试等 那么究竟应该选择什么方向呢 我的意见是 不要太过相信各种培训机构或是抢
  • ctfshow web7

    文章目录 题目分析 解题过程 题目分析 打开题目后 有三个文章 随便点一个之后发现网址上有个后缀 id 2 应该是get传参的注入了 在后缀上加 id 1 1 显示全部文章 可能是整形注入 还是盲注 他这个过滤了空格 用 代替 详见web6
  • MySQL 8.0数据库在Win10的位置

    MySQL 8 0的配置文件位置在下面的ini文件中 C ProgramData MySQL MySQL Server 8 0 my ini C ProgramData 一般是隐藏的 修改文件夹选项可见 或者直接输入位置就能打开文件加了 m
  • wifidog浏览器弹窗认证 — 基于OpenWRT路由器

    一 移植 wifidog功能 1 功能介绍 wifidog是一种能够实现让路由器局域网设备 包括wifi连接和网线连接设备 在上网前先进行 portal认证的工具 主要应用于手机端上网认证 手机在连接wifi后会自动打开浏览器并跳转出 lo
  • C++顺序链表

    include
  • Android AutoCompleteTextView实现自动补全

    辛苦堆砌 转载请注明出处 谢谢 最近工作用到了自动补全 这里做一个简单记录 首先上我们的布局