Android 实现搜索历史(1)

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.存储工具类

import 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();

}

}

/**

    1. 读取数据

*/

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 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主要功能实现

import 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.xml

<?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” />

adapter_search_keyword.xml

<?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”

/>

ZFlowLayout.java

import android.content.Context;

import android.util.AttributeSet;

import android.view.View;

import android.view.ViewGroup;

import java.util.ArrayList;

import java.util.List;

/*****************************

  • @Copyright© 2014-2018

  • @Author:dengyalan

  • @Date:2018/1/16

  • @Description:自定义搜索标签布局

  • @Version:v1.0.0

*****************************/

public class ZFlowLayout extends ViewGroup {

/**

  • 存储所有子View

*/

private List<List> mAllChildViews = new ArrayList<>();

/**

  • 每一行的高度

*/

private List 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);

面试复习路线,梳理知识,提升储备

自己的知识准备得怎么样,这直接决定了你能否顺利通过一面和二面,所以在面试前来一个知识梳理,看需不需要提升自己的知识储备是很有必要的。

关于知识梳理,这里再分享一下我面试这段时间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)

  • 架构师筑基必备技能
  • Android高级UI与FrameWork源码
  • 360°全方面性能调优
  • 解读开源框架设计思想
  • NDK模块开发
  • 微信小程序
  • Hybrid 开发与Flutter

知识梳理完之后,就需要进行查漏补缺,所以针对这些知识点,我手头上也准备了不少的电子书和笔记,这些笔记将各个知识点进行了完美的总结:

Android开发七大模块核心知识笔记

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF
试这段时间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)

  • 架构师筑基必备技能
  • Android高级UI与FrameWork源码
  • 360°全方面性能调优
  • 解读开源框架设计思想
  • NDK模块开发
  • 微信小程序
  • Hybrid 开发与Flutter

[外链图片转存中…(img-SoB6oPmq-1724443170323)]

知识梳理完之后,就需要进行查漏补缺,所以针对这些知识点,我手头上也准备了不少的电子书和笔记,这些笔记将各个知识点进行了完美的总结:

[外链图片转存中…(img-9LgmCfUY-1724443170323)]

《960全网最全Android开发笔记》

[外链图片转存中…(img-BnXt0Rby-1724443170324)]

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

[外链图片转存中…(img-WEE73pmA-1724443170324)]

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值