Android 显示历史搜索记录
网上有许多这方面的教程,思来想去还是决定写下我自己的代码,为了方便以后复习查看。
先看效果图:
实现如下功能
1、数据库的增删改查操作
2、已搜索的关键字再次搜索不会重复添加到数据库
3、点击的记录可添加到搜索框里
XML布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical"
tools:context=".SearchActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/search_et_search"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_marginRight="2dp"
android:background="@drawable/et_style_search"
android:hint=" 搜索 "
android:drawableLeft="@drawable/search"
android:paddingLeft="5dp"
android:singleLine="true"
android:layout_weight="1"
/>
<ImageView
android:id="@+id/voice_iv"
android:layout_width="25dp"
android:layout_height="30dp"
android:src="@drawable/voice"
android:layout_gravity="center"
android:layout_marginRight="5dp"
/>
<TextView
android:id="@+id/cancel_tv_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="取消"
android:textSize="20sp"
android:textColor="#257bf4"
/>
</LinearLayout>
<ListView
android:id="@+id/search_record_iv"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<View
android:layout_width="match_parent"
android:layout_height="0.05dp"
android:background="#4a949393"/>
<TextView
android:id="@+id/clearReocrds_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textAlignment="center"
android:visibility="gone"
android:text="清除历史记录"
android:textSize="12sp" />
</LinearLayout>
创建listview_item.xml文件
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<ImageView
android:id="@+id/search_record_image_iv"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/record"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
/>
<TextView
android:id="@+id/search_content_tv"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_margin="10dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
</LinearLayout>
Java代码
1、
public class RecordsSQLiteOpenHelper extends SQLiteOpenHelper {
//声明一个代表数据库名称的字符串
private final static String DB_NAME = "MyRecords.db";
//声明一个代表数据库版本的整形变量
private static int DB_VERSION = 1;
public RecordsSQLiteOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//建立records表格
String sql = "CREATE TABLE IF NOT EXISTS records (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
}
2、继承ArrayAdapter类,编写RecordsAdapter适配器类
public class RecordsAdapter extends ArrayAdapter {
//定义一个整型,记录‘显示记录的文本’的id
private int resourceId;
public RecordsAdapter(@NonNull Context context, int resource, @NonNull List<String> objects) {
super(context, resource, objects);
resourceId = resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = LayoutInflater.from(getContext()).inflate(resourceId,null); //实例化一个对象
TextView showRecord = (TextView)view.findViewById(R.id.search_content_tv);
String record = (String)getItem(position); //获取当前的记录字符串
showRecord.setText(record);
return view;
}
}
3、编写搜索记录操作类
/**
* 搜索记录操作类
* 用于封装度对搜索记录的各种操作
*/
public class RecordsDao {
RecordsSQLiteOpenHelper recordHelper; //定义一个数据库的操作帮助对象
SQLiteDatabase recordDb; //定义一个记录的数据库对象
public RecordsDao(Context context){
recordHelper = new RecordsSQLiteOpenHelper(context);
}
/**
* 该函数用于添加搜索记录
*/
public void addRecords(String record){
if (!isHasRecord(record)){ //判断源数据中是否已有该记录
recordDb = recordHelper.getWritableDatabase(); //获取搜索记录数据库
ContentValues value = new ContentValues();
value.put("name",record);
recordDb.insert("records",null,value); //插入记录
recordDb.close();
}
}
/**
* 该函数用于获取全部搜索记录
* @return List<String>
*/
public List<String> getRecordsList(){
List<String> recordsList = new ArrayList<String>();
recordDb = recordHelper.getReadableDatabase();
Cursor cursor = recordDb.query("records",null,null,null,null,null,null);
while (cursor.moveToNext()){
String record = cursor.getString(cursor.getColumnIndexOrThrow("name"));
recordsList.add(record);
}
recordDb.close();
cursor.close();
return recordsList;
}
/**
* 该函数用于清空搜索记录
*/
public void clearRecords(){
String sql = "delete from records";
recordDb = recordHelper.getWritableDatabase();
recordDb.execSQL(sql);
recordDb.close();
}
/**
* 该函数用于模糊查询
*/
public List<String> querySimilarRecords(String record){
String sql = "select * from records where name like'%" + record + "%' order by name";
// String queryStr = "select * from records where name like '%" + record + "%' order by name ";
List<String> similarRecordsList = new ArrayList<String>();
recordDb = recordHelper.getReadableDatabase();
Cursor cursor = recordDb.rawQuery(sql,null);
while (cursor.moveToNext()){
String myRecord = cursor.getString(cursor.getColumnIndexOrThrow("name"));
similarRecordsList.add(myRecord);
}
recordDb.close();
cursor.close();
return similarRecordsList;
}
/**
* 该函数用于判断原数据库中是否已有该记录
* @return 有记录返回true
*/
private boolean isHasRecord(String record){
boolean isHasRecord = false;
recordDb = recordHelper.getReadableDatabase();
Cursor cursor = recordDb.query("records",null,null,null,null,null,null);
while (cursor.moveToNext()){
if (record.equals(cursor.getString(cursor.getColumnIndexOrThrow("name")))){
isHasRecord = true;
break;
}
}
recordDb.close();
cursor.close();
return isHasRecord;
}
}
4、接下来是在MainActivity里的代码了,我是在我练习的一个项目里实现了这部分功能,代码多而杂。下面是关键性代码
recordsDao = new RecordsDao(SearchActivity.this);
/**
* 绑定适配器
*/
void bindAdapter(){
recordsList = recordsDao.getRecordsList(); //获取搜索记录的数组
reversedRecords();
ckeckRecords(); //检查是否有记录
recordsAdapter = new RecordsAdapter(SearchActivity.this,R.layout.listview_item,recordsList);
records_lv.setAdapter(recordsAdapter);
}
/**
* 该函数用于反转搜索记录
*/
private void reversedRecords(){
String temp = "";
int size = (recordsList.size())/2;
int foot = recordsList.size()-1;
//下面的循环实现数组首尾置换
for (int i=0;i<size;i++){
foot = foot - i;
temp = recordsList.get(i);
recordsList.set(i,recordsList.get(foot));
recordsList.set(foot,temp);
}
}
/**
* 创建一个“历史记录”列表的监听器对象
* 点击记录,可把该记录添加到搜索框里
*/
AdapterView.OnItemClickListener lvListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String myClicked = recordsList.get(position);
search_et.setText(myClicked);
}
};
/**
* 创建一个“清除历史记录”的监听器对象
*/
View.OnClickListener clearListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
recordsList.clear();
recordsDao.clearRecords();
recordsAdapter.notifyDataSetChanged();
ckeckRecords();
}
};
上面的代码有许多细节没有放出来。还有一些功能没有实现,比如:监听软键盘回车按钮设置为搜索按钮、 使用TextWatcher( )进行实时筛选 等
更详细的代码参考这两位大神的文章
Android—— ListView 的简单用法及定制ListView界面
简单实现Android搜索功能 显示清除历史搜索记录