Android自定義View實(shí)現(xiàn)搜索框(SearchView)功能

概述

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、虛擬主機(jī)、營銷軟件、網(wǎng)站建設(shè)、新昌網(wǎng)站維護(hù)、網(wǎng)站推廣。

在Android開發(fā)中,當(dāng)系統(tǒng)數(shù)據(jù)項(xiàng)比較多時(shí),常常會(huì)在app添加搜索功能,方便用戶能快速獲得需要的數(shù)據(jù)。搜索欄對于我們并不陌生,在許多app都能見到它,比如豌豆莢

Android自定義View實(shí)現(xiàn)搜索框(SearchView)功能

在某些情況下,我們希望我們的自動(dòng)補(bǔ)全信息可以不只是純文本,還可以像豌豆莢這樣,能顯示相應(yīng)的圖片和其他數(shù)據(jù)信息,因此Android給我們提供的AutoCompleteTextView往往就不夠用,在大多情況下我們都需要自己去實(shí)現(xiàn)搜索框。

分析

根據(jù)上面這張圖,簡單分析一下自定義搜索框的結(jié)構(gòu)與功能,有
1. 搜索界面大致由三部門組成,如圖:輸入框+(自動(dòng)補(bǔ)全)提示框+結(jié)果列表。
2. 提示框的數(shù)據(jù)與輸入框輸入的文本是實(shí)時(shí)聯(lián)動(dòng)的,而結(jié)果列表只有在每次進(jìn)行搜索操作時(shí)才會(huì)更新數(shù)據(jù)

3. 輸入框的UI應(yīng)是動(dòng)態(tài)的,即UI隨著輸入的文本的改變而改變,如:在未輸入文本時(shí),清除按鈕Android自定義View實(shí)現(xiàn)搜索框(SearchView)功能應(yīng)該是隱藏的;只有當(dāng)框中有文本時(shí)才會(huì)顯示。
4. 軟鍵盤也應(yīng)該是動(dòng)態(tài)的,如完成搜索時(shí)應(yīng)自動(dòng)隱藏。
5. 選擇提示框的選項(xiàng)會(huì)自動(dòng)補(bǔ)全輸入框,且自動(dòng)進(jìn)行搜索
6. (external)有熱門搜索推薦/記錄搜索記錄的功能——熱門搜索推薦列表只在剛要進(jìn)行搜索的時(shí)候彈出,即未輸入文本時(shí),可供用戶選擇。

根據(jù)上面的分析,我們認(rèn)為一個(gè)搜索框應(yīng)該包含輸入框和提示框兩個(gè)部分。搜索框可以設(shè)置一個(gè)回調(diào)監(jiān)聽接口,當(dāng)需要進(jìn)行搜索操作時(shí),調(diào)用監(jiān)聽者的search()方法,從而實(shí)現(xiàn)具體的搜索操作以及結(jié)果列表的數(shù)據(jù)聯(lián)動(dòng)。

演示Demo

Android自定義View實(shí)現(xiàn)搜索框(SearchView)功能

注意:

1. 這里,博主圖方便沒有模擬太多數(shù)據(jù),而且提示框和熱搜列表也都只是使用String類型的數(shù)據(jù),各位看官們可以根據(jù)自身需要去設(shè)置item_layout和相應(yīng)的adapter。
2. 由于個(gè)人習(xí)慣,博主在這個(gè)demo中使用了通用適配器,所以生成和設(shè)置adapter的代碼比較簡略,看官們可以根據(jù)傳統(tǒng)的ViewHolder模式打造自己的adapter。或者學(xué)習(xí)一下通用適配器的打造。可以參考這里(鴻神博客Again)學(xué)習(xí)一下通用適配器的打造,在我的源碼里面也有對應(yīng)的源碼。

實(shí)現(xiàn)

好了,說了那么多,開始來看代碼吧

先看SearchView的布局文件 search_layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:background="#eee" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"> 
 
  <LinearLayout 
    android:background="#eb4f38" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 
 
 
    <FrameLayout 
 
      android:layout_weight="1" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content"> 
 
      <EditText 
        android:id="@+id/search_et_input" 
        android:layout_gravity="center_vertical" 
        android:layout_margin="10dp" 
        android:drawableLeft="@drawable/search_icon" 
        android:drawablePadding="5dp" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:background="@drawable/search_edittext_shape" 
        android:textSize="16sp" 
        android:imeOptions="actionSearch" 
        android:inputType="text" 
        android:hint="請輸入關(guān)鍵字"/> 
 
      <ImageView 
        android:visibility="gone" 
        android:layout_marginRight="20dp" 
        android:src="@drawable/iv_delete_bg" 
        android:id="@+id/search_iv_delete" 
        android:layout_gravity="right|center_vertical" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"/> 
    </FrameLayout> 
 
    <Button 
      android:id="@+id/search_btn_back" 
      android:layout_marginRight="10dp" 
      android:layout_marginTop="10dp" 
      android:layout_marginBottom="10dp" 
      android:layout_gravity="center_vertical" 
      android:background="@drawable/btn_search_bg" 
      android:layout_width="@dimen/btn_width" 
      android:layout_height="@dimen/btn_height" 
      android:text="返回" 
      android:textColor="@color/color_white"/> 
  </LinearLayout> 
 
  <ListView 
    android:visibility="gone" 
    android:id="@+id/search_lv_tips" 
    android:background="@drawable/lv_search_tips_bg" 
    android:layout_marginLeft="20dp" 
    android:layout_marginRight="20dp" 
    android:layout_marginBottom="10dp" 
    android:layout_width="match_parent" 
    android:layout_height="200dp"> 
  </ListView> 
</LinearLayout> 

注意:demo中顏色什么的都直接用的rgb 值去設(shè)置,在實(shí)際開發(fā)時(shí),需要把它們都統(tǒng)一管理到values目錄下 。

比較簡單,需要注意的是EditText的這個(gè)屬性

android:imeOptions="actionSearch"
就是把Enter鍵設(shè)置為Search鍵,并把點(diǎn)擊Enter鍵的動(dòng)作設(shè)為actionSearch,這樣既可在代碼中監(jiān)聽何時(shí)按下search鍵

沒什么說的,bg屬性可以直接看看源碼。接下來看模擬的bean類,這里直接就叫Bean.java

public class Bean { 
 
  private int iconId; 
  private String title; 
  private String content; 
  private String comments; 
 
  public Bean(int iconId, String title, String content, String comments) { 
    this.iconId = iconId; 
    this.title = title; 
    this.content = content; 
    this.comments = comments; 
  } 
 
  public int getIconId() { 
    return iconId; 
  } 
 
  public void setIconId(int iconId) { 
    this.iconId = iconId; 
  } 
 
  public String getTitle() { 
    return title; 
  } 
 
  public void setTitle(String title) { 
    this.title = title; 
  } 
 
  public String getContent() { 
    return content; 
  } 
 
  public void setContent(String content) { 
    this.content = content; 
  } 
 
  public String getComments() { 
    return comments; 
  } 
 
  public void setComments(String comments) { 
    this.comments = comments; 
  } 
} 

接著看主角SearchView.java

public class SearchView extends LinearLayout implements View.OnClickListener { 
 
  /** 
   * 輸入框 
   */ 
  private EditText etInput; 
 
  /** 
   * 刪除鍵 
   */ 
  private ImageView ivDelete; 
 
  /** 
   * 返回按鈕 
   */ 
  private Button btnBack; 
 
  /** 
   * 上下文對象 
   */ 
  private Context mContext; 
 
  /** 
   * 彈出列表 
   */ 
  private ListView lvTips; 
 
  /** 
   * 提示adapter (推薦adapter) 
   */ 
  private ArrayAdapter<String> mHintAdapter; 
 
  /** 
   * 自動(dòng)補(bǔ)全adapter 只顯示名字 
   */ 
  private ArrayAdapter<String> mAutoCompleteAdapter; 
 
  /** 
   * 搜索回調(diào)接口 
   */ 
  private SearchViewListener mListener; 
 
  /** 
   * 設(shè)置搜索回調(diào)接口 
   * 
   * @param listener 監(jiān)聽者 
   */ 
  public void setSearchViewListener(SearchViewListener listener) { 
    mListener = listener; 
  } 
 
  public SearchView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mContext = context; 
    LayoutInflater.from(context).inflate(R.layout.search_layout, this); 
    initViews(); 
  } 
 
  private void initViews() { 
    etInput = (EditText) findViewById(R.id.search_et_input); 
    ivDelete = (ImageView) findViewById(R.id.search_iv_delete); 
    btnBack = (Button) findViewById(R.id.search_btn_back); 
    lvTips = (ListView) findViewById(R.id.search_lv_tips); 
 
    lvTips.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
        //set edit text 
        String text = lvTips.getAdapter().getItem(i).toString(); 
        etInput.setText(text); 
        etInput.setSelection(text.length()); 
        //hint list view gone and result list view show 
        lvTips.setVisibility(View.GONE); 
        notifyStartSearching(text); 
      } 
    }); 
 
    ivDelete.setOnClickListener(this); 
    btnBack.setOnClickListener(this); 
 
    etInput.addTextChangedListener(new EditChangedListener()); 
    etInput.setOnClickListener(this); 
    etInput.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
      @Override 
      public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { 
        if (actionId == EditorInfo.IME_ACTION_SEARCH) { 
          lvTips.setVisibility(GONE); 
          notifyStartSearching(etInput.getText().toString()); 
        } 
        return true; 
      } 
    }); 
  } 
 
  /** 
   * 通知監(jiān)聽者 進(jìn)行搜索操作 
   * @param text 
   */ 
  private void notifyStartSearching(String text){ 
    if (mListener != null) { 
      mListener.onSearch(etInput.getText().toString()); 
    } 
    //隱藏軟鍵盤 
    InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); 
  } 
 
  /** 
   * 設(shè)置熱搜版提示 adapter 
   */ 
  public void setTipsHintAdapter(ArrayAdapter<String> adapter) { 
    this.mHintAdapter = adapter; 
    if (lvTips.getAdapter() == null) { 
      lvTips.setAdapter(mHintAdapter); 
    } 
  } 
 
  /** 
   * 設(shè)置自動(dòng)補(bǔ)全adapter 
   */ 
  public void setAutoCompleteAdapter(ArrayAdapter<String> adapter) { 
    this.mAutoCompleteAdapter = adapter; 
  } 
 
  private class EditChangedListener implements TextWatcher { 
    @Override 
    public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { 
 
    } 
 
    @Override 
    public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 
      if (!"".equals(charSequence.toString())) { 
        ivDelete.setVisibility(VISIBLE); 
        lvTips.setVisibility(VISIBLE); 
        if (mAutoCompleteAdapter != null && lvTips.getAdapter() != mAutoCompleteAdapter) { 
          lvTips.setAdapter(mAutoCompleteAdapter); 
        } 
        //更新autoComplete數(shù)據(jù) 
        if (mListener != null) { 
          mListener.onRefreshAutoComplete(charSequence + ""); 
        } 
      } else { 
        ivDelete.setVisibility(GONE); 
        if (mHintAdapter != null) { 
          lvTips.setAdapter(mHintAdapter); 
        } 
        lvTips.setVisibility(GONE); 
      } 
 
    } 
 
    @Override 
    public void afterTextChanged(Editable editable) { 
    } 
  } 
 
  @Override 
  public void onClick(View view) { 
    switch (view.getId()) { 
      case R.id.search_et_input: 
        lvTips.setVisibility(VISIBLE); 
        break; 
      case R.id.search_iv_delete: 
        etInput.setText(""); 
        ivDelete.setVisibility(GONE); 
        break; 
      case R.id.search_btn_back: 
        ((Activity) mContext).finish(); 
        break; 
    } 
  } 
 
  /** 
   * search view回調(diào)方法 
   */ 
  public interface SearchViewListener { 
 
    /** 
     * 更新自動(dòng)補(bǔ)全內(nèi)容 
     * 
     * @param text 傳入補(bǔ)全后的文本 
     */ 
    void onRefreshAutoComplete(String text); 
 
    /** 
     * 開始搜索 
     * 
     * @param text 傳入輸入框的文本 
     */ 
    void onSearch(String text); 
 
//    /** 
//     * 提示列表項(xiàng)點(diǎn)擊時(shí)回調(diào)方法 (提示/自動(dòng)補(bǔ)全) 
//     */ 
//    void onTipsItemClick(String text); 
  } 
 
} 

搜索框主要包含兩個(gè)結(jié)構(gòu):輸入欄+彈出框(自動(dòng)補(bǔ)全或熱門搜素推薦)。

代碼不多,實(shí)現(xiàn)很簡單,主要是需要給EditText(輸入框)設(shè)置點(diǎn)擊監(jiān)聽和文本改變監(jiān)聽,有以下幾點(diǎn):
1. 當(dāng)輸入框沒有文本時(shí),點(diǎn)擊輸入框,顯示熱門搜索列表框。
2. 當(dāng)輸入框有文本時(shí),點(diǎn)擊輸入框,應(yīng)顯示自動(dòng)補(bǔ)全列表框。
3. 當(dāng)輸入框的文本發(fā)生改變時(shí),需要更新自動(dòng)補(bǔ)全列表框的數(shù)據(jù)。由于這些數(shù)據(jù)應(yīng)該是在外部(調(diào)用者)中獲得的,所以可以通過接口回調(diào)的形式,當(dāng)需要更新時(shí),通知監(jiān)聽者更新數(shù)據(jù)。
4. 當(dāng)輸入框的文本從空”“變換到非空時(shí),即有字符時(shí),界面應(yīng)顯示自動(dòng)補(bǔ)全框,隱藏?zé)衢T搜索框。
5. 當(dāng)輸入框的文本從非空變?yōu)榭諘r(shí),系統(tǒng)應(yīng)隱藏自動(dòng)補(bǔ)全框和熱門搜索框。
6. 需要監(jiān)聽是否按下search鍵(enter),按下時(shí)通知監(jiān)聽者執(zhí)行search操作

結(jié)合以上6點(diǎn)和在上文分析過的內(nèi)容,就能很輕松地實(shí)現(xiàn)該view。

之后來看看搜索界面的布局文activity_main.xml

<LinearLayout 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" 
       tools:context=".MainActivity" 
       android:orientation="vertical"> 
 
  <com.yetwish.customsearchdemo.activity.widge.SearchView 
    android:id="@+id/main_search_layout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 
  </com.yetwish.customsearchdemo.activity.widge.SearchView> 
 
  <ListView 
    android:visibility="gone" 
    android:id="@+id/main_lv_search_results" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 
 
  </ListView> 
</LinearLayout> 

就是一個(gè)SearchView加上一個(gè)結(jié)果列表,這些我們在上文都分析過了,所以也沒什么好說的。布局可根據(jù)自身需求去自定義。

最后就是搜索界面調(diào)用該view  MainActiviy.java

public class MainActivity extends Activity implements SearchView.SearchViewListener { 
 
  /** 
   * 搜索結(jié)果列表view 
   */ 
  private ListView lvResults; 
 
  /** 
   * 搜索view 
   */ 
  private SearchView searchView; 
 
 
  /** 
   * 熱搜框列表adapter 
   */ 
  private ArrayAdapter<String> hintAdapter; 
 
  /** 
   * 自動(dòng)補(bǔ)全列表adapter 
   */ 
  private ArrayAdapter<String> autoCompleteAdapter; 
 
  /** 
   * 搜索結(jié)果列表adapter 
   */ 
  private SearchAdapter resultAdapter; 
 
  /** 
   * 數(shù)據(jù)庫數(shù)據(jù),總數(shù)據(jù) 
   */ 
  private List<Bean> dbData; 
 
  /** 
   * 熱搜版數(shù)據(jù) 
   */ 
  private List<String> hintData; 
 
  /** 
   * 搜索過程中自動(dòng)補(bǔ)全數(shù)據(jù) 
   */ 
  private List<String> autoCompleteData; 
 
  /** 
   * 搜索結(jié)果的數(shù)據(jù) 
   */ 
  private List<Bean> resultData; 
 
  /** 
   * 默認(rèn)提示框顯示項(xiàng)的個(gè)數(shù) 
   */ 
  private static int DEFAULT_HINT_SIZE = 4; 
 
  /** 
   * 提示框顯示項(xiàng)的個(gè)數(shù) 
   */ 
  private static int hintSize = DEFAULT_HINT_SIZE; 
 
  /** 
   * 設(shè)置提示框顯示項(xiàng)的個(gè)數(shù) 
   * 
   * @param hintSize 提示框顯示個(gè)數(shù) 
   */ 
  public static void setHintSize(int hintSize) { 
    MainActivity.hintSize = hintSize; 
  } 
 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.activity_main); 
    initData(); 
    initViews(); 
  } 
 
  /** 
   * 初始化視圖 
   */ 
  private void initViews() { 
    lvResults = (ListView) findViewById(R.id.main_lv_search_results); 
    searchView = (SearchView) findViewById(R.id.main_search_layout); 
    //設(shè)置監(jiān)聽 
    searchView.setSearchViewListener(this); 
    //設(shè)置adapter 
    searchView.setTipsHintAdapter(hintAdapter); 
    searchView.setAutoCompleteAdapter(autoCompleteAdapter); 
 
    lvResults.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { 
        Toast.makeText(MainActivity.this, position + "", Toast.LENGTH_SHORT).show(); 
      } 
    }); 
  } 
 
  /** 
   * 初始化數(shù)據(jù) 
   */ 
  private void initData() { 
    //從數(shù)據(jù)庫獲取數(shù)據(jù) 
    getDbData(); 
    //初始化熱搜版數(shù)據(jù) 
    getHintData(); 
    //初始化自動(dòng)補(bǔ)全數(shù)據(jù) 
    getAutoCompleteData(null); 
    //初始化搜索結(jié)果數(shù)據(jù) 
    getResultData(null); 
  } 
 
  /** 
   * 獲取db 數(shù)據(jù) 
   */ 
  private void getDbData() { 
    int size = 100; 
    dbData = new ArrayList<>(size); 
    for (int i = 0; i < size; i++) { 
      dbData.add(new Bean(R.drawable.icon, "android開發(fā)必備技能" + (i + 1), "Android自定義view——自定義搜索view", i * 20 + 2 + "")); 
    } 
  } 
 
  /** 
   * 獲取熱搜版data 和adapter 
   */ 
  private void getHintData() { 
    hintData = new ArrayList<>(hintSize); 
    for (int i = 1; i <= hintSize; i++) { 
      hintData.add("熱搜版" + i + ":Android自定義View"); 
    } 
    hintAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, hintData); 
  } 
 
  /** 
   * 獲取自動(dòng)補(bǔ)全data 和adapter 
   */ 
  private void getAutoCompleteData(String text) { 
    if (autoCompleteData == null) { 
      //初始化 
      autoCompleteData = new ArrayList<>(hintSize); 
    } else { 
      // 根據(jù)text 獲取auto data 
      autoCompleteData.clear(); 
      for (int i = 0, count = 0; i < dbData.size() 
          && count < hintSize; i++) { 
        if (dbData.get(i).getTitle().contains(text.trim())) { 
          autoCompleteData.add(dbData.get(i).getTitle()); 
          count++; 
        } 
      } 
    } 
    if (autoCompleteAdapter == null) { 
      autoCompleteAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, autoCompleteData); 
    } else { 
      autoCompleteAdapter.notifyDataSetChanged(); 
    } 
  } 
 
  /** 
   * 獲取搜索結(jié)果data和adapter 
   */ 
  private void getResultData(String text) { 
    if (resultData == null) { 
      // 初始化 
      resultData = new ArrayList<>(); 
    } else { 
      resultData.clear(); 
      for (int i = 0; i < dbData.size(); i++) { 
        if (dbData.get(i).getTitle().contains(text.trim())) { 
          resultData.add(dbData.get(i)); 
        } 
      } 
    } 
    if (resultAdapter == null) { 
      resultAdapter = new SearchAdapter(this, resultData, R.layout.item_bean_list); 
    } else { 
      resultAdapter.notifyDataSetChanged(); 
    } 
  } 
 
  /** 
   * 當(dāng)搜索框 文本改變時(shí) 觸發(fā)的回調(diào) ,更新自動(dòng)補(bǔ)全數(shù)據(jù) 
   * @param text 
   */ 
  @Override 
  public void onRefreshAutoComplete(String text) { 
    //更新數(shù)據(jù) 
    getAutoCompleteData(text); 
  } 
 
  /** 
   * 點(diǎn)擊搜索鍵時(shí)edit text觸發(fā)的回調(diào) 
   * 
   * @param text 
   */ 
  @Override 
  public void onSearch(String text) { 
    //更新result數(shù)據(jù) 
    getResultData(text); 
    lvResults.setVisibility(View.VISIBLE); 
    //第一次獲取結(jié)果 還未配置適配器 
    if (lvResults.getAdapter() == null) { 
      //獲取搜索數(shù)據(jù) 設(shè)置適配器 
      lvResults.setAdapter(resultAdapter); 
    } else { 
      //更新搜索數(shù)據(jù) 
      resultAdapter.notifyDataSetChanged(); 
    } 
    Toast.makeText(this, "完成搜素", Toast.LENGTH_SHORT).show(); 
  } 
 
} 

使用SearchView比較簡單,只要給SearchView設(shè)置onSearchViewListener監(jiān)聽接口,實(shí)現(xiàn)對應(yīng)的方法,并給SearchView傳入熱搜版和自動(dòng)補(bǔ)全的adapter既可。

這里使用的匹配算法比較簡單,也沒有考慮多個(gè)搜索詞的情況,(這些之后都可以再完善),主要實(shí)現(xiàn)就是在總數(shù)據(jù)中匹配每個(gè)Bean的Title是否包含搜索詞,包含則表示該數(shù)據(jù)匹配,否則不匹配。然后將所有匹配的Bean顯示到結(jié)果列表中。

考慮到實(shí)際開發(fā)中,數(shù)據(jù)量十分龐大,可以只把結(jié)果集的一部分(如前10個(gè))顯示出來,上拉到底的時(shí)候再加載之后的記錄,也就是可以加入上拉加載的機(jī)制,使app性能更優(yōu)化。

自動(dòng)補(bǔ)全匹配也是采用相同的算法。算法都比較簡單,當(dāng)然也可以弄得復(fù)雜點(diǎn),比如根據(jù)“ ”(空格)去分割輸入文本,再逐個(gè)考慮單個(gè)搜索詞的匹配項(xiàng),把匹配次數(shù)從多到少排列出結(jié)果集等等。這里不細(xì)說。

這里有一個(gè)問題是進(jìn)入該搜索界面時(shí)需要加載所有的數(shù)據(jù)項(xiàng)到內(nèi)存,當(dāng)數(shù)據(jù)項(xiàng)很多時(shí),是否會(huì)占用大量的內(nèi)存?如果是應(yīng)該如何避免?是采用只加載一部分?jǐn)?shù)據(jù)的形式,還是直接使用搜索詞到數(shù)據(jù)庫中查詢更優(yōu)?還請各位看官大神們給出寶貴的意見~

好了,自定義搜索框到這就打造完成啦,是不是感覺簡單過頭了。

各位看官如果有任何問題可評(píng)論或者發(fā)郵件跟我聯(lián)系yetwish@gmail.com

囧~忘記貼代碼了,代碼放在github上,各位看官直接download即可
鏈接:https://github.com/yetwish/CustomSearchView

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

分享文章:Android自定義View實(shí)現(xiàn)搜索框(SearchView)功能
文章轉(zhuǎn)載:http://bm7419.com/article44/jcseee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、網(wǎng)站建設(shè)、商城網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)、服務(wù)器托管、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)