热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android实现搜索历史(1),android开发框架qmui

**xxx改为你想保存的sp文件名称*publicstaticSPUtilsgetInstance(Contextcontext){mContextcontext;if(

/**

  • 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

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

android:orientation=“vertical”

xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“h
ttp://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

tools:context=“kemizhibo.rhkj.com.ijkpalaydemo.Main2Activity”>

android:id="@+id/button_search"

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“搜索”

/>

android:layout_width=“match_parent”

android:layout_height=“40dp”

android:id="@+id/autoSearch"

/>

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

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 mAllChildViews &#61; new ArrayList<>();

/**

  • 每一行的高度

*/

private List mLineHeight &#61; 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);

}

&#64;Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

//父控件传进来的宽度和高度以及对应的测量模式

int sizeWidth &#61; MeasureSpec.getSize(widthMeasureSpec);

int modeWidth &#61; MeasureSpec.getMode(widthMeasureSpec);

int sizeHeight &#61; MeasureSpec.getSize(heightMeasureSpec);

int modeHeight &#61; MeasureSpec.getMode(heightMeasureSpec);

//如果当前ViewGroup的宽高为wrap_content的情况

//自己测量的宽度

int width &#61; 0;

//自己测量的高度

int height &#61; 0;

//记录每一行的宽度和高度

int lineWidth &#61; 0;

int lineHeight &#61; 0;

//获取子view的个数

int childCount &#61; getChildCount();

for (int i &#61; 0; i

View child &#61; getChildAt(i);

//测量子View的宽和高

measureChild(child, widthMeasureSpec, heightMeasureSpec);

//得到LayoutParams

MarginLayoutParams lp &#61; (MarginLayoutParams) child.getLayoutParams();

//子View占据的宽度

int childWidth &#61; child.getMeasuredWidth() &#43; lp.leftMargin &#43; lp.rightMargin;

//子View占据的高度

int childHeight &#61; child.getMeasuredHeight() &#43; lp.topMargin &#43; lp.bottomMargin;

//换行时候

if (lineWidth &#43; childWidth > sizeWidth) {

//对比得到最大的宽度
ntent的情况

//自己测量的宽度

int width &#61; 0;

//自己测量的高度

int height &#61; 0;

//记录每一行的宽度和高度

int lineWidth &#61; 0;

int lineHeight &#61; 0;

//获取子view的个数

int childCount &#61; getChildCount();

for (int i &#61; 0; i

View child &#61; getChildAt(i);

//测量子View的宽和高

measureChild(child, widthMeasureSpec, heightMeasureSpec);

//得到LayoutParams

MarginLayoutParams lp &#61; (MarginLayoutParams) child.getLayoutParams();

//子View占据的宽度

int childWidth &#61; child.getMeasuredWidth() &#43; lp.leftMargin &#43; lp.rightMargin;

//子View占据的高度

int childHeight &#61; child.getMeasuredHeight() &#43; lp.topMargin &#43; lp.bottomMargin;

//换行时候

if (lineWidth &#43; childWidth > sizeWidth) {

//对比得到最大的宽度


推荐阅读
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 在探讨如何在Android的TextView中实现多彩文字与多样化字体效果时,本文提供了一种不依赖HTML技术的解决方案。通过使用SpannableString和相关的Span类,开发者可以轻松地为文本添加丰富的样式和颜色,从而提升用户体验。文章详细介绍了实现过程中的关键步骤和技术细节,帮助开发者快速掌握这一技巧。 ... [详细]
  • 在 iOS 开发中,内存管理是一个至关重要的环节。初学者常常因为内存管理不当导致程序崩溃。本文将详细介绍 iOS 中内存的分配与释放机制,并提供一些实用的技巧。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • ARM汇编基础基于Keil创建STM32汇编程序的编写
    文章目录一、新建项目(1)工具介绍(2)创建项目:二、配置环境(1)配置芯片&#x ... [详细]
  • 本文详细解析了Autofac在高级应用场景中的具体实现,特别是如何通过注册泛型接口的类来优化依赖注入。示例代码展示了如何使用 `builder.RegisterAssemblyTypes` 方法,结合 `typeof(IEventHandler).Assembly` 和 `Where` 过滤条件,动态注册所有符合条件的类,从而简化配置并提高代码的可维护性。此外,文章还探讨了这一方法在复杂系统中的实际应用及其优势。 ... [详细]
author-avatar
孙俊啟66864
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有