安卓進階系列-02搜索框(PersistentSearch)的使用

這篇文章主要介紹安卓開發中常用的搜索框控件的使用。

爲第三方控件,需要添加依賴如下。

'com.quinny898.library.persistentsearch:library:1.1.0-SNAPSHOT'

同時因爲gradle默認倉庫爲jcenter,所以build一定會報錯。需要在另一個gradle腳本添加倉庫。(不是App的而是Project的build.gradle)

1.佈局使用

只要在主佈局中添加該空間即可。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    tools:context="com.zc.test.MainActivity"
    android:orientation="vertical">
    <com.quinny898.library.persistentsearch.SearchBox
        android:layout_width="wrap_content"
        android:id="@+id/searchbox"
        android:layout_height="wrap_content"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >
        <ListView
            android:id="@+id/lv_history"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginBottom="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </ListView>
    </LinearLayout>
    <ListView
        android:id="@+id/lv_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
    <TextView
        android:id="@+id/tv_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:gravity="center_horizontal"
        />
</LinearLayout>

2.代碼實現

package com.zc.test;

/**
 * Created by 16957 on 2018/11/18.
 */

import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

import com.quinny898.library.persistentsearch.SearchBox;
import com.quinny898.library.persistentsearch.SearchResult;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    //上下文
    private Context mContext;
    //搜索框控件,可以自定義style
    private SearchBox sbSearch;
    //底部結果統計控件
    private TextView tvBottom;
    //數據列表
    private List<String> listSearch;
    //結果列表
    private List<String> listResult;

    //歷史列表控件
    private ListView mHistory ;
    //搜索結果列表控件
    private ListView mSearchResult ;
    //底部結果控件
    private TextView bottom;
    //兩個繼承BaseAdapter的適配器,搜索歷史sf本地保存
    private SearchAdapter mResultAdapter ;
    private HistoryAdapter mHistoryAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        bindViews();
    }

    @Override
    protected void onResume() {
        super.onResume();
        initData();
        init();
        initHistory();
        updateBottom();
    }

    private void initData() {
        //本地可供檢索數據獲取,每次resume就要重新渲染
        listSearch = new ArrayList<>();
        listSearch.add("123");
        listSearch.add("1234");
        listSearch.add("12345");
    }

    private void bindViews() {
        mSearchResult = (ListView) findViewById(R.id.lv_content);
        sbSearch = (SearchBox) findViewById(R.id.searchbox);
        tvBottom = (TextView) findViewById(R.id.tv_bottom);
        mHistory = (ListView) findViewById(R.id.lv_history);
        bottom = (TextView) findViewById(R.id.tv_bottom);
    }

    public void init(){
        //結果的初始化
        listResult = new ArrayList<>();
        mResultAdapter = new SearchAdapter(MainActivity.this, listResult);
        mSearchResult.setAdapter(mResultAdapter);
        mSearchResult.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            }
        });

        //搜索框的初始化
        sbSearch.enableVoiceRecognition(this);
        sbSearch.setMenuListener(new SearchBox.MenuListener(){
            @Override
            public void onMenuClick() {
                finish();
            }
        });
        sbSearch.setSearchListener(new SearchBox.SearchListener(){

            @Override
            public void onSearchOpened() {
                //Use this to tint the screen
            }
            @Override
            public void onSearchClosed() {
                //Use this to un-tint the screen
            }
            @Override
            public void onSearchTermChanged(String term) {
                //搜索框內容修改就進行搜索,但只要點擊搜索按鈕纔會加入搜索歷史
                search(term);
                updateBottom();
                if(listResult.size()==0){
                    mHistory.setVisibility(View.VISIBLE);
                }else {
                    mHistory.setVisibility(View.GONE);
                }
            }
            @Override
            public void onSearch(String searchTerm) {
                search(searchTerm);
                saveHistory(searchTerm);
                initHistory();
                updateBottom();
            }
            @Override
            public void onResultClick(SearchResult result) {
                //React to a result being clicked
            }
            @Override
            public void onSearchCleared() {
                //Called when the clear button is clicked
            }

        });
    }

    private void initHistory(){
        final List<String> history = getHistory();
        mHistoryAdapter = new HistoryAdapter(MainActivity.this,history);
        mHistory.setAdapter(mHistoryAdapter);
        mHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                sbSearch.populateEditText(history.get(position));
                sbSearch.setSearchString(history.get(position));
            }
        });

    }

    private void search(String newText){
        //若搜索內容爲空
        if(newText.isEmpty()){
            listResult.clear();
        }
        else{
            for (String node : listSearch) {
                //在數據集遍歷搜索
                if (node.contains(newText)) {
                    if(listResult.indexOf(node)==-1) {
                        //如果結果集不含有它(爲了防止結果重複)
                        listResult.add(node);
                    }
                }else{
                    //搜索內容搜索不到相關 檢測是否之前有加入結果集 有則刪除
                    if(listResult.indexOf(node)!=-1) {
                        listResult.remove(node);
                    }
                }
            }
        }
        mResultAdapter.notifyDataSetChanged();
    }



    private ArrayList<String> getHistory() {
        SharedPreferences reader = getSharedPreferences("history", MODE_PRIVATE);
        String data = reader.getString("data_history", "");
        ArrayList<String> history = new ArrayList<>();
        String [] get=  data.split("\\|");
        for( String str:get){
            if(! history.contains(str) && !str.isEmpty()){
                history.add(str);
            }
        }
        return history;
    }

    private void saveHistory(String s){
        StringBuilder sb = new StringBuilder();
        SharedPreferences.Editor editor = getSharedPreferences("history",MODE_PRIVATE).edit();
        for (String str: getHistory()){
            sb.append(str);
            sb.append("|");
        }
        sb.append(s);
        editor.putString("data_history",sb.toString());
        editor.apply();
    }


    private void updateBottom(){
        if(sbSearch.getSearchText().trim().isEmpty()){
            bottom.setVisibility(View.GONE);
            return;
        }
        tvBottom.setVisibility(View.VISIBLE);
        tvBottom.setText("找到了 "+ listResult.size() +" 條記錄");

    }

    
}

3.效果演示

這個項目只是個測試代碼,所以組件渲染和事件處理是存在很多bug的,歡迎指正。

項目github地址:https://github.com/luanshiyinyang/TestForPersistentSearch

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章