Android保存搜索历史

来源:互联网 发布:中大找面料的软件 编辑:程序博客网 时间:2024/05/21 10:16
在我项目中,有这样一个功能实现:先看图

这里写图片描述

搜索后实时将搜索内容显示到RecyclerView中,可以删除单个历史,也可以清空全部,点击其中一项显示到EditText中。将会涉及到的内容有:RecyclerView使用方法adapter接口SharedPerference我们先看一下布局:

R.layout.activity_favo_add

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    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"    android:background="@color/activity_background"    android:orientation="vertical"    tools:context="com.mymap.practice.ui.aty.favorite.FavoAddActivity">    <android.support.v7.widget.Toolbar        android:id="@+id/activity_favo_add_tb_toolbar"        style="@style/toolbar_style"        android:focusable="true"        android:focusableInTouchMode="true">        <EditText            android:id="@+id/activity_favo_add_et_search"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginRight="50dp"            android:background="@drawable/edit_backgroud"            android:drawableLeft="@mipmap/search_icon"            android:drawablePadding="@dimen/padding10"            android:hint="@string/favo_search_hint"            android:imeOptions="actionSearch"            android:maxLength="30"            android:maxLines="1"            android:padding="@dimen/padding10"            android:singleLine="true"            android:textColor="@color/ios_btntext_blue"            android:textColorHint="@color/gray"/>    </android.support.v7.widget.Toolbar>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@+id/activity_favo_add_tv_delAll"        android:layout_below="@id/activity_favo_add_tb_toolbar"        android:divider="@mipmap/input_line"        android:orientation="vertical"        android:showDividers="middle">        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginBottom="14dp"            android:layout_marginLeft="14dp"            android:layout_marginTop="14dp"            android:drawableLeft="@mipmap/search_icon"            android:drawablePadding="10dp"            android:text="@string/see_history"            android:textColor="@color/ios_btntext_blue"            android:textSize="@dimen/textSize18"/>        <android.support.v7.widget.RecyclerView            android:id="@+id/activity_favo_add_rv_list"            android:layout_width="match_parent"            android:layout_height="match_parent"/>    </LinearLayout>    <TextView        android:id="@id/activity_favo_add_tv_delAll"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        android:drawableStart="@mipmap/ic_del_all"        android:gravity="center"        android:padding="10dp"        android:text="@string/del_all"/></RelativeLayout>《!-- item布局 --》R.layout.item_favo_add<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="wrap_content"                android:gravity="center_vertical"              android:orientation="horizontal">    <TextView        android:id="@+id/item_favo_add_tv_history"        android:layout_width="0dp"        android:layout_weight="1"        android:layout_height="wrap_content"        android:padding="10dp"        android:paddingLeft="30dp"        android:textSize="@dimen/textSize18"/>    <ImageView        android:padding="10dp"        android:id="@+id/item_favo_add_iv_del"        android:src="@mipmap/ic_del_all"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>
布局很简单,接下来我们先看一下Adapter吧
    public interface FavoAddClick    {        void onItemClick(View view, int position);        void onDelClick(View view, int position);    }    public void setOnItemClickListener(FavoAddClick mOnItemClickListener)    {        this.listener = mOnItemClickListener;    }    // 删除一条    public void removeData(int position)    {        list.remove(position); // 删掉对应的数据源        notifyItemRemoved(position);        notifyItemRangeChanged(position, getItemCount()); //刷 新    }    // 清空    public void remoceAll()    {        list.clear();    }    // 添加一条数据    public void add(String item, int position)    {        list.add(position, item);        notifyItemInserted(position);    }
在接口中,定义了点击事件和删除事件。注释都写得很清楚。其他的Adapter代码:
    public FavoAddAdapter(Context context, List<String> list)    {        mInflater = LayoutInflater.from(context);        this.context = context;        this.list = list;    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)    {        MyViewHolder holder = new MyViewHolder(mInflater.inflate(                R.layout.item_favo_add, parent, false));        return holder;    }    @Override    public void onBindViewHolder(final MyViewHolder holder, final int position)    {        holder.tv_title.setText(list.get(position).toString());//为控件绑定数据        if (null != listener)        {            final int pos = holder.getLayoutPosition();            holder.itemView.setOnClickListener(new View.OnClickListener()            {                @Override                public void onClick(View v)                {                    listener.onItemClick(holder.itemView, pos);                }            });            holder.iv_del.setOnClickListener(new View.OnClickListener()            {                @Override                public void onClick(View v)                {                    listener.onDelClick(v, position);                    removeData(pos);                }            });        }    }    @Override    public int getItemCount()    {        return list == null ? 0 : list.size();    }    class MyViewHolder extends RecyclerView.ViewHolder    {        TextView tv_title;        ImageView iv_del;        public MyViewHolder(final View itemView)        {            super(itemView);            tv_title = (TextView) itemView.findViewById(R.id.item_favo_add_tv_history);            iv_del = (ImageView) itemView.findViewById(R.id.item_favo_add_iv_del);        }    }
OK,在类中,我们要在onCreate中初始化控件:    private Activity activity = FavoAddActivity.this;private SimpleDateFormat mFormat;private FavoAddAdapter mAdapter;private List<String> list; // 存放搜索内容的list
    /**     * 初始化控件     */    private void initWidget()    {        //toolbar的控件        setSupportActionBar(mToolbar);        getSupportActionBar().setDisplayShowTitleEnabled(false); // Toolbar掉标题栏        getSupportActionBar().setDisplayHomeAsUpEnabled(true); // 显示返回按钮        rv_list.setHasFixedSize(true); // 确定了RecyclerView的高度此属性会提升性能        rv_list.setLayoutManager(new LinearLayoutManager(this));        rv_list.setItemAnimator(new DefaultItemAnimator());// 设置item动画        rv_list.addItemDecoration(new DividerGridItemDecoration(this)); //分割线        showSearchHistory(); // 显示搜索历史    }
重点就是搜索历,我们先看一下搜索历史是如何显示的:
    /**     * 从SP查询搜索历史,并按时间显示     */    private void showSearchHistory()    {        Map<String, String> hisAll = (Map<String, String>) SearchHistoryUtils.getAll(activity);        //将key排序升序        Object[] keys = hisAll.keySet().toArray();        Arrays.sort(keys);        int keyLeng = keys.length;        //这里计算 如果历史记录条数是大于 可以显示的最大条数,则用最大条数做循环条件,防止历史记录条数-最大条数为负值,数组越界        int hisLeng = keyLeng > HISTORY_MAX ? HISTORY_MAX : keyLeng;        list = new ArrayList<>();        for (int i = 1; i <= hisLeng; i++)        {            list.add(hisAll.get(keys[keyLeng - i]));        }        mAdapter = new FavoAddAdapter(activity, list);        rv_list.setAdapter(mAdapter);    }
其中,SearchHistoryUtils工具实现了按时间排序显示搜索历史,支持最大搜索历史条数,接下来将取到的数据填充到Adapter中。接下来,看看监听事件:
// 搜索        et_search.setOnEditorActionListener(new TextView.OnEditorActionListener()        {            @Override            public boolean onEditorAction(TextView v, int actionId, KeyEvent event)            {                if (actionId == EditorInfo.IME_ACTION_SEARCH)                {                    // 先隐藏键盘                    KeyboardUtils.closeKeyboard(activity, et_search); // 显示键盘                    // TODO Connect Service TO Search            此处做联网搜索操作                    // 将搜索记录保存到SP中                    saveSearchHistory(et_search.getText().toString().trim());                    mAdapter.add( et_search.getText().toString() , 0 ); //插入数据源                    return true;                }                return false;            }        });// 适配器点击事件        mAdapter.setOnItemClickListener(new FavoAddAdapter.FavoAddClick()        {            @Override            public void onItemClick(View view, int position) // 单击事件            {                et_search.setText(list.get(position).toString());                et_search.requestFocus(); // 手动获得EditText焦点                KeyboardUtils.openKeyboard(activity, et_search); // 显示键盘                et_search.setSelection(list.get(position).toString().length()); // 将EditText光标移动到最后            }            @Override            public void onDelClick(View view, int position) // 删除            {                // 获取map中value对应的key,然后删除key对应的某条数据                String key = SearchHistoryUtils.valueGetKey(SearchHistoryUtils.getAll(activity), list.get(position).toString());                SearchHistoryUtils.remove(activity, key);            }        });        // 清空        tv_delAll.setOnClickListener(new View.OnClickListener()        {            @Override            public void onClick(View v)            {                clearsearchHistory();                mAdapter.remoceAll();            }        });
KeyboardUtils是写好的工具类,实现了弹出、隐藏键盘。文章末尾我将会提供下载地址。最后看一下对于map删除的操作过程:
    /**     * 将历史记录保存至sp中,key=当前时间(20160302133455,便于排序) ,value=关键字     *     * @param keyWords 搜索内容     */    private void saveSearchHistory(String keyWords)    {        //保存之前要先查询sp中是否有该value的记录,有则删除.这样保证搜索历史记录不会有重复条目        Map<String, String> historys = (Map<String, String>) SearchHistoryUtils.getAll(activity);        for (Map.Entry<String, String> entry : historys.entrySet())        {            if (keyWords.equals(entry.getValue()))            {                SearchHistoryUtils.remove(activity, entry.getKey());            }        }        mFormat = new SimpleDateFormat("yyyyMMddHHmmss");        // 以时间为key,保存搜索记录        SearchHistoryUtils.put(activity, "" + mFormat.format(new Date()), keyWords);        // 刷新适配器        mAdapter.notifyDataSetChanged();    }    /**     * 清除历史记录     */    private void clearsearchHistory()    {        SearchHistoryUtils.clear(this);        //同时刷新历史记录显示页面        mAdapter.notifyDataSetChanged();    }/*** 最后是标题栏返回按钮监听事件**/    @Override    public boolean onOptionsItemSelected(MenuItem item)    {        switch (item.getItemId())        {            case android.R.id.home:                ActivityCollector.removeActivity(this);                break;        }        return super.onOptionsItemSelected(item);    }
哦,对了,Toolbar只有在AppCompatActivity中才可以使用哦。本文使用的SearchHistoryUtils是基于某同志分享的工具类基础上加了根据value得到key的方法,被很多人转载却并没有标注作者是谁,在此对作者表示感谢。由于时间有限并没有写成Demo而是把用到的类和布局抽了出来,在此奉上

http://download.csdn.net/detail/u012552275/9695668

0 0
原创粉丝点击