Android历史搜索

又是一轮新需求,实现本地搜索,估计其实很多地方都有用到过,尤其电商类APP。作为自己亲历实现的又一功能,自己做一个小的标注。


闲话少叙,直入主题~_~ ~_~ ~_~ ~_~

需求:

1,实现搜索功能,将搜索关键词保存并展示;

2,搜索关键词输入内容无限制;

3,APP关闭重启后,历史搜索可展示;

4,历史搜索关键词重复则将其提至最开始;【去重复,占首位】


技术实现:

1,本地文件保存,使用SP,将关键词串成字符串保存;

2,分割符使用空格,在内容输入空格时,保存关键词时将空格过滤。


编码过程:

1,xml实现布局;

2,类承接获取View;

3,初始化数据,并刷新页面;

4,交互操作,保存更新数据,刷新页面;

5,异常情形考虑,细节维护。


布局文件:

<?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="match_parent"
    android:background="@color/page_bg_color"
    android:orientation="vertical">
    <!--搜索页面布局文件-->
    <!-- ***************************** title ********************************* -->

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="13dp"
            android:layout_weight="1"
            android:background="@mipmap/search_title_bg_pic"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="12dp"
                android:src="@mipmap/search_inner_pic" />

            <EditText
                android:id="@+id/search_key_words_et"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_weight="1"
                android:background="@null"
                android:hint="字体名"
                android:imeOptions="actionSearch"
                android:maxLines="1"
                android:padding="10dp"
                android:textSize="16sp" />

            <ImageView
                android:id="@+id/clear_content_iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="12dp"
                android:layout_marginRight="10dp"
                android:src="@mipmap/del_search_content_pic"
                android:visibility="invisible" />

        </LinearLayout>

        <TextView
            android:id="@+id/search_cancel_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginRight="10dp"
            android:clickable="true"
            android:text="取消"
            android:textSize="16sp" />

    </LinearLayout>
    <!-- ***************************** title ********************************* -->

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="搜索历史"
            android:textSize="15sp" />

        <ImageView
            android:id="@+id/clear_history_iv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:src="@mipmap/del_history_pic"
            android:visibility="gone" />
    </RelativeLayout>


    <ListView
        android:id="@+id/search_history_lv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:headerDividersEnabled="true"
        android:scrollbars="none" />


</LinearLayout>

代码实现:

public class MainActivity extends Activity implements View.OnClickListener {

    //=========常量================================================================
    /**
     * 搜索历史关键字
     */
    private static final String SEARCH_HISTORY_KEY = "seach_history_key";


    //==========View================================================================
    /**
     * 搜索关键字输入
     */
    private EditText searchKeyWordsET;
    /**
     * 标题栏 - 取消
     */
    private TextView topCancelTV;
    /**
     * 清除历史搜索
     */
    private ImageView clearHistoryIV;
    /**
     * 搜索历史展示
     */
    private ListView searchHistoryLV;
    /**
     * 清除输入内容
     */
    private ImageView clearContentIV;

    //=========数据================================================================
    /**
     * 搜索历史具体内容
     */
    private List<String> searchHistoryList;
    /**
     * 搜索历史适配器
     */
    private ArrayAdapter<String> adapter;
    /**
     * 已经开启了新的Activity
     */
    private boolean startedActivity = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_search);
        initView();
        initListener();
        initData();
        refreshPageView();
        showSoftInputFromWindow(MainActivity.this, searchKeyWordsET);

    }


    /**
     * 初始化页面控件
     */
    private void initView() {
        searchKeyWordsET = (EditText) findViewById(R.id.search_key_words_et);
        topCancelTV = (TextView) findViewById(R.id.search_cancel_tv);
        clearHistoryIV = (ImageView) findViewById(R.id.clear_history_iv);
        searchHistoryLV = (ListView) findViewById(R.id.search_history_lv);
        clearContentIV = (ImageView) findViewById(R.id.clear_content_iv);

        searchHistoryLV.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    }

    /**
     * 初始化监听器
     */
    private void initListener() {
        topCancelTV.setOnClickListener(this);
        clearHistoryIV.setOnClickListener(this);
        clearContentIV.setOnClickListener(this);
        searchKeyWordsET.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_SEND || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
                    /**
                     * 点击“搜索”后的处理
                     */
                    String keyWord = searchKeyWordsET.getText().toString().trim();
                    keyWord = keyWord.replace(" ", "");

                    if (!TextUtils.isEmpty(keyWord)) {//为空不处理
                        searchHistoryLV.setVisibility(View.VISIBLE);
                        clearHistoryIV.setVisibility(View.VISIBLE);
                        //去重复、保存内容、长度确认
                        /**
                         * 保存长串中出现短串  会出现异常
                         * 只能在数组中判断
                         */
                       /*
                        String historyContent = SharedPreferencesUtil.getString(ActivitySearch.this, SEARCH_HISTORY_KEY, "");
                        if (historyContent.length() > 0) {
                            if (historyContent.contains(keyWord)) {//有重复
                                String historySubContent = getSubString(historyContent, keyWord + " ");
                                SharedPreferencesUtil.putString(ActivitySearch.this, SEARCH_HISTORY_KEY, keyWord + " " + historySubContent);
                            } else {
                                SharedPreferencesUtil.putString(ActivitySearch.this, SEARCH_HISTORY_KEY, keyWord + " " + historyContent);
                            }
                        } else {//没有保存过内容
                            SharedPreferencesUtil.putString(ActivitySearch.this, SEARCH_HISTORY_KEY, keyWord + " ");
                        }
                        */
                        if (searchHistoryList == null) {
                            initData();
                        }
                        //去重复
                        Iterator<String> iterator = searchHistoryList.iterator();
                        while (iterator.hasNext()) {
                            String item = iterator.next();
                            if (keyWord.equals(item)) {
                                iterator.remove();
                            }
                        }

                        searchHistoryList.add(0, keyWord);
                        //数据量控制
                        if (searchHistoryList.size() > 5) {
                            for (int i = 4; i < searchHistoryList.size(); i++) {
                                searchHistoryList.remove(5);
                            }
                        }
                        if (adapter != null) {
                            adapter.notifyDataSetChanged();
                        } else {
                            refreshPageView();
                        }
                        /**
                         * 当前监听器会执行两次
                         */
                        if (!startedActivity) {
                            startedActivity = true;
                            startSearchResultActivity(keyWord);
                        }
                        return true;
                    } else {
                        return false;
                    }
                }
                return false;
            }
        });
        searchHistoryLV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final String keyword = searchHistoryList.get(position - 1);
                searchHistoryList.remove(position - 1);
                searchHistoryList.add(0, keyword);
                adapter.notifyDataSetChanged();
                searchKeyWordsET.setText(keyword);
                searchKeyWordsET.setSelection(keyword.length());
                startSearchResultActivity(keyword);
            }
        });

        searchKeyWordsET.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() > 0) {
                    clearContentIV.setVisibility(View.VISIBLE);
                } else {
                    clearContentIV.setVisibility(View.INVISIBLE);
                }
            }
        });
    }

    /**
     * 跳转结果页面
     *
     * @param keyWord
     */
    private void startSearchResultActivity(String keyWord) {
        if (keyWord == null || "".equalsIgnoreCase(keyWord) || keyWord.length() <= 0) {
            return;
        }
        /**
         * 跳转结果页面
         */
//        Intent intent = new Intent(MainActivity.this, ActivitySearchResult.class).putExtra("keyWord", keyWord);
//        startActivity(intent);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        searchHistoryList = new ArrayList<>();
        String historyContent = SharedPreferencesUtil.getString(MainActivity.this, SEARCH_HISTORY_KEY, "");
        if (!"".equalsIgnoreCase(historyContent)) {
            /**
             *  保存有效内容
             *  筛选掉最后保存内容有空格的情形
             *  也可以在保存内容时,最后一个值加判断条件,过滤掉空格
             */

            String[] historys = historyContent.split(" ");
            if (historys.length > 0) {
                for (int i = 0; i < historys.length; i++) {
                    String history = historys[i].trim();
                    if (history.length() > 0) {
                        searchHistoryList.add(history);
                    }
                }
            }
        }
    }

    /**
     * 刷新页面
     */
    private void refreshPageView() {
        /**
         * 筛选组合完历史消息
         */
        if (searchHistoryList != null && searchHistoryList.size() > 0) {
            searchHistoryLV.setVisibility(View.VISIBLE);
            clearHistoryIV.setVisibility(View.VISIBLE);

            adapter = new ArrayAdapter<String>
                    (MainActivity.this, R.layout.item_search_history, searchHistoryList);//item布局及内容关联??
            searchHistoryLV.setAdapter(adapter);
            adapter.notifyDataSetChanged();
        } else {
            searchHistoryLV.setVisibility(View.GONE);
            clearHistoryIV.setVisibility(View.GONE);
        }
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            /**
             * 取消
             */
            case R.id.search_cancel_tv:
                finish();//关闭当前页面
                break;
            /**
             * 清除历史
             */
            case R.id.clear_history_iv:
                SharedPreferencesUtil.putString(MainActivity.this, SEARCH_HISTORY_KEY, "");
                searchHistoryList.clear();
                adapter.notifyDataSetChanged();
                searchHistoryLV.setVisibility(View.GONE);
                clearHistoryIV.setVisibility(View.GONE);
                break;
            /**
             * 内容输入清空
             */
            case R.id.clear_content_iv:
                clearContentIV.setVisibility(View.INVISIBLE);
                searchKeyWordsET.setText("");
                break;
        }

    }


    /**
     * EditText获取焦点并显示软键盘
     */
    public void showSoftInputFromWindow(Activity activity, EditText editText) {
        editText.setFocusable(true);
        editText.setFocusableInTouchMode(true);
        editText.requestFocus();
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }


    /**
     * 字符串删除指定子串
     *
     * @param s  是需要删除某个子串的字符串 【原字符串】
     * @param s1 是需要删除的子串
     * @return
     */
    public String getSubString(String s, String s1) {
        int postion = s.indexOf(s1);
        int length = s1.length();
        int Length = s.length();
        String newString = s.substring(0, postion) + s.substring(postion + length, Length);
        return newString;//返回已经删除好的字符串
    }

    @Override
    protected void onStop() {
        super.onStop();
        /**
         * 保存历史搜索到文件
         */
        if (searchHistoryList != null && searchHistoryList.size() > 0) {
            String result = "";
            for (int i = 0; i < searchHistoryList.size(); i++) {
                result += searchHistoryList.get(i) + " ";
            }
            SharedPreferencesUtil.putString(MainActivity.this, SEARCH_HISTORY_KEY, result);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        startedActivity = false;
    }


    /**
     * 涉及点考虑:
     * 1,内容是需要能够在应用再次重启的时候展示的,需要文件化保存,选择SP,将所有内容保存成为字符串;
     * 2,分割符:表示所有符号均可以输入,只能选择其中特殊的符号,选择了空格;
     * 3,空格作为内容输入时,在保存成为单个关键词时,筛除所有空格;
     * 4,保存一个关键词,后跟一个空格,在最后一个也有,再从文件读取时,压入数组,需要做去空格处理;
     * 5,实际操作中,创建该背时,从文件加载历史;类存在过程中,一直使用数组;在离开页面时,再次保存到文件中;
     * 6,另一个思路是所有直接操作文件,使用字符串删除的指定串的方法;
     *      文件操作中不能直接用于页面渲染;
     *      存在先有长串关键词,之后有包含关系子串,筛选错误,比较多的控制;
     * 7,逻辑方面:
     *      【1】保存内容到文件;
     *      【2】去处重复考虑;
     *      【3】搜索过的内容排序到最前面;
     *      【4】历史内容保存数量限制;
     *
     * 细节处理:
     *      1,进入页面,获取焦点,软件盘弹出;---- 减少用户操作,从细节出发;
     *      2,内容输入,保留清除内容助手 X;
     *      3,EditText监听器的多次执行,使用变量控制执行次数;【管控目的页面的启动模式】
     *
     */

}


实现效果展示:




异次元传送门:

                                       异次元传送门





心灵鸡汤:偷笑


这一切点滴小事,或许好,或许差,为的就是让自己了解、认知平凡的自己和平凡的生活。也希望自己能永葆在平凡生活中活出不平凡的动力~_~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壹叁零壹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值