Config
package com.tan.searchhistory.constants;
public class Config {
//数据库
public static final int DATABASE_VERSION = 1;//如果数据库升级此处需+1
public static final String DATABASE_NAME = "search.db";
public static final String DB_PATH = "/search_db";
public static final int DEFAULT_HISTORY_SEARCH_LIST_NUM = 5;
}
DatabaseContext
package com.tan.searchhistory.db;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.tan.searchhistory.constants.Config;
import java.io.File;
import java.io.IOException;
/**
* 用于支持对存储在SD卡上的数据库的访问
**/
public class DatabaseContext extends ContextWrapper {
/**
* 构造函数
* @param base 上下文环境
*/
public DatabaseContext(Context base){
super(base);
}
/**
* 获得数据库路径,如果不存在,则创建对象对象
* @param name
*/
@Override
public File getDatabasePath(String name) {
//判断是否存在sd卡
boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState());
if(!sdExist){//如果不存在,
Log.e("SD卡管理:", "SD卡不存在,请加载SD卡");
return null;
}
else{//如果存在
//获取sd卡路径
String dbDir=android.os.Environment.getExternalStorageDirectory().toString();
dbDir += Config.DB_PATH;//数据库所在目录
String dbPath = dbDir+"/"+name;//数据库路径
//判断目录是否存在,不存在则创建该目录
File dirFile = new File(dbDir);
if(!dirFile.exists())
dirFile.mkdirs();
//数据库文件是否创建成功
boolean isFileCreateSuccess = false;
//判断文件是否存在,不存在则创建该文件
File dbFile = new File(dbPath);
if(!dbFile.exists()){
try {
isFileCreateSuccess = dbFile.createNewFile();//创建文件
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
isFileCreateSuccess = true;
//返回数据库文件对象
if(isFileCreateSuccess)
return dbFile;
else
return null;
}
}
/**
* 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。
*
* @param name
* @param mode
* @param factory
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
SQLiteDatabase.CursorFactory factory) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
return result;
}
/**
* Android 4.0会调用此方法获取数据库。
*
* @see ContextWrapper#openOrCreateDatabase(String, int,
* SQLiteDatabase.CursorFactory,
* DatabaseErrorHandler)
* @param name
* @param mode
* @param factory
* @param errorHandler
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
return result;
}
}
DBHelper
package com.tan.searchhistory.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.tan.searchhistory.constants.Config;
import com.tan.searchhistory.utils.Dog;
public class DBHelper extends SQLiteOpenHelper {
private static final String TAG = DBHelper.class.getSimpleName();
private static DatabaseContext mDatabaseContext;
private static DBHelper mInstance;
private Context mContext;
/**
*
* @param context
*/
private DBHelper(Context context) {
super(context, Config.DATABASE_NAME, null, Config.DATABASE_VERSION);
this.mContext = context;
}
public static DBHelper getInstance (Context context){
if (null == mInstance){
synchronized (DBHelper.class){
if (null == mInstance){
mDatabaseContext = new DatabaseContext(context);
mInstance = new DBHelper(mDatabaseContext);
}
}
}
return mInstance;
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
Dog.d(TAG,"--onOpen---");
}
@Override
public void onCreate(SQLiteDatabase db) {
Dog.d(TAG , "---onCreate start ---");
db.execSQL(DBTable.CREATE_HISTORY);
Dog.d(TAG , "---onCreate finish---");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Dog.d(TAG , "--onUpgrade ---oldVersion=" + oldVersion + "----newVersion=" + newVersion);
}
}
DBManager
package com.tan.searchhistory.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.tan.searchhistory.models.HistoryItem;
import com.tan.searchhistory.utils.Dog;
import java.util.ArrayList;
import java.util.List;
/**
* Created by pateo on 17-12-27.
*/
public class DBManager {
protected static final String TAG = DBManager.class.getSimpleName();
private static DBManager mInstance;
private static DBHelper mDBHelper;
private static SQLiteDatabase mDB;
private DBManager(Context context){
mDBHelper = DBHelper.getInstance(context);
mDB = mDBHelper.getReadableDatabase();
}
public static DBManager getInstance(Context context){
if (null == mInstance){
synchronized (DBManager.class){
if (null == mInstance){
mInstance = new DBManager(context);
}
}
}
return mInstance;
}
//获取所有的记录列表
public List<HistoryItem> queryAllHistoryList(){
mDB = mDBHelper.getReadableDatabase();
List<HistoryItem> historyItemList = new ArrayList<HistoryItem>();
Cursor cursor = null ;
try{
cursor = mDB.query(DBTable.HISTORY_TABLE_NAME , null ,null ,null , null ,null , null);
Dog.d(TAG , "--queryAllHistoryList---cursor=" + cursor.getCount());
if (null != cursor && cursor.getCount() > 0){
cursor.moveToFirst();
do {
int id = cursor.getInt(cursor.getColumnIndex(DBTable.ID));
String name = cursor.getString(cursor.getColumnIndex(DBTable.NAME));
String createTime = cursor.getString(cursor.getColumnIndex(DBTable.CREATE_TIME));
HistoryItem historyItem = new HistoryItem( name , createTime);
Dog.d(TAG , " ---queryAllHistoryList----historyItem=" + historyItem);
historyItemList.add(historyItem);
}while (cursor.moveToNext());
}
}catch ( Exception e ){
Dog.d(TAG , "Exception=" + e.toString());
}finally {
if (null != cursor){
cursor.close();
}
closeDatabase();
}
return historyItemList;
}
//orderby 查询最新的几条数据
//查询所有数据
public static List<HistoryItem> queryLatestHistoryListByNum(int num){
mDB = mDBHelper.getReadableDatabase();
List<HistoryItem> historyItemList = new ArrayList<HistoryItem>();
Cursor cursor = null ;
try{
cursor = mDB.query(DBTable.HISTORY_TABLE_NAME , null ,null ,null,null ,null , DBTable.ID + " desc" );
Dog.d(TAG, "cursor.size ======" + cursor.getCount());
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
Dog.d(TAG , "----queryLatestHistoryListByNum----num=" + num + "----historyItemList.size()=" + historyItemList.size());
if (historyItemList.size() > num - 1){
break;
}
int id = cursor.getInt(cursor.getColumnIndex(DBTable.ID));
String name = cursor.getString(cursor.getColumnIndex(DBTable.NAME));
String createTime = cursor.getString(cursor.getColumnIndex(DBTable.CREATE_TIME));
HistoryItem historyItem = new HistoryItem( name , createTime);
Dog.d(TAG , " ---queryLatestHistoryListByNum----historyItem=" + historyItem);
historyItemList.add(historyItem);
} while (cursor.moveToNext());
}
}catch ( Exception e ){
Dog.d(TAG , "Exception=" + e.toString());
}finally {
if (null != cursor){
cursor.close();
}
closeDatabase();
}
return historyItemList;
}
//查询最新的一条数据
public HistoryItem queryLatestHistoryItem (){
HistoryItem historyItem = null ;
mDB = mDBHelper.getReadableDatabase();
Cursor cursor = null ;
try{
cursor = mDB.query(DBTable.HISTORY_TABLE_NAME , null ,null ,null , null ,null , null);
Dog.d(TAG , "--queryLatestHistoryItem---cursor=" + cursor.getCount());
if (null != cursor && cursor.getCount() > 0){
cursor.moveToLast();
int id = cursor.getInt(cursor.getColumnIndex(DBTable.ID));
String name = cursor.getString(cursor.getColumnIndex(DBTable.NAME));
String createTime = cursor.getString(cursor.getColumnIndex(DBTable.CREATE_TIME));
historyItem = new HistoryItem( name, createTime);
Dog.d(TAG , " ---queryLatestHistoryItem----historyItem=" + historyItem);
}
}catch ( Exception e ){
Dog.d(TAG , "Exception=" + e.toString());
}finally {
if (null != cursor){
cursor.close();
}
closeDatabase();
}
return historyItem;
}
//更新数据
public boolean updateHistoryItem(HistoryItem historyItem){
boolean result = false;
mDB = mDBHelper.getWritableDatabase();
if (null != historyItem){
int id = historyItem.getId();
String name = historyItem.getName();
ContentValues cValue = new ContentValues();
cValue.put(DBTable.NAME , historyItem.getName());
mDB.update(DBTable.HISTORY_TABLE_NAME , cValue , DBTable.ID + "=?" , new String[]{id + ""});
result = true;
}
return result;
}
//插入数据
public boolean insertHistoryItem (HistoryItem historyItem){
mDB = mDBHelper.getReadableDatabase();
if (null != historyItem){
//插入前应该先判断数据库是否存在
ContentValues cValue = new ContentValues();
cValue.put(DBTable.NAME , historyItem.getName());
cValue.put(DBTable.CREATE_TIME , historyItem.getCreateTime());
mDB.insert(DBTable.HISTORY_TABLE_NAME , null ,cValue);
closeDatabase();
return true;
}
closeDatabase();
return false;
}
//删除快速查询
public static boolean deleteHistory (HistoryItem historyItem){
mDB = mDBHelper.getReadableDatabase();
int result = 0;
//删除条件
String whereClause = ""+DBTable.ID+"=?";
//删除条件参数
String[] whereArgs = { historyItem.getId() + ""};
//执行删除
try {
result = mDB.delete(DBTable.HISTORY_TABLE_NAME ,whereClause,whereArgs);
Dog.d(TAG , "deleteHistory- ---result=" + result);
}catch (Exception e){
Dog.d(TAG , "deleteHistory- ---Exception=" + e.toString());
}finally {
closeDatabase();
}
if (result > 0){
return true;
}
return false;
}
//删除多个快速查询
public static boolean deleteQuickQuery( List<HistoryItem> historyItemList){
mDB = mDBHelper.getReadableDatabase();
try{
for (HistoryItem item : historyItemList){
//删除条件
String whereClause = ""+DBTable.ID+"=?";
//删除条件参数
String[] whereArgs = { item.getId() + ""};
//执行删除
mDB.delete(DBTable.HISTORY_TABLE_NAME ,whereClause,whereArgs);
}
return true;
}catch (Exception e ){
Dog.d(TAG , "deleteQuickQuery--list ---Exception=" + e.toString());
}finally {
closeDatabase();
}
return false;
}
//删除所有的数据
public static boolean deleteAllHistory (){
mDB = mDBHelper.getReadableDatabase();
try{
//执行删除
mDB.delete(DBTable.HISTORY_TABLE_NAME ,null,null);
return true;
}catch (Exception e ){
Dog.d(TAG , "deleteAllHistory--list ---Exception=" + e.toString());
}finally {
closeDatabase();
}
return false;
}
// 关闭数据库对象
public static void closeDatabase() {
if (mDB != null && mDB.isOpen()) {
mDB.close();
}
}
}
DBTable
package com.tan.searchhistory.db;
/**
* 数据库表字段
*
* @author richard.tan
*/
public class DBTable {
public static final String HISTORY_TABLE_NAME = "history";
public static final String ID = "id";
public static final String NAME = "name";
public static final String CREATE_TIME = "createTime";
public static final String CREATE_HISTORY = "create table if not exists " + HISTORY_TABLE_NAME + " ("
+ ID + " INTEGER PRIMARY KEY AUTOINCREMENT ,"
+ NAME + " text ,"
+ CREATE_TIME + " text) ";
}
HistoryItem
package com.tan.searchhistory.models;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
/**
* Created by pateo on 18-1-2.
*/
public class HistoryItem implements Serializable, Parcelable {
private static final long serialVersionUID = 1L;
//id
private int id;
//name
private String name;
//date
private String createTime;
public HistoryItem(){
}
public HistoryItem(String name, String createTime) {
this.name = name;
this.createTime = createTime;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeString(createTime);
}
public static final Parcelable.Creator<HistoryItem> CREATOR = new Creator<HistoryItem>() {
@Override
public HistoryItem createFromParcel(Parcel source) {
HistoryItem deviceCodes = new HistoryItem();
deviceCodes.id = source.readInt();
deviceCodes.name = source.readString();
deviceCodes.createTime = source.readString();
return deviceCodes;
}
@Override
public HistoryItem[] newArray(int size) {
return new HistoryItem[size];
}
};
@Override
public String toString() {
return "HistoryItem{" +
"id=" + id +
", name='" + name + '\'' +
", createTime='" + createTime + '\'' +
'}';
}
}
MainActivity
Dogpackage com.tan.searchhistory.ui;import android.content.DialogInterface;import android.os.Message;import android.service.carrier.CarrierMessagingService;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.TextUtils;import android.view.KeyEvent;import android.view.View;import android.view.inputmethod.EditorInfo;import android.widget.EditText;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.ScrollView;import android.widget.TextView;import com.tan.searchhistory.R;import com.tan.searchhistory.constants.Config;import com.tan.searchhistory.db.DBManager;import com.tan.searchhistory.models.HistoryItem;import com.tan.searchhistory.utils.Utils;import com.tan.searchhistory.view.XCFlowLayout;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private EditText vSearchEditText; private ImageView vClearEditImg; private RelativeLayout vHistoryTitleLayout; private XCFlowLayout vHistoryFlowLayout; private ImageView vDeleteHistoryView; private List<HistoryItem> mHistoryList = new ArrayList<>(); private List<String> mStrHistoryList = new ArrayList<>(); private DBManager mDBManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); initListener(); } private void initData(){ mDBManager = DBManager.getInstance(this); //数据库返回的数据是降序排列的最新的五条数据 //但是,XCFlowLayout 会传入的数据,再倒序排列展示 //所以.数据库查询到的数据,再反一次.穿个XCFlowLayout List<HistoryItem> tempHistoryList = mDBManager.queryLatestHistoryListByNum(Config.DEFAULT_HISTORY_SEARCH_LIST_NUM); for (int i = tempHistoryList.size()-1; i >= 0 ;i--){ mHistoryList.add(tempHistoryList.get(i)); } if (null != mHistoryList && mHistoryList.size() > 0){ for (HistoryItem item : mHistoryList){ mStrHistoryList.add(item.getName()); } } } private void initView(){ vSearchEditText = (EditText) findViewById(R.id.edit_text); vClearEditImg = (ImageView) findViewById(R.id.iv_clear); vHistoryTitleLayout = (RelativeLayout) findViewById(R.id.layout_history_search_title); vHistoryFlowLayout = (XCFlowLayout) findViewById(R.id.search_history_flow_view); vDeleteHistoryView = (ImageView) findViewById(R.id.search_history_clear_view); initHistoryData(); } private void initListener(){ vSearchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { if (actionId == EditorInfo.IME_ACTION_SEARCH) { Utils.hideSoftInput(vSearchEditText); if (!TextUtils.isEmpty(textView.getText().toString())){ saveHistoryData(textView.getText().toString()); } } return true; } }); //清空输入 vClearEditImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { vSearchEditText.setText(""); } }); //删除历史搜索 vDeleteHistoryView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showDeleteHistoryDialog(); } }); vHistoryFlowLayout.setOnItemClickListener(new XCFlowLayout.OnItemClickListener() { @Override public void onItemClick(View view) { if (view instanceof TextView) { String value = ((TextView) view).getText().toString(); vSearchEditText.setText(value); vSearchEditText.setSelection(value.length()); Utils.hideSoftInput(vSearchEditText); } } }); } /** * 初始化搜索历史数据 */ private void initHistoryData() { if (mStrHistoryList.size() > 0) { vHistoryTitleLayout.setVisibility(View.VISIBLE); vHistoryFlowLayout.setData(mStrHistoryList); } else { vHistoryTitleLayout.setVisibility(View.GONE); } } /** * 存储搜索历史数据 */ private void saveHistoryData(String value) { if (!mStrHistoryList.contains(value)) { long time = System.currentTimeMillis();//获取系统时间 String strTime = String.valueOf(time); HistoryItem historyItem = new HistoryItem(value ,strTime ); if (mStrHistoryList.size() < Config.DEFAULT_HISTORY_SEARCH_LIST_NUM) { mStrHistoryList.add(value); mHistoryList.add(historyItem); mDBManager.insertHistoryItem(historyItem); } else { mStrHistoryList.remove(0); mStrHistoryList.add(value); mHistoryList.remove(0); mHistoryList.add(historyItem); mDBManager.insertHistoryItem(historyItem); } //刷新列表 vHistoryFlowLayout.setData(mStrHistoryList); } vHistoryTitleLayout.setVisibility(View.VISIBLE); } private void showDeleteHistoryDialog(){ new AlertDialog.Builder(MainActivity.this) .setTitle(R.string.search_delete_history_dialog_title) .setMessage(R.string.search_delete_history_dialog_tips) .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mDBManager.deleteAllHistory();mHistoryList.clear(); mStrHistoryList.clear(); vHistoryFlowLayout.removeAllViews(); vHistoryTitleLayout.setVisibility(View.GONE);
mHistoryList.clear();
mStrHistoryList.clear();
vHistoryFlowLayout.removeAllViews();
vHistoryTitleLayout.setVisibility(View.GONE); } }).setNegativeButton(R.string.cancel, null) .show(); }}
package com.tan.searchhistory.utils;
import android.util.Log;
/**
* Created by keith on 17-8-16.
*/
public class Dog {
private static final String TAG = "search_history";
private static final boolean DEBUG = true;
public static void d(String className, String message) {
if (DEBUG) {
Log.d(TAG, '[' + className + "]:" + message);
}
}
public static void e(String className, String message) {
if (DEBUG) {
Log.e(TAG, '[' + className + "]:" + message);
}
}
public static void e(String className, String message, Throwable tr) {
if (DEBUG) {
Log.e(TAG, '[' + className + "]:" + message + "; tr:" + tr);
}
}
public static void i(String className, String message) {
if (DEBUG) {
Log.i(TAG, '[' + className + "]:" + message);
}
}
}
Utils
package com.tan.searchhistory.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import com.tan.searchhistory.MainApplication;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by pateo on 17-3-15.
*/
public class Utils {
private static final String TAG = Utils.class.getSimpleName();
/**
* 获取一个统一的路径名,以便统一清除,但项目一定要继承BaseApplication,否则将导致此方法无法正常运行
* @return 路径名
*/
public static String getPath(){
String path=null;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
path=Environment.getExternalStorageDirectory()+"/Android/data/"+ MainApplication.getInstance().getPackageName()+"/cache/";
}else{
path=MainApplication.getInstance().getCacheDir()+"";
}
return path;
}
/**
* 隐藏软键盘
* @param v
*/
public static void hideSoftInput(View v){
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive()) {
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
}
}
/**
* 显示软键盘
* @param v
*/
public static void showSoftInput(View v){
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
//如果edittext 从gone --visible 。设置获取焦点,仍不弹出键盘。去掉此处判断。强制弹出
imm.showSoftInput(v, InputMethodManager.SHOW_FORCED);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
// if (!imm.isActive()) {
// imm.showSoftInput(v, InputMethodManager.SHOW_FORCED);
// imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
// }
}
//去掉String中的所有空格
public static String removeAllSpaceInString (String str ){
return str = str.replaceAll(" " , "");
}
//格式化当前 时间为 2017/03/19, 返回String
public static String formatCurDate(){
long time=System.currentTimeMillis();//long now = android.os.SystemClock.uptimeMillis();
SimpleDateFormat format=new SimpleDateFormat("yyyy/MM/dd");
Date d1=new Date(time);
String curDate=format.format(d1);
return curDate;
}
/**
* 判断网络是否连接
*
*/
public static boolean isConnected() {
Context context = MainApplication.getInstance();// 这个context是不可能为空的,除非application停止了
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (manager == null) {
return false;
}
NetworkInfo networkinfo = manager.getActiveNetworkInfo();
return networkinfo != null && networkinfo.isAvailable();
}
/**
* 新闻列表Item 新闻发布时间 , 去掉时间,只显示日期
*
*/
public static String formatDateForNewsListItem (String date){
String strDate = "";
String [] arr = date.split("\\s+");
if (arr.length > 0){
strDate = arr[0];
}
return strDate;
}
/**
* 新闻列表 ,刷新时间 显示日期
*
*/
public static String formatDateForRefreshNewsList (String date){
String result = "";
String strDate = "";
String [] arr = date.split("\\s+");
if (arr.length > 0){
strDate = arr[0];
String [] arrDate = strDate.split("-");
for (int i = 0 ; i < arrDate.length ; i++){
if (i == arrDate.length -1){
result = result + arrDate[i];
}else {
result = result + arrDate[i] + "/";
}
}
}
return result;
}
/**
*比较两个日期的大小,日期格式为yyyy-MM-dd
*/
public static boolean isDateOneBigger(String strDate1 , String strDate2){
boolean isBigger = false;
if (TextUtils.isEmpty(strDate1) || TextUtils.isEmpty(strDate2)){
//如果有一个为空.就判断为需要更新.
isBigger = true;
return isBigger;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dt1 = null ;
Date dt2 = null ;
try{
dt1 = sdf.parse(strDate1);
dt2 = sdf.parse(strDate2);
}catch (ParseException e) {
e.printStackTrace();
Dog.d(TAG , "-isDateOneBigger--ParseException=" + e.toString());
}
if (dt1.getTime() > dt2.getTime()) {
isBigger = true;
} else if (dt1.getTime() < dt2.getTime()) {
isBigger = false;
}
return isBigger;
}
}
XCFlowLayout
package com.tan.searchhistory.view;
import android.content.Context;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.tan.searchhistory.R;
import java.util.ArrayList;
import java.util.List;
public class XCFlowLayout extends ViewGroup {
private OnItemClickListener onItemClickListener;
private TextPaint mPaint;
private Rect mRect;
private float mItemHeight;
private float mTextSize;
public XCFlowLayout(Context context) {
this(context, null);
}
public XCFlowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public XCFlowLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mItemHeight = getResources().getDimensionPixelSize(R.dimen.search_history_item_text_height);
mTextSize = getResources().getDimensionPixelSize(R.dimen.search_history_item_text_size);
mPaint = new TextPaint();
mPaint.setTextSize(mTextSize);
mRect = new Rect();
}
@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) 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);
}
//存储所有子View
private List<List<View>> mAllChildViews = new ArrayList<List<View>>();
//每一行的高度
private List<Integer> mLineHeight = new ArrayList<Integer>();
@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);
}
@Override
public void addView(View child, LayoutParams params) {
super.addView(child, params);
child.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (null != onItemClickListener) {
onItemClickListener.onItemClick(v);
}
}
});
}
public void setData(List<String> list) {
removeAllViews();
for (int i = list.size() - 1; i >= 0; i--) {
String cache = list.get(i);
TextView view = new TextView(getContext());
mPaint.getTextBounds(cache, 0, cache.length(), mRect);
MarginLayoutParams lp = new MarginLayoutParams(mRect.width() + 20 * 2, (int) mItemHeight);
lp.leftMargin = 10;
lp.rightMargin = 10;
lp.bottomMargin = 30;
//设置圆角点九背景图
view.setBackgroundResource(R.drawable.search_history_bg);
view.setTextColor(getResources().getColor(R.color.search_gray));
view.setGravity(Gravity.CENTER);
view.setTextSize(mTextSize);
view.setText(cache);
view.setTag(cache);
addView(view, lp);
}
}
public interface OnItemClickListener {
void onItemClick(View view);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
}
MainApplication
package com.tan.searchhistory;
import android.app.Application;
import com.tan.searchhistory.utils.Dog;
/**
* Created by pateo on 17-3-13.
*/
public class MainApplication extends Application{
private static final String TAG = MainApplication.class.getSimpleName();
protected static MainApplication mInstance = null;
@Override
public void onCreate() {
super.onCreate();
Dog.d(TAG , "--onCreate--");
mInstance = this;
}
public static MainApplication getInstance(){
return mInstance;
}
}