本文实例为大家分享了Android实现搜索历史的具体代码,供大家参考,具体内容如下
SharedPreferences实现本地搜索历史功能,覆盖搜索重复的文本,可清空
1. 判断搜索内容是否含表情,不需要可以不判断
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14/** * 校验字符串是否含有表情 * @param content * @return */ public static boolean hasEmoji(String content){ Pattern pattern = Pattern.compile("[ud83cudc00-ud83cudfff]|[ud83dudc00-ud83dudfff]|[u2600-u27ff]"); Matcher matcher = pattern.matcher(content); if(matcher .find()){ return true; } return false; }
2.软键盘工具类弹出、关闭,不需要可以不判断
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80public class KeyBoardUtils { /** * 打开软键盘 * * @param editText * @param context */ public static void openKeybord(EditText editText, Context context) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.RESULT_SHOWN); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); } /** * 关闭软键盘 * @param editText * @param context */ public static void closeKeybord(EditText editText, Context context) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); } /** * 判断软键盘是否显示 * @param activity * @return */ public static boolean isSoftShowing(Activity activity) { //获取当前屏幕内容的高度 int screenHeight = activity.getWindow().getDecorView().getHeight(); //获取View可见区域的bottom Rect rect = new Rect(); //DecorView即为activity的顶级view activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); //考虑到虚拟导航栏的情况(虚拟导航栏情况下:screenHeight = rect.bottom + 虚拟导航栏高度) //选取screenHeight*2/3进行判断 return screenHeight*2/3 > rect.bottom; } public static void hintKeyboard(Activity activity) { InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive() && activity.getCurrentFocus() != null) { if (activity.getCurrentFocus().getWindowToken() != null) { imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } } /** * 打开软键盘 */ public static void openKeyboard(Handler mHandler, int s, final Activity activity) { mHandler.postDelayed(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } }, s); } /** * 点击空白处关闭软键盘 */ public static void inputClose(View view, Context context) { if (view instanceof EditText) { view.clearFocus(); } try { InputMethodManager im = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); im.hideSoftInputFromWindow(view.getWindowToken(), 0); } catch (NullPointerException e) { e.printStackTrace(); } } }
3.存储工具类
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; import android.os.Build; /** * @author Administrator * SharedPreferences使用工具类 */ @TargetApi(Build.VERSION_CODES.GINGERBREAD) public class SPUtils { private static SharedPreferences sp; private static SPUtils instance = new SPUtils(); public static Context mContext; /** * 保存在手机里面的文件名 */ public static final String FILE_NAME = "maigoo"; private SPUtils() { } /** * xxx改为你想保存的sp文件名称 */ public static SPUtils getInstance(Context context) { mContext = context; if (sp == null) { sp = context.getApplicationContext().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); } return instance; } /** * 保存数据 */ public void put(String key, Object value) { if (value instanceof Integer) { sp.edit().putInt(key, (Integer) value).apply(); } else if (value instanceof String) { sp.edit().putString(key, (String) value).apply(); } else if (value instanceof Boolean) { sp.edit().putBoolean(key, (Boolean) value).apply(); } else if (value instanceof Float) { sp.edit().putFloat(key, (Float) value).apply(); } else if (value instanceof Long) { sp.edit().putLong(key, (Long) value).apply(); } } /** * 2. 读取数据 */ public int getInt(String key, int defValue) { return sp.getInt(key, defValue); } public String getString(String key, String defValue) { return sp.getString(key, defValue); } public boolean getBoolean(String key, boolean defValue) { return sp.getBoolean(key, defValue); } /** * 读取数据 * * @param key * @param defValue * @return */ public <T> T get(String key, T defValue) { T t = null; if (defValue instanceof String || defValue == null) { String value = sp.getString(key, (String) defValue); t = (T) value; } else if (defValue instanceof Integer) { Integer value = sp.getInt(key, (Integer) defValue); t = (T) value; } else if (defValue instanceof Boolean) { Boolean value = sp.getBoolean(key, (Boolean) defValue); t = (T) value; } else if (defValue instanceof Float) { Float value = sp.getFloat(key, (Float) defValue); t = (T) value; } return t; } /** * 保存搜索记录 * * @param keyword */ public void save(String keyword) { // 获取搜索框信息 SharedPreferences mysp = mContext.getSharedPreferences("search_history", 0); String old_text = mysp.getString("history", ""); // 利用StringBuilder.append新增内容,逗号便于读取内容时用逗号拆分开 StringBuilder builder = new StringBuilder(old_text); builder.append(keyword + ","); // 判断搜索内容是否已经存在于历史文件,已存在则不重复添加 if (!old_text.contains(keyword + ",")) { SharedPreferences.Editor myeditor = mysp.edit(); myeditor.putString("history", builder.toString()); myeditor.commit(); } } public String[] getHistoryList() { // 获取搜索记录文件内容 SharedPreferences sp = mContext.getSharedPreferences("search_history", 0); String history = sp.getString("history", ""); // 用逗号分割内容返回数组 String[] history_arr = history.split(","); // 保留前50条数据 if (history_arr.length > 50) { String[] newArrays = new String[50]; System.arraycopy(history_arr, 0, newArrays, 0, 50); } return history_arr; } /** * 清除搜索记录 */ public void cleanHistory() { SharedPreferences sp = mContext.getSharedPreferences("search_history", 0); SharedPreferences.Editor editor = sp.edit(); editor.clear(); editor.commit(); } }
4.Activity主要功能实现
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import kemizhibo.rhkj.com.ijkpalaydemo.search.KeyBoardUtils; import kemizhibo.rhkj.com.ijkpalaydemo.search.RegularUtils; import kemizhibo.rhkj.com.ijkpalaydemo.search.SPUtils; public class Main2Activity extends AppCompatActivity { ZFlowLayout historyFl; EditText autoSearch; Button button_search; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); historyFl = findViewById(R.id.history_fl); autoSearch=findViewById(R.id.autoSearch); button_search=findViewById(R.id.button_search); initHistory(); button_search.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (KeyBoardUtils.isSoftShowing(Main2Activity.this)) { KeyBoardUtils.hintKeyboard(Main2Activity.this); } String searchKey = autoSearch.getText().toString(); if (!isNullorEmpty(searchKey)) { if (RegularUtils.hasEmoji(autoSearch.getText().toString())) { //含有非法字符串 } else { //搜索 String keyWord = autoSearch.getText().toString(); if (!isNullorEmpty(keyWord)) { SPUtils.getInstance(Main2Activity.this).save(autoSearch.getText().toString()); } initHistory(); } } else { //搜索为空 } } }); } private boolean isNullorEmpty(String str) { return str == null || "".equals(str); } /** * 初始化 历史记录列表 */ private void initHistory() { final String[] data = SPUtils.getInstance(Main2Activity.this).getHistoryList(); ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(10, 10, 10, 10); historyFl.removeAllViews(); for (int i = 0; i < data.length; i++) { if (isNullorEmpty(data[i])) { return; } //有数据往下走 final int j = i; //添加分类块 View paramItemView = getLayoutInflater().inflate(R.layout.adapter_search_keyword, null); TextView keyWordTv = paramItemView.findViewById(R.id.tv_content); keyWordTv.setText(data[j]); historyFl.addView(paramItemView, layoutParams); keyWordTv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (KeyBoardUtils.isSoftShowing(Main2Activity.this)) { KeyBoardUtils.hintKeyboard(Main2Activity.this); } autoSearch.setText(data[j]); autoSearch.setSelection(data[j].length());//光标在最后 if (!isNullorEmpty(data[j])) { SPUtils.getInstance(Main2Activity.this).save(autoSearch.getText().toString()); } //点击事件 } }); // initautoSearch(); } } }
5.布局文件activity_main2 adapter_search_keyword
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="kemizhibo.rhkj.com.ijkpalaydemo.Main2Activity"> <Button android:id="@+id/button_search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="搜索" /> <EditText android:layout_width="match_parent" android:layout_height="40dp" android:id="@+id/autoSearch" /> <kemizhibo.rhkj.com.ijkpalaydemo.ZFlowLayout android:id="@+id/history_fl" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/title" android:orientation="vertical" /> </LinearLayout> <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tv_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_marginTop="12dp" android:background="#00f" android:paddingBottom="8dp" android:paddingLeft="12dp" android:paddingRight="12dp" android:includeFontPadding="false" android:paddingTop="8dp" android:textColor="#fff" />
6.ZFlowLayout
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; /***************************** * @Copyright(c) 2014-2018 * @Author:dengyalan * @Date:2018/1/16 * @Description:自定义搜索标签布局 * @Version:v1.0.0 *****************************/ public class ZFlowLayout extends ViewGroup { /** * 存储所有子View */ private List<List<View>> mAllChildViews = new ArrayList<>(); /** * 每一行的高度 */ private List<Integer> mLineHeight = new ArrayList<>(); public ZFlowLayout(Context context) { this(context, null); } public ZFlowLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ZFlowLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //父控件传进来的宽度和高度以及对应的测量模式 int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); //如果当前ViewGroup的宽高为wrap_content的情况 //自己测量的宽度 int width = 0; //自己测量的高度 int height = 0; //记录每一行的宽度和高度 int lineWidth = 0; int lineHeight = 0; //获取子view的个数 int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); //测量子View的宽和高 measureChild(child, widthMeasureSpec, heightMeasureSpec); //得到LayoutParams MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //子View占据的宽度 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //子View占据的高度 int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; //换行时候 if (lineWidth + childWidth > sizeWidth) { //对比得到最大的宽度 width = Math.max(width, lineWidth); //重置lineWidth lineWidth = childWidth; //记录行高 height += lineHeight; lineHeight = childHeight; } else {//不换行情况 //叠加行宽 lineWidth += childWidth; //得到最大行高 lineHeight = Math.max(lineHeight, childHeight); } //处理最后一个子View的情况 if (i == childCount - 1) { width = Math.max(width, lineWidth); height += lineHeight; } } //wrap_content setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width, modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mAllChildViews.clear(); mLineHeight.clear(); //获取当前ViewGroup的宽度 int width = getWidth(); int lineWidth = 0; int lineHeight = 0; //记录当前行的view List<View> lineViews = new ArrayList<View>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); //如果需要换行 if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width) { //记录LineHeight mLineHeight.add(lineHeight); //记录当前行的Views mAllChildViews.add(lineViews); //重置行的宽高 lineWidth = 0; lineHeight = childHeight + lp.topMargin + lp.bottomMargin; //重置view的集合 lineViews = new ArrayList(); } lineWidth += childWidth + lp.leftMargin + lp.rightMargin; lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin); lineViews.add(child); } //处理最后一行 mLineHeight.add(lineHeight); mAllChildViews.add(lineViews); //设置子View的位置 int left = 0; int top = 0; //获取行数 int lineCount = mAllChildViews.size(); for (int i = 0; i < lineCount; i++) { //当前行的views和高度 lineViews = mAllChildViews.get(i); lineHeight = mLineHeight.get(i); for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); //判断是否显示 if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int cLeft = left + lp.leftMargin; int cTop = top + lp.topMargin; int cRight = cLeft + child.getMeasuredWidth(); int cBottom = cTop + child.getMeasuredHeight(); //进行子View进行布局 child.layout(cLeft, cTop, cRight, cBottom); left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } left = 0; top += lineHeight; } } /** * 与当前ViewGroup对应的LayoutParams */ @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是机灵豌豆最近收集整理的关于Android实现搜索历史功能的全部内容,更多相关Android实现搜索历史功能内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复