前言

作为一名Android开发小白,应该时刻督促自己不断的学习技术,最近遇到了一个和搜索有关的问题,就学习找时间学习了一下,如何实现简单Android的搜索功能并可以实时预览搜索结果,整体思路应该和平常我们见到的搜索功能差不多,所以可以直接将我的这个嵌套到你的项目中使用。 项目源代码
本博客同步发布于 XueLong的博客

先来看看效果图吧!

实现思路

首先搜索纪录应该有两种情况:
1、用户直接输入的信息这个毫无疑问肯定是搜索纪录。
2、用户输入完成后并没有点击搜索按钮而是直接点击了搜索结果,那么搜索结果应该也是搜索纪录。

思路:

  • 刚进入搜索界面时,查询搜索纪录数据库,看是否有搜索纪录,有则显示搜索纪录,无则不显示。
  • 当用户在搜索框中输入关键字字时,下方listview实时显示数据库中模糊查询的结果。

具体实现

  • 1、初始化本地数据库
  • 2、尝试从保存查询纪录的数据库中获取历史纪录并显示
  • 3、使用TextWatcher实现对实时搜索
  • 4、搜索及保存搜索纪录
  • 5、listview的点击 做你自己的业务逻辑

知识点

数据库的增删改查ScrollView中嵌套ListViewEditText的TextWatcher软键盘隐藏

以下是代码实现:

RecordsSqliteHelper实现(用来操作历史纪录的)

public class RecordsSqliteHelper extends SQLiteOpenHelper {    private String CREATE_RECORDS_TABLE = "create table table_records(_id integer primary key autoincrement,username varchar(200),password varchar(200))";    public RecordsSqliteHelper(Context context) {        super(context, "records_db", null, 1);    }    @Override    public void onCreate(SQLiteDatabase sqLiteDatabase) {        sqLiteDatabase.execSQL(CREATE_RECORDS_TABLE);    }    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {    }}

SearchSqliteHelper实现(用来操作搜索查询的)

public class SearchSqliteHelper extends SQLiteOpenHelper {    private String CREATE_TABLE = "create table table_search(_id integer primary key autoincrement,username varchar(200),password varchar(200))";    public SearchSqliteHelper(Context context) {        super(context, "search_db", null, 1);    }    @Override    public void onCreate(SQLiteDatabase sqLiteDatabase) {        sqLiteDatabase.execSQL(CREATE_TABLE);    }    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {    }}

ListViewForScrollView(一个可以兼容ScrollView的ListView)

public class ListViewForScrollView extends ListView {    public ListViewForScrollView(Context context) {        super(context);    }    public ListViewForScrollView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public ListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    // TODO: 2017/8/9 只需要重写这一个方法就可以了,重写后可以使ListView在ScrollView中展开    /**     * 传入一个固定值expandSpec来绘制ListView的高。     * http://blog.csdn.net/liaoinstan/article/details/50509122     * @param widthMeasureSpec     * @param heightMeasureSpec     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        super.onMeasure(widthMeasureSpec, expandSpec);    }}

activity_main(主布局)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp"        android:gravity="center"        android:orientation="horizontal">        <EditText            android:id="@+id/edit_search"            android:layout_width="wrap_content"            android:layout_height="50dp"            android:background="@null"            android:drawableLeft="@android:drawable/ic_menu_search"            android:drawablePadding="8dp"            android:gravity="center_vertical"            android:hint="请输入关键词查询!"            android:imeOptions="actionSearch"            android:singleLine="true" />        <TextView            android:id="@+id/tv_search"            android:layout_width="50dp"            android:layout_height="match_parent"            android:gravity="center"            android:text="搜索"            android:textSize="20sp" />    LinearLayout>    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical">            <LinearLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="vertical"                android:paddingLeft="20dp">                <TextView                    android:id="@+id/tv_tip"                    android:layout_width="match_parent"                    android:layout_height="50dp"                    android:gravity="left|center_vertical"                    android:text="搜索历史" />                <com.skylark.localsearchdemo.views.ListViewForScrollView                    android:id="@+id/listView"                    android:layout_width="match_parent"                    android:layout_height="wrap_content" />            LinearLayout>            <TextView                android:id="@+id/tv_clear"                android:layout_width="match_parent"                android:layout_height="40dp"                android:background="#F6F6F6"                android:gravity="center"                android:text="清除搜索历史" />        LinearLayout>    ScrollView>LinearLayout>

MainActivity(主方法实现)

public class MainActivity extends AppCompatActivity {    EditText mEditSearch;    TextView mTvSearch;    TextView mTvTip;    ListViewForScrollView mListView;    TextView mTvClear;    SimpleCursorAdapter adapter;    SearchSqliteHelper searchSqliteHelper;    RecordsSqliteHelper recordsSqliteHelper;    SQLiteDatabase db_search;    SQLiteDatabase db_records;    Cursor cursor;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initData();        initListener();    }    private void initView() {        mEditSearch = (EditText) findViewById(R.id.edit_search);        mTvSearch = (TextView) findViewById(R.id.tv_search);        mTvTip = (TextView) findViewById(R.id.tv_tip);        mListView = (ListViewForScrollView) findViewById(R.id.listView);        mTvClear = (TextView) findViewById(R.id.tv_clear);    }    private void initData() {        searchSqliteHelper = new SearchSqliteHelper(this);        recordsSqliteHelper = new RecordsSqliteHelper(this);        // TODO: 2017/8/10 1、初始化本地数据库        initializeData();        // TODO: 2017/8/10 2、尝试从保存查询纪录的数据库中获取历史纪录并显示        cursor = recordsSqliteHelper.getReadableDatabase().rawQuery("select * from table_records", null);        adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor                , new String[]{"username", "password"}, new int[]{android.R.id.text1, android.R.id.text2}                , CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);        mListView.setAdapter(adapter);    }    /**     * 避免重复初始化数据     */    private void deleteData() {        db_search = searchSqliteHelper.getWritableDatabase();        db_search.execSQL("delete from table_search");        db_search.close();    }    /**     * 初始化数据     */    private void initializeData() {        deleteData();        db_search = searchSqliteHelper.getWritableDatabase();        for (int i = 0; i < 20; i++) {            db_search.execSQL("insert into table_search values(null,?,?)",                    new String[]{"name" + i + 10, "pass" + i + "word"});        }        db_search.close();    }    /**     * 初始化事件监听     */    private void initListener() {        /**         * 清除历史纪录         */        mTvClear.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                deleteRecords();            }        });        /**         * 搜索按钮保存搜索纪录,隐藏软键盘         */        mTvSearch.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                //隐藏键盘                ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))                        .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);                //保存搜索记录                insertRecords(mEditSearch.getText().toString().trim());            }        });        /**         * EditText对键盘搜索按钮的监听,保存搜索纪录,隐藏软件盘         */        // TODO: 2017/8/10 4、搜索及保存搜索纪录        mEditSearch.setOnKeyListener(new View.OnKeyListener() {            @Override            public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {                if (keyCode == KeyEvent.KEYCODE_ENTER && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {                    //隐藏键盘                    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))                            .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);                    //保存搜索记录                    insertRecords(mEditSearch.getText().toString().trim());                }                return false;            }        });        /**         * EditText搜索框对输入值变化的监听,实时搜索         */        // TODO: 2017/8/10 3、使用TextWatcher实现对实时搜索        mEditSearch.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}            @Override            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}            @Override            public void afterTextChanged(Editable editable) {                if (mEditSearch.getText().toString().equals("")) {                    mTvTip.setText("搜索历史");                    mTvClear.setVisibility(View.VISIBLE);                    cursor = recordsSqliteHelper.getReadableDatabase().rawQuery("select * from table_records", null);                    refreshListView();                } else {                    mTvTip.setText("搜索结果");                    mTvClear.setVisibility(View.GONE);                    String searchString = mEditSearch.getText().toString();                    queryData(searchString);                }            }        });        /**         * ListView的item点击事件         */        // TODO: 2017/8/10 5、listview的点击 做你自己的业务逻辑 保存搜索纪录        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {                String username = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();                String password = ((TextView) view.findViewById(android.R.id.text2)).getText().toString();                Log.e("Skylark ", username + "---" + password);                // TODO: 2017/8/10 做自己的业务逻辑            }        });    }    /**     * 保存搜索纪录     *     * @param username     */    private void insertRecords(String username) {        if (!hasDataRecords(username)) {            db_records = recordsSqliteHelper.getWritableDatabase();            db_records.execSQL("insert into table_records values(null,?,?)", new String[]{username, ""});            db_records.close();        }    }    /**     * 检查是否已经存在此搜索纪录     *     * @param records     * @return     */    private boolean hasDataRecords(String records) {        cursor = recordsSqliteHelper.getReadableDatabase()                .rawQuery("select _id,username from table_records where username = ?"                        , new String[]{records});        return cursor.moveToNext();    }    /**     * 搜索数据库中的数据     *     * @param searchData     */    private void queryData(String searchData) {        cursor = searchSqliteHelper.getReadableDatabase()                .rawQuery("select * from table_search where username like '%" + searchData + "%' or password like '%" + searchData + "%'", null);        refreshListView();    }    /**     * 删除历史纪录     */    private void deleteRecords() {        db_records = recordsSqliteHelper.getWritableDatabase();        db_records.execSQL("delete from table_records");        cursor = recordsSqliteHelper.getReadableDatabase().rawQuery("select * from table_records", null);        if (mEditSearch.getText().toString().equals("")) {            refreshListView();        }    }    /**     * 刷新listview     */    private void refreshListView() {        adapter.notifyDataSetChanged();        adapter.swapCursor(cursor);    }    @Override    protected void onDestroy() {        super.onDestroy();        if (db_records != null) {            db_records.close();        }        if (db_search != null) {            db_search.close();        }    }}

写在最后

第一篇技术类型博客,讲解可能不是很清楚,还存在着诸多漏洞,请多包涵。

如果你在参考过程中遇到问题,可以在我的联系方式中给我提问。

后面会继续介绍,Android的相关知识,欢迎继续关注我博客的更新

项目源代码

参考资源

  • Android搜索功能的案例,本地保存搜索历史记录

转载请注明:XueLong的博客 » Android搜索实时显示功能实现

更多相关文章

  1. Android状态保存与恢复流程 完全解析
  2. Android中保存图片的两种方式
  3. Android对View进行截图并保存到本地相册
  4. Android(安卓)SharedPreferences工具类 ,实现List/Map的保存读取
  5. Android保存位图
  6. android将InputStream转为FileOutputStream保存HttpURLConnectio
  7. pAdTy_-5 保存数据
  8. Android(安卓)开发
  9. Android(安卓)7.0拍照后保存到手机的指定目录并返回显示

随机推荐

  1. 在SQL Server数据库中为标识(IDENTITY)列
  2. Microsoft SQLServer的版本区别及选择
  3. 更改SQL Server更改当前数据库的所有者:s
  4. 设定sql server定期自动备份数据库
  5. xp_cmdshell开启与关闭
  6. 如何恢复数据库备份到一个已存在的正在使
  7. 如何强制删除或恢复SQLServer正在使用的
  8. 清除SQLServer日志的两种方法
  9. SQL Server连接失败错误及解决第1/5页
  10. 最长用最基本的MSSQL数据库备份与还原