android 利用数据库实现历史搜索记录功能
来源:互联网 发布:网络隐私权的法律规定 编辑:程序博客网 时间:2024/05/20 14:19
最近在一个项目中使用到了搜索功能,特来此记录一下
本篇博文需要用到的知识点:
1.RecyclerView的简单操作
2.本地数据库的简单操作
3.ScrollView与RecyclerView的滑动冲突解决
废话不多说,先上效果图
先看看工程界面截图
其中HistorySearchAdapter是历史记录的适配器,HistorySearchUtil是本地数据库的管理工具类
1.
<?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" tools:context="zzx.historysearch.MainActivity" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimary" android:orientation="horizontal" android:paddingTop="4dp" android:paddingLeft="6dp" android:paddingRight="6dp" android:paddingBottom="4dp"> <EditText android:id="@+id/search_edit" android:layout_width="0dp" android:layout_weight="6" android:layout_height="wrap_content" android:hint="搜索" android:textColor="#333333" android:textColorHint="#dddddd" android:textSize="15sp"/> <TextView android:id="@+id/search_tv" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:gravity="center" android:text="搜索" android:textSize="15sp" android:textColor="#ffffff" android:layout_centerVertical="true" android:layout_marginLeft="6dp"/> </LinearLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/history_search_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="历史纪录" android:textColor="#dddddd" android:textSize="13sp" android:paddingTop="8dp" android:paddingLeft="8dp" android:paddingBottom="8dp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#dddddd"/> <android.support.v7.widget.RecyclerView android:id="@+id/history_search_recycler" android:layout_width="match_parent" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> <TextView android:id="@+id/history_empty_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="清除所有历史记录" android:textColor="#dddddd" android:textSize="13sp" android:paddingTop="8dp" android:paddingBottom="8dp" android:gravity="center"/> </LinearLayout> </android.support.v4.widget.NestedScrollView></LinearLayout>这个大概看看就好,可以根据自己的喜好设计
2.history_search_item.xml历史纪录RecyclerView的单项视图
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/search_history_item_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="10dp" android:paddingLeft="10dp" android:paddingRight="4dp" android:paddingTop="10dp" android:textColor="#333333" android:textSize="17sp" /> <ImageView android:id="@+id/search_history_item_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="6dp" android:src="@mipmap/ic_delete" /> </RelativeLayout></LinearLayout>3.数据库管理工具类HistorySearchUtil.java
public class HistorySearchUtil { /** * 建表语句 */ private static final String CREATE_HISTORY_SEARCH = "create table searchHistory (" + "id integer primary key autoincrement, " + "name text)"; private final String TAG = "HistorySearchUtil"; private final String TABLE_NAME = "searchHistory"; public Context mContext; private static HistorySearchUtil mHistorySearchUtil; private MyDatabaseHelper mMyDatabaseHelper; private HistorySearchUtil(Context context) { mMyDatabaseHelper = new MyDatabaseHelper(context, "Record.db", null, 1); this.mContext = context; } public static HistorySearchUtil getInstance(Context context) {//得到一个实例 if (mHistorySearchUtil == null) { mHistorySearchUtil = new HistorySearchUtil(context); } else if ((!mHistorySearchUtil.mContext.getClass() .equals(context.getClass()))) {////判断两个context是否相同 mHistorySearchUtil = new HistorySearchUtil(context); } return mHistorySearchUtil; } /** * 添加一条新纪录 * @param name */ public void putNewSearch(String name) { SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase(); if (!isExist(name)) {//判断新纪录是否存在,不存在则添加 ContentValues values = new ContentValues(); values.put("name", name); db.insert(TABLE_NAME, null, values); } } /** * 判断记录是否存在 * @param name * @return */ public boolean isExist(String name) { SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase(); Cursor cursor = db.rawQuery("select * from " + TABLE_NAME + " where name = ?", new String[]{name}); if (cursor.moveToFirst()) {//如果存在 return true; } else { return false; } } /** * 查询所有历史纪录 * @return */ public List<String> queryHistorySearchList() { SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase(); List<String> list = new ArrayList<String>(); Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null); if (cursor.moveToFirst()) { do { String name = cursor.getString(cursor.getColumnIndex("name")); list.add(name); } while(cursor.moveToNext()); } return list; } /** * 删除单条记录 * @param name */ public void deleteHistorySearch(String name) { SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase(); if (isExist(name)) { db.delete(TABLE_NAME, "name = " + "'" + name + "'", null); } } /** * 删除所有记录 */ public void deleteAllHistorySearch() { SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase(); db.delete(TABLE_NAME, null, null); } public class MyDatabaseHelper extends SQLiteOpenHelper { public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factoty, int version) { super(context, name, factoty, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_HISTORY_SEARCH);//建表 } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } }}
其中操作比较简单,根据注释基本都能看懂4.主界面操作MainActivity.java
package zzx.historysearch;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import adapter.HistorySearchAdapter;import util.HistorySearchUtil;public class MainActivity extends AppCompatActivity { private EditText searchEdit;//搜索EditText private TextView searchTv;//搜索按钮,不过是以TextView形式 private RecyclerView histotyRecycler;//历史纪录列表 private TextView historyEmptyTv;//清空历史纪录按钮 private LinearLayout histotySearchLayout;//历史记录整个布局 private HistorySearchAdapter adapter;//适配器 private ArrayList<String> histotyList = new ArrayList<String>();//历史纪录数组 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); android.support.v7.app.ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.hide(); } initViews();//初始化组件 initHistoryRecycler();//初始化historyRecyclerView getHistoryList();//得到历史记录数组 setSearchTvListener();//设置搜索按钮监听器 setHistoryEmptyTvListener();//设置清空记录按钮监听器 } private void setHistoryEmptyTvListener() { historyEmptyTv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { HistorySearchUtil.getInstance(MainActivity.this) .deleteAllHistorySearch(); getHistoryList(); adapter.notifyDataSetChanged();//刷新列表 showViews(); } }); } private void setSearchTvListener() { searchTv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { HistorySearchUtil.getInstance(MainActivity.this) .putNewSearch(searchEdit.getText().toString());//保存记录到数据库 getHistoryList(); adapter.notifyDataSetChanged(); showViews(); Toast.makeText(MainActivity.this, "此条记录已保存到数据库", Toast.LENGTH_SHORT).show(); } }); } /** * 设置历史记录界面可见性,即记录为空时,不显示清空历史记录按钮等view */ private void showViews() { if (histotyList.size() > 0) { histotySearchLayout.setVisibility(View.VISIBLE); } else { histotySearchLayout.setVisibility(View.GONE); } } private void initHistoryRecycler() { LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); histotyRecycler.setLayoutManager(layoutManager); histotyRecycler.setNestedScrollingEnabled(false);//解决滑动冲突 adapter = new HistorySearchAdapter(this, histotyList); histotyRecycler.setAdapter(adapter); adapter.setOnItemClickListener(new HistorySearchAdapter.OnItemClickListener() { @Override public void onItemNameTvClick(View v, String name) { searchEdit.setText(name); } @Override public void onItemDeleteImgClick(View v, String name) { HistorySearchUtil.getInstance(MainActivity.this) .deleteHistorySearch(name); getHistoryList(); adapter.notifyDataSetChanged(); showViews(); } }); } private void initViews() { searchEdit = (EditText) findViewById(R.id.search_edit); searchTv = (TextView) findViewById(R.id.search_tv); historyEmptyTv = (TextView) findViewById(R.id.history_empty_tv); histotyRecycler = (RecyclerView) findViewById(R.id.history_search_recycler); histotySearchLayout = (LinearLayout) findViewById(R.id.history_search_layout); } private void getHistoryList() { histotyList.clear(); histotyList.addAll(HistorySearchUtil.getInstance(this) .queryHistorySearchList()); adapter.notifyDataSetChanged(); showViews(); }}
根据注释,应该都能看懂,值得注意的是。在本篇中解决ScrollView与RecyclerView的冲突的办法是,将ScrollView换成NestedScrollView,大家可以看看main_activity.xml里验证一下,然后在设置RecyclerView时将setNestedScrollingEnabled设置为false就可以了,即上文中的
histotyRecycler.setNestedScrollingEnabled(false);
至于NestedScrollView的其他用法,大家可以自行百度或者谷歌,这里就不展开了。5.RecyclerView适配器HistorySearchAdapter.java
public class HistorySearchAdapter extends Adapter<HistorySearchAdapter.ViewHolder> implements View.OnClickListener { private Context mContext; private OnItemClickListener mOnItemClickListener;//item点击监听接口 private List<String> histotyList = new ArrayList<String>(); public HistorySearchAdapter(Context context, List<String> histotyList) { this.mContext = context; this.histotyList = histotyList; } class ViewHolder extends RecyclerView.ViewHolder { private TextView nameTv; private ImageView deleteImg; private View itemView; public ViewHolder(View itemView) { super(itemView); nameTv = (TextView) itemView.findViewById(R.id.search_history_item_tv); deleteImg = (ImageView) itemView.findViewById(R.id.search_history_item_img); this.itemView = itemView; } } @Override public HistorySearchAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext) .inflate(R.layout.history_search_item, null); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(HistorySearchAdapter.ViewHolder holder, int position) { holder.nameTv.setText(histotyList.get(position)); holder.nameTv.setTag(histotyList.get(position)); holder.deleteImg.setTag(histotyList.get(position)); holder.nameTv.setOnClickListener(this); holder.deleteImg.setOnClickListener(this); } public void onClick(View v) { switch (v.getId()) { case R.id.search_history_item_tv://点击历史纪录名称时调用 if (mOnItemClickListener != null) { mOnItemClickListener.onItemNameTvClick(v, (String) v.getTag()); } break; case R.id.search_history_item_img://点击删除按钮时调用 if (mOnItemClickListener != null) { mOnItemClickListener.onItemDeleteImgClick(v, (String) v.getTag()); } break; default: } } /** * 设置item点击监听器 * @param listener */ public void setOnItemClickListener(OnItemClickListener listener) { this.mOnItemClickListener = listener; } @Override public int getItemCount() { return histotyList.size(); } /** * item点击接口 */ public interface OnItemClickListener { void onItemNameTvClick(View v, String name);//点击历史纪录名称时 void onItemDeleteImgClick(View v, String name);//点击删除按钮时 }}
在本适配器中采用了观察者模式,也是大众常用的一种模式,将删除按钮和历史纪录TextView的点击事件处理,交给了OnItemClickListener来处理,这样的话在MainActivity中可以很好的处理相关数据,也是代码更加规范吧。
好了,本篇博文到此也就结束了。至于item中使用的删除图片大家可以在阿里矢量库中寻找,里面非常多。
阅读全文
0 0
- android 利用数据库实现历史搜索记录功能
- 简单实现Android搜索功能 显示清除历史搜索记录
- 实现Android搜索功能 显示清除历史搜索记录
- 简单实现Android搜索功能 显示清除历史搜索记录
- jquery实现搜索框历史搜索记录功能
- Android-AutoCompleteTextView实现历史搜索记录显示
- 实现搜索的历史浏览记录,含数据库
- Android流式布局实现历史搜索记录
- JS--历史搜索记录的实现
- Android常用:手把手教你实现搜索框(含历史搜索记录)
- Android常用:手把手教你实现搜索框(含历史搜索记录)
- Android常用:手把手教你实现搜索框(含历史搜索记录)
- 微信小程序之"搜索历史"功能实现
- 【玩转SQLite系列】(六)SQLite数据库应用案例实现历史搜索记录
- 【玩转SQLite系列】(六)SQLite数据库应用案例实现历史搜索记录
- 实现搜索框(含历史搜索记录)
- 历史搜索记录保存
- localstorage历史搜索记录
- 测试websocket接口
- javaAgent简单使用
- 自然语言处理学习(三):上下文无关文法和概率上下文无关文法
- 训练总结 8.23
- 什么是ARP协议?
- android 利用数据库实现历史搜索记录功能
- XYNUOJ 1080求和
- 任务计划
- Taxi Fare
- Segmentation obtained by thresholding the UCM at certain level
- [Leetcode] 41, 75, 34
- hdu6147 模拟
- 为什么是装饰模式而不是继承
- python 程序运行时间