Demo地址:https://github.com/chaoyu168/searchHistory
效果图:
搜索界面,显示搜索历史,数据保存在本地数据库。词条维持在10条,短词条可以在三行全部显示完,多出的行数隐藏,长词条默认只显示两行,多出的部分隐藏,点击更多箭头展示全部词条,长按出现删除某个词条弹框,点击清理按钮可以清除所有历史记录。 布局使用到鸿洋大神的流式布局,GitHub地址:https://github.com/hongyangAndroid/FlowLayout
主要代码:
package com.example.searchhistory;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.zhy.view.flowlayout.FlowLayout;
import com.zhy.view.flowlayout.TagAdapter;
import com.zhy.view.flowlayout.TagFlowLayout;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity {
private RecordsDao mRecordsDao;
//默然展示词条个数
private final int DEFAULT_RECORD_NUMBER = 10;
private List recordList = new ArrayList<>();
private TagAdapter mRecordsAdapter;
@BindView(R.id.iv_back)
ImageView ivBack;
@BindView(R.id.edit_query)
EditText editText;
@BindView(R.id.iv_clear_search)
ImageView clearSearch;
@BindView(R.id.iv_search)
TextView ivSearch;
@BindView(R.id.cl_toolbar)
ConstraintLayout clToolbar;
@BindView(R.id.tv_history_hint)
TextView tvHistoryHint;
@BindView(R.id.clear_all_records)
ImageView clearAllRecords;
@BindView(R.id.fl_search_records)
TagFlowLayout tagFlowLayout;
@BindView(R.id.iv_arrow)
ImageView moreArrow;
@BindView(R.id.ll_history_content)
LinearLayout mHistoryContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//默认账号
String username = "a";
//初始化数据库
mRecordsDao = new RecordsDao(this, username);
initData();
initView();
}
private void initView() {
//创建历史标签适配器
//为标签设置对应的内容
mRecordsAdapter = new TagAdapter(recordList) {
@Override
public View getView(FlowLayout parent, int position, String s) {
TextView tv = (TextView) LayoutInflater.from(MainActivity.this).inflate(R.layout.tv_history,
tagFlowLayout, false);
//为标签设置对应的内容
tv.setText(s);
return tv;
}
};
tagFlowLayout.setAdapter(mRecordsAdapter);
tagFlowLayout.setOnTagClickListener(new TagFlowLayout.OnTagClickListener() {
@Override
public void onTagClick(View view, int position, FlowLayout parent) {
//清空editText之前的数据
editText.setText("");
//将获取到的字符串传到搜索结果界面,点击后搜索对应条目内容
editText.setText(recordList.get(position));
editText.setSelection(editText.length());
}
});
//删除某个条目
tagFlowLayout.setOnLongClickListener(new TagFlowLayout.OnLongClickListener() {
@Override
public void onLongClick(View view, final int position) {
showDialog("确定要删除该条历史记录?", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//删除某一条记录
mRecordsDao.deleteRecord(recordList.get(position));
}
});
}
});
//view加载完成时回调
tagFlowLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
boolean isOverFlow = tagFlowLayout.isOverFlow();
boolean isLimit = tagFlowLayout.isLimit();
if (isLimit && isOverFlow) {
moreArrow.setVisibility(View.VISIBLE);
} else {
moreArrow.setVisibility(View.GONE);
}
}
});
moreArrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tagFlowLayout.setLimit(false);
mRecordsAdapter.notifyDataChanged();
}
});
//清除所有记录
clearAllRecords.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog("确定要删除全部历史记录?", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tagFlowLayout.setLimit(true);
//清除所有数据
mRecordsDao.deleteUsernameAllRecords();
}
});
}
});
ivSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String record = editText.getText().toString();
if (!TextUtils.isEmpty(record)) {
//添加数据
mRecordsDao.addRecords(record);
}
}
});
clearSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//清除搜索历史
editText.setText("");
}
});
mRecordsDao.setNotifyDataChanged(new RecordsDao.NotifyDataChanged() {
@Override
public void notifyDataChanged() {
initData();
}
});
}
private void showDialog(String dialogTitle, @NonNull DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage(dialogTitle);
builder.setPositiveButton("确定", onClickListener);
builder.setNegativeButton("取消", null);
builder.create().show();
}
private void initData() {
Observable.create(new ObservableOnSubscribe>() {
@Override
public void subscribe(ObservableEmitter> emitter) throws Exception {
emitter.onNext(mRecordsDao.getRecordsByNumber(DEFAULT_RECORD_NUMBER));
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer>() {
@Override
public void accept(List s) throws Exception {
recordList.clear();
recordList = s;
if (null == recordList || recordList.size() == 0) {
mHistoryContent.setVisibility(View.GONE);
} else {
mHistoryContent.setVisibility(View.VISIBLE);
}
if (mRecordsAdapter != null) {
mRecordsAdapter.setData(recordList);
mRecordsAdapter.notifyDataChanged();
}
}
});
}
@Override
protected void onDestroy() {
mRecordsDao.closeDatabase();
mRecordsDao.removeNotifyDataChanged();
super.onDestroy();
}
}
在网上还看到通过SharedPreferences进行存储实现的:
private final static String PREFERENCE_NAME = "superservice_ly";
private final static String SEARCH_HISTORY="linya_history";
// 保存搜索记录
public static void saveSearchHistory(String inputText) {
SharedPreferences sp = App.context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
if (TextUtils.isEmpty(inputText)) {
return;
}
String longHistory = sp.getString(SEARCH_HISTORY, ""); //获取之前保存的历史记录
String[] tmpHistory = longHistory.split(","); //逗号截取 保存在数组中
List historyList = new ArrayList(Arrays.asList(tmpHistory)); //将改数组转换成ArrayList
SharedPreferences.Editor editor = sp.edit();
if (historyList.size() > 0) {
//1.移除之前重复添加的元素
for (int i = 0; i < historyList.size(); i++) {
if (inputText.equals(historyList.get(i))) {
historyList.remove(i);
break;
}
}
historyList.add(0, inputText); //将新输入的文字添加集合的第0位也就是最前面(2.倒序)
if (historyList.size() > 8) {
historyList.remove(historyList.size() - 1); //3.最多保存8条搜索记录 删除最早搜索的那一项
}
//逗号拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < historyList.size(); i++) {
sb.append(historyList.get(i) + ",");
}
//保存到sp
editor.putString(SEARCH_HISTORY, sb.toString());
editor.commit();
} else {
//之前未添加过
editor.putString(SEARCH_HISTORY, inputText + ",");
editor.commit();
}
}
//获取搜索记录
public static List getSearchHistory(){
SharedPreferences sp = App.context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
String longHistory =sp.getString(SEARCH_HISTORY, "");
String[] tmpHistory = longHistory.split(","); //split后长度为1有一个空串对象
List historyList = new ArrayList(Arrays.asList(tmpHistory));
if (historyList.size() == 1 && historyList.get(0).equals("")) { //如果没有搜索记录,split之后第0位是个空串的情况下
historyList.clear(); //清空集合,这个很关键
}
return historyList;
}