欢迎来到258分享网,纯净的网络源码分享基地!

258资源分享网

全部作品
全部作品
网站源码
微信源码
素材特效
源码插件
视频教程
建站学院
热门搜索: 织梦  农业种植  农业  安全设置  官方
258资源分享 > 建站学院 > 微信开发 > 微信小程序开发之带搜索记录的搜索框

推荐下载

HTML5响应式自适应网咯设计

2020-05-12   浏览:740

高端HTML5响应式企业通用网

2020-05-06   浏览:521

html5响应式外贸网站英文版

2020-05-08   浏览:510

HTML5自适应律师工作室类网

2020-04-04   浏览:504

HTML5影视传媒文化公司类网

2020-05-12   浏览:502

微信小程序开发之带搜索记录的搜索框

发布时间:2020-12-25  

前言

像下图的搜索功能在Android开发中非常常见

搜索功能

今天我将手把手教大家如何实现具备历史搜索记录的搜索框

目录

目录

1. 使用场景

在敲下代码前,理解用户的功能使用场景是非常重要的,这样有助于我们更好地去进行功能的实现,使用场景如下:

用户需要进行某类事物的搜索(通过文字输入进行精确搜索)

在搜索框输入时,通过显示搜索历史从而降低用户二次搜索的成本

简单来说,就是输入过字段会保存,当用户再次搜索该字段时,能快速帮助用户输入

2. 功能业务流程

搜索功能场景

3. 明确功能点

功能1:关键字搜索

功能2:实时显示历史搜索记录

功能3:历史搜索记录保存

功能4:将软键盘上的”回车按钮“改为”搜索按钮“

4. 涉及到的知识点

知识点

4.1 SQLite数据库的增删改查操作

在数据库建立一个叫records的表用于存储搜索历史记录 
 里面只有一列name来存储历史记录

db.execSQL("create table records(id integer primary key autoincrement,name varchar(200))");

通过插入和删除操作数据库里面的数据

通过查询操作来显示数据库里面的数据到ListView上 

已搜索的关键字再次搜索不重复添加到数据库

注:对于SQLlite数据库的操作详情请看我写的文章:Android:SQLlite数据库操作最详细解析 4.2 ListView和ScrollView的嵌套冲突

问题:ListView和ScrollView一起使用会有冲突,导致ListView显示不全

解决方案:本人采用继承ListView并重写它的onMeasure()方法来解决冲突。

至于两者的滑动冲突则暂时不需要处理(默认拉动ScrollView),这样用户就会感觉里面的搜索历史项和清空搜索记录项是在ListView里面一样,符合设计。

更多解决方法请看:ListView和ScrollView的嵌套冲突解决方案

具体代码如下:

//解决ListView和ScrollView的冲突 public class Search_Listview extends ListView { public Search_Listview(Context context) { super(context); } //通过复写其onMeasure方法、达到对ScrollView适配的效果 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }

Search_View.java

作用:用于封装搜索框功能的所有操作(涵盖历史搜索记录的插入、删除、查询和显示)

具体代码如下:

package scut.carson_ho.search_layout; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.CursorAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.SimpleCursorAdapter; import android.widget.TextView; import android.widget.Toast; /** * Created by Carson_Ho on 16/11/15. */ public class Search_View extends LinearLayout { private Context context; /*UI组件*/ private TextView tv_clear; private EditText et_search; private TextView tv_tip; private ImageView iv_search; /*列表及其适配器*/ private Search_Listview listView; private BaseAdapter adapter; /*数据库变量*/ private RecordSQLiteOpenHelper helper ; private SQLiteDatabase db; /*三个构造函数*/ //在构造函数里直接对搜索框进行初始化 - init() public Search_View(Context context) { super(context); this.context = context; init(); } public Search_View(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; init(); } public Search_View(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(); } /*初始化搜索框*/ private void init(){ //初始化UI组件 initView(); //实例化数据库SQLiteOpenHelper子类对象 helper = new RecordSQLiteOpenHelper(context); // 第一次进入时查询所有的历史记录 queryData(""); //"清空搜索历史"按钮 tv_clear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //清空数据库 deleteData(); queryData(""); } }); //搜索框的文本变化实时监听 et_search.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } //输入后调用该方法 @Override public void afterTextChanged(Editable s) { if (s.toString().trim().length() == 0) { //若搜索框为空,则模糊搜索空字符,即显示所有的搜索历史 tv_tip.setText("搜索历史"); } else { tv_tip.setText("搜索结果"); } //每次输入后都查询数据库并显示 //根据输入的值去模糊查询数据库中有没有数据 String tempName = et_search.getText().toString(); queryData(tempName); } }); // 搜索框的键盘搜索键 // 点击回调 et_search.setOnKeyListener(new View.OnKeyListener() {// 输入完后按键盘上的搜索键 // 修改回车键功能 public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) { // 隐藏键盘,这里getCurrentFocus()需要传入Activity对象,如果实际不需要的话就不用隐藏键盘了,免得传入Activity对象,这里就先不实现了 // ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow( // getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); // 按完搜索键后将当前查询的关键字保存起来,如果该关键字已经存在就不执行保存 boolean hasData = hasData(et_search.getText().toString().trim()); if (!hasData) { insertData(et_search.getText().toString().trim()); queryData(""); } //根据输入的内容模糊查询商品,并跳转到另一个界面,这个需要根据需求实现 Toast.makeText(context, "点击搜索", Toast.LENGTH_SHORT).show(); } return false; } }); //列表监听 //即当用户点击搜索历史里的字段后,会直接将结果当作搜索字段进行搜索 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //获取到用户点击列表里的文字,并自动填充到搜索框内 TextView textView = (TextView) view.findViewById(android.R.id.text1); String name = textView.getText().toString(); et_search.setText(name); Toast.makeText(context, name, Toast.LENGTH_SHORT).show(); } }); //点击搜索按钮后的事件 iv_search.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean hasData = hasData(et_search.getText().toString().trim()); if (!hasData) { insertData(et_search.getText().toString().trim()); //搜索后显示数据库里所有搜索历史是为了测试 queryData(""); } //根据输入的内容模糊查询商品,并跳转到另一个界面,这个根据需求实现 Toast.makeText(context, "clicked!", Toast.LENGTH_SHORT).show(); } }); } /** * 封装的函数 */ /*初始化组件*/ private void initView(){ LayoutInflater.from(context).inflate(R.layout.search_layout,this); et_search = (EditText) findViewById(R.id.et_search); tv_clear = (TextView) findViewById(R.id.tv_clear); tv_tip = (TextView) findViewById(R.id.tv_tip); listView = (Search_Listview) findViewById(R.id.listView); iv_search = (ImageView) findViewById(R.id.iv_search); } /*插入数据*/ private void insertData(String tempName) { db = helper.getWritableDatabase(); db.execSQL("insert into records(name) values('" + tempName + "')"); db.close(); } /*模糊查询数据 并显示在ListView列表上*/ private void queryData(String tempName) { //模糊搜索 Cursor cursor = helper.getReadableDatabase().rawQuery( "select id as _id,name from records where name like '%" + tempName + "%' order by id desc ", null); // 创建adapter适配器对象,装入模糊搜索的结果 adapter = new SimpleCursorAdapter(context, android.R.layout.simple_list_item_1, cursor, new String[] { "name" }, new int[] { android.R.id.text1 }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); // 设置适配器 listView.setAdapter(adapter); adapter.notifyDataSetChanged(); } /*检查数据库中是否已经有该条记录*/ private boolean hasData(String tempName) { //从Record这个表里找到name=tempName的id Cursor cursor = helper.getReadableDatabase().rawQuery( "select id as _id,name from records where name =?", new String[]{tempName}); //判断是否有下一个 return cursor.moveToNext(); } /*清空数据*/ private void deleteData() { db = helper.getWritableDatabase(); db.execSQL("delete from records"); db.close(); } }

search_layout.xml

作用:搜索框的布局

本文标签

: