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实现自动补全 的相关文章

随机推荐

  • 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实现自动补全

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