- 数据库的增删改查操作
- ListView和ScrollView的嵌套冲突解决
- 监听软键盘回车按钮设置为搜索按钮
- 使用TextWatcher( )实时筛选
- 已搜索的关键字再次搜索不重复添加到数据库
- 刚进入页面设置软键盘不因为EditText而自动弹出
开始撸代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText searchContentEt;
private SearchRecordsAdapter recordsAdapter;
private View recordsHistoryView;
private ListView recordsListLv;
private TextView clearAllRecordsTv;
private LinearLayout searchRecordsLl;
private List searchRecordsList;
private List tempList;
private RecordsDao recordsDao;
private TextView tv_history;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
bindAdapter();
initListener();
}
private void initView() {
// setHideHeader();
initRecordsView();
searchRecordsLl = (LinearLayout) findViewById(R.id.search_content_show_ll);
searchContentEt = (EditText) findViewById(R.id.input_search_content_et);
tv_history = (TextView) findViewById(R.id.tv_history);
//添加搜索view
searchRecordsLl.addView(recordsHistoryView);
}
//初始化搜索历史记录View
private void initRecordsView() {
recordsHistoryView = LayoutInflater.from(this).inflate(R.layout.search_lishi, null);
//显示历史记录lv
recordsListLv = (ListView) recordsHistoryView.findViewById(R.id.search_records_lv);
//清除搜索历史记录
clearAllRecordsTv = (TextView) recordsHistoryView.findViewById(R.id.clear_all_records_tv);
}
private void initData() {
recordsDao = new RecordsDao(this);
searchRecordsList = new ArrayList<>();
tempList = new ArrayList<>();
tempList.addAll(recordsDao.getRecordsList());
reversedList();
//第一次进入判断数据库中是否有历史记录,没有则不显示
checkRecordsSize();
}
private void bindAdapter() {
recordsAdapter = new SearchRecordsAdapter(this, searchRecordsList);
recordsListLv.setAdapter(recordsAdapter);
}
private void initListener() {
clearAllRecordsTv.setOnClickListener(this);
searchContentEt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
if (searchContentEt.getText().toString().length() > 0) {
String record = searchContentEt.getText().toString();
//判断数据库中是否存在该记录
// if (!recordsDao.isHasRecord(record)) {
// tempList.add(record);
// }
//将搜索记录保存至数据库中
recordsDao.addRecords(record);
// reversedList();
// checkRecordsSize();
// recordsAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this, "11",Toast.LENGTH_SHORT).show();
//根据关键词去搜索
} else {
Toast.makeText(MainActivity.this, "搜索内容不能为空",Toast.LENGTH_SHORT).show();
}
}
return false;
}
});
//根据输入的信息去模糊搜索
searchContentEt.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_history.setText("搜索历史");
} else {
tv_history.setText("搜索结果");
}
String tempName = searchContentEt.getText().toString();
tempList.clear();
tempList.addAll(recordsDao.querySimlarRecord(tempName));
reversedList();
checkRecordsSize();
recordsAdapter.notifyDataSetChanged();
}
});
//历史记录点击事件
recordsListLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
//将获取到的字符串传到搜索结果界面
//点击后搜索对应条目内容
// searchContentEt.setText(searchRecordsList.get(position));
Toast.makeText(MainActivity.this,searchRecordsList.get(position)+"",Toast.LENGTH_SHORT).show();
searchContentEt.setSelection(searchContentEt.length());
}
});
}
//当没有匹配的搜索数据的时候不显示历史记录栏
private void checkRecordsSize(){
if(searchRecordsList.size() == 0){
searchRecordsLl.setVisibility(View.GONE);
}else{
searchRecordsLl.setVisibility(View.VISIBLE);
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
//清空所有历史数据
case R.id.clear_all_records_tv:
tempList.clear();
reversedList();
recordsDao.deleteAllRecords();
recordsAdapter.notifyDataSetChanged();
searchRecordsLl.setVisibility(View.GONE);
searchContentEt.setHint("请输入你要搜索的内容");
break;
}
}
//颠倒list顺序,用户输入的信息会从上依次往下显示
private void reversedList(){
searchRecordsList.clear();
for(int i = tempList.size() - 1 ; i >= 0 ; i --) {
searchRecordsList.add(tempList.get(i));
}
}
}
搜索记录操作类
public class RecordsDao {
RecordSQLiteOpenHelper recordHelper;
SQLiteDatabase recordsDb;
public RecordsDao(Context context) {
recordHelper = new RecordSQLiteOpenHelper(context);
}
//添加搜索记录
public void addRecords(String record) {
if (!isHasRecord(record)) {
recordsDb = recordHelper.getReadableDatabase();
ContentValues values = new ContentValues();
values.put("name", record);
//添加
recordsDb.insert("records", null, values);
//关闭
recordsDb.close();
}
}
//判断是否含有该搜索记录
public boolean isHasRecord(String record) {
boolean isHasRecord = false;
recordsDb = recordHelper.getReadableDatabase();
Cursor cursor = recordsDb.query("records", null, null, null, null, null, null);
while (cursor.moveToNext()) {
if (record.equals(cursor.getString(cursor.getColumnIndexOrThrow("name")))) {
isHasRecord = true;
}
}
//关闭数据库
recordsDb.close();
cursor.close();
return isHasRecord;
}
//获取全部搜索记录
public List getRecordsList() {
List recordsList = new ArrayList<>();
recordsDb = recordHelper.getReadableDatabase();
Cursor cursor = recordsDb.query("records", null, null, null, null, null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
recordsList.add(name);
}
//关闭数据库
recordsDb.close();
cursor.close();
return recordsList;
}
//模糊查询
public List querySimlarRecord(String record){
String queryStr = "select * from records where name like '%" + record + "%' order by name ";
List similarRecords = new ArrayList<>();
Cursor cursor= recordHelper.getReadableDatabase().rawQuery(queryStr,null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
similarRecords.add(name);
}
cursor.close();
return similarRecords;
}
//清空搜索记录
public void deleteAllRecords() {
recordsDb = recordHelper.getWritableDatabase();
recordsDb.execSQL("delete from records");
recordsDb.close();
}
// 删除
public int delete(int _id) {
SQLiteDatabase db = recordHelper.getWritableDatabase();
int d = db.delete("records", "_id=?", new String[] { _id + "" });
db.close();
return d;
}
}
搜索记录帮助类
ublic class RecordSQLiteOpenHelper extends SQLiteOpenHelper {
private final static String DB_NAME = "temp.db";
private final static int DB_VERSION = 1;
public RecordSQLiteOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sqlStr = "CREATE TABLE IF NOT EXISTS records (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);";
db.execSQL(sqlStr);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public class SearchRecordsAdapter extends BaseAdapter {
private Context mContext;
private List mSearchList;
private LayoutInflater mInflater;
private int itemCount = SEARCH_RECORD_COUNT;
public SearchRecordsAdapter(Context context, List searchRecordsList) {
this.mContext = context;
this.mSearchList = searchRecordsList;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
if (mSearchList.size() > SEARCH_RECORD_COUNT) {
return itemCount;
} else {
return mSearchList.size();
}
}
@Override
public Object getItem(int position) {
return mSearchList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item, null);
viewHolder.recordTv = convertView.findViewById(R.id.search_content_tv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
String count = mSearchList.get(position);
viewHolder.recordTv.setText(count);
return convertView;
}
private class ViewHolder {
TextView recordTv;
}
/**
* 点击后设置Item的数量
*
* @param number Item的数量
*/
public void addItemNum(int number) {
itemCount = number;
}
public class ClearEditText extends AppCompatEditText implements View.OnFocusChangeListener,TextWatcher {
/**
* 删除按钮的引用
*/
private Drawable mClearDrawable ;
/**
* 控件是否有焦点
*/
private boolean hasFoucs;
public ClearEditText(Context context) {
this(context, null);
}
public ClearEditText(Context context, AttributeSet attrs) {
//这里构造方法也很重要,不加这个很多属性不能再XML里面定义
this(context, attrs, android.R.attr.editTextStyle );
}
public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
mClearDrawable = getCompoundDrawables()[2];
if ( mClearDrawable == null ) {
//throw new NullPointerException("You can add drawableRight attribute in XML");
mClearDrawable = getResources().getDrawable(R.drawable.delete_selector);
}
mClearDrawable.setBounds( 0 , 0, mClearDrawable.getIntrinsicWidth() , mClearDrawable.getIntrinsicHeight());
//默认设置隐藏图标
setClearIconVisible(false);
//设置焦点改变的监听
setOnFocusChangeListener(this);
//设置输入框里面内容发生改变的监听
addTextChangedListener(this);
}
/**
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
* 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
*
* getWidth() - getTotalPaddingRight()表示:
* 控件左边到clean的图标左边缘的区域
*
* getWidth() - getPaddingRight()表示:
* 控件左边到clean的图标右边缘的区域
*
* 所以这两者之间的区域刚好是clean的图标的区域
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (getCompoundDrawables()[2] != null) {
boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
&& (event.getX() < ((getWidth() - getPaddingRight())));
if (touchable) { //点击清除图标
this.setText( "" ) ;
}
}
}
return super.onTouchEvent(event) ;
}
/**
* 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
this.hasFoucs = hasFocus;
if (hasFocus) {
setClearIconVisible(getText().length() > 0);
} else {
setClearIconVisible(false);
}
}
/**
* 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
* @param visible
*/
protected void setClearIconVisible(boolean visible) {
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}
/**
* 当输入框里面内容发生变化的时候回调的方法
*/
@Override
public void onTextChanged(CharSequence s, int start, int count,
int after) {
if(hasFoucs){
setClearIconVisible(s.length() > 0);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
/**
* 设置晃动动画
*/
public void setShakeAnimation(){
this.startAnimation( shakeAnimation( 5 ) );
}
/**
* 晃动动画
* @param counts 1秒钟晃动多少下
* @return
*/
public static Animation shakeAnimation(int counts){
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration( 1000 );
return translateAnimation;
}
}
布局文件
适配器布局
搜索布局
源码地址:https://download.csdn.net/download/qq_38875767/10906365