使用SearchView+RecyclerView做搜尋框
阿新 • • 發佈:2019-01-06
安卓搜尋框分別使用了EditText+RecycleView和SearchView+RecycleView都實現了一遍 對比下兩種的區別!
首先是一張效果圖!
一、EditText+RecycleView
先丟上程式碼!
Layout
<?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:orientation="vertical">
<EditText
android:id="@+id/search_tag_input_edit"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:background ="@drawable/shape_tag_search"
android:layout_margin="8dp"
android:hint="請輸入檢索Tag"
android:drawableLeft="@mipmap/ic_search"
android:drawablePadding="3dp"
android:padding="8dp"
android:maxLength="20"
android:inputType="text"
android:maxLines ="1"
android:textSize="12sp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/search_tag_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
android:listSelector="@android:color/transparent" />
</LinearLayout>
Activity
package net.yeah.lililearn.searchrecyclerview;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import net.yeah.lililearn.searchrecyclerview.adapter.SearchAdapter;
import net.yeah.lililearn.searchrecyclerview.model.SearchTag;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private EditText mSearchTagEdit;
private RecyclerView mRecyclerView;
private Handler handler = new Handler();
private List<SearchTag> searchTagList;
private SearchAdapter mAdapter;
private Runnable delayRun = new Runnable() {
@Override
public void run() {
searchTags(mSearchTagEdit.getText().toString().trim());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initAdapter();
setEvent();
}
private void initView() {
mSearchTagEdit = (EditText) findViewById(R.id.search_tag_input_edit);
mRecyclerView = (RecyclerView) findViewById(R.id.search_tag_recycler);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAnimation(null);
}
private void initAdapter() {
searchTagList = new ArrayList<>();
mAdapter = new SearchAdapter(searchTagList, this);
mRecyclerView.setAdapter(mAdapter);
}
private void setEvent() {
mSearchTagEdit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//no-op
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//no-op
}
@Override
public void afterTextChanged(Editable editable) {
//輸入完成後嚴重8毫秒在請求
if (delayRun != null) {
handler.removeCallbacks(delayRun);
}
handler.postDelayed(delayRun, 800);
}
});
}
/**
* 請求資料
* @param searchTagName
*/
private void searchTags(String searchTagName) {
List<SearchTag> searchTags=new ArrayList<>();
searchTags.add(new SearchTag("測試資料1"));
searchTags.add(new SearchTag("測試資料2"));
searchTags.add(new SearchTag("測試資料3"));
searchTags.add(new SearchTag("測試資料4"));
searchTags.add(new SearchTag("測試資料5"));
searchTags.add(new SearchTag("測試資料6"));
searchTags.add(new SearchTag("測試資料7"));
searchTags.add(new SearchTag("測試資料8"));
searchTags.add(new SearchTag("測試資料9"));
searchTags.add(new SearchTag("測試資料10"));
searchTagList.clear();
searchTagList.addAll(searchTags);
mAdapter.notifyDataSetChanged();
}
}
adapter
package net.yeah.lililearn.searchrecyclerview.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebViewFragment;
import android.widget.RelativeLayout;
import android.widget.TextView;
import net.yeah.lililearn.searchrecyclerview.R;
import net.yeah.lililearn.searchrecyclerview.model.SearchTag;
import java.util.List;
import lombok.NonNull;
public class SearchAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_TOP = 0;
private static final int VIEW_TYPE_ITEM = 1;
private static final int VIEW_TYPE_END = 2;
private static final int VIEW_TYPE_EMPTY = 3;
private List<SearchTag> searchTagList;
private Context context;
public SearchAdapter(@NonNull List<SearchTag> Tags,
@NonNull Context context) {
this.context = context;
this.searchTagList = Tags;
Log.e("11",searchTagList.toString());
}
@Override
public int getItemViewType(int position) {
Log.e("11",searchTagList.toString());
if (searchTagList.isEmpty()) {
if (position == 0) {
return VIEW_TYPE_EMPTY;
}
return VIEW_TYPE_END;
}
if (position == 0) {
return VIEW_TYPE_TOP;
} else if (position == getItemCount() - 1) {
return VIEW_TYPE_END;
}
return VIEW_TYPE_ITEM;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_TOP: {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_goods_tag_top, parent, false);
return new GoodsTagTopHolder(view);
}
case VIEW_TYPE_ITEM: {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_goods_tag_item, parent, false);
return new GoodsTagItemHolder(view);
}
case VIEW_TYPE_END: {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_goods_tag_end, parent, false);
GoodsTagEndHolder holder = new GoodsTagEndHolder(view);
holder.setEvent();
return holder;
}
default: {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_goods_tag_empty, parent, false);
return new EmptyViewHolder(view);
}
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof GoodsTagItemHolder) {
SearchTag searchTag = searchTagList.get(position - 1);
GoodsTagItemHolder goodsTagItemHolder = (GoodsTagItemHolder) holder;
goodsTagItemHolder.setData(searchTag);
goodsTagItemHolder.setEvent(searchTag);
}
}
@Override
public int getItemCount() {
if (searchTagList.isEmpty()) {
return 2;
}
return searchTagList.size() + 2;
}
private class GoodsTagTopHolder extends RecyclerView.ViewHolder {
GoodsTagTopHolder(View view) {
super(view);
}
}
private class GoodsTagItemHolder extends RecyclerView.ViewHolder {
private TextView mGoodsTagItemTv;
private RelativeLayout mGoodsTagItemLayout;
GoodsTagItemHolder(View view) {
super(view);
mGoodsTagItemLayout = (RelativeLayout) view.findViewById(R.id.goods_tag_item_layout);
mGoodsTagItemTv = (TextView) view.findViewById(R.id.goods_tag_item_tv);
}
public void setData(SearchTag searchTag) {
String label = searchTag.getName();
mGoodsTagItemTv.setText(label);
}
public void setEvent(SearchTag searchTag) {
}
}
private class GoodsTagEndHolder extends RecyclerView.ViewHolder {
private TextView mGoodsTagLinkTv;
GoodsTagEndHolder(View view) {
super(view);
mGoodsTagLinkTv = (TextView) view.findViewById(R.id.goods_tag_link_tv);
}
public void setEvent() {
mGoodsTagLinkTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
}
private class EmptyViewHolder extends RecyclerView.ViewHolder {
EmptyViewHolder(View itemView) {
super(itemView);
TextView textView = (TextView) itemView.findViewById(R.id.empty_text);
}
}
}
SearchView雖然是官方的但是一般不推薦使用!對於搜尋框的實現官方提供了SearchView但是很多坑需要去填推薦用EditText!
SearchView屬性
屬性名稱 | 相關方法 | 描述 |
---|---|---|
android:iconifiedByDefault | setIconifiedByDefault(boolean) | 設定搜尋圖示是否顯示在搜尋框內 |
android:imeOptions | setImeOptions(int) | 設定輸入法搜尋選項欄位,預設是搜尋,可以是:下一頁、傳送、完成等 |
android:inputType | setInputType(int) | 設定輸入型別 |
android:maxWidth | setMaxWidth(int) | 設定最大寬度 |
android:queryHint | setQueryHint(CharSequence) | 設定查詢提示字串 |
setSubmitButtonEnabled (boolean enabled) | 設定是否出現提交按鈕 |
package net.yeah.lililearn.searchrecyclerview.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;;
import android.text.TextUtils;
import android.widget.SearchView;
import net.yeah.lililearn.searchrecyclerview.R;
import net.yeah.lililearn.searchrecyclerview.adapter.SearchAdapter;
import net.yeah.lililearn.searchrecyclerview.model.SearchTag;
import java.util.ArrayList;
import java.util.List;
public class SearchViewActivity extends AppCompatActivity {
private RecyclerView mSearchTagRecycler;
private List<SearchTag> searchTagList;
private SearchAdapter mAdapter;
private SearchView mSearchTagView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
initAdapter();
setEvent();
}
private void initView() {
mSearchTagView = (SearchView) findViewById(R.id.search_tag_view);
mSearchTagRecycler = (RecyclerView) findViewById(R.id.search_tag_recycler);
mSearchTagRecycler.setLayoutManager(new LinearLayoutManager(this));
mSearchTagRecycler.setAnimation(null);
}
private void initAdapter() {
searchTagList = new ArrayList<>();
mAdapter = new SearchAdapter(searchTagList, this);
mSearchTagRecycler.setAdapter(mAdapter);
}
private void setEvent() {
mSearchTagView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// 當點選搜尋按鈕時觸發該方法
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// 當搜尋內容改變時觸發該方法
if (!TextUtils.isEmpty(newText.trim())){
searchTags(newText.trim());
}else{
searchTagList.clear();
mAdapter.notifyDataSetChanged();
}
return false;
}
});
}
/**
* 請求資料
* @param searchTagName
*/
private void searchTags(String searchTagName) {
List<SearchTag> searchTags=new ArrayList<>();
searchTags.add(new SearchTag("測試資料1"));
searchTags.add(new SearchTag("測試資料2"));
searchTags.add(new SearchTag("測試資料3"));
searchTags.add(new SearchTag("測試資料4"));
searchTags.add(new SearchTag("測試資料5"));
searchTags.add(new SearchTag("測試資料6"));
searchTags.add(new SearchTag("測試資料7"));
searchTags.add(new SearchTag("測試資料8"));
searchTags.add(new SearchTag("測試資料9"));
searchTags.add(new SearchTag("測試資料10"));
searchTagList.clear();
searchTagList.addAll(searchTags);
mAdapter.notifyDataSetChanged();
}
}
<?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:orientation="vertical">
<SearchView
android:id="@+id/search_tag_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:layout_margin="8dp"
android:background="@drawable/shape_tag_search"
android:queryHint="請輸入搜尋內容" />
<android.support.v7.widget.RecyclerView
android:id="@+id/search_tag_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
android:listSelector="@android:color/transparent" />
</LinearLayout>
貼上效果圖
專案中經常遇到的問題
1.放大鏡圖示的替換
2.X圖示的刪除
3.Text框下劃線刪除
總結:雖然官方的元件挺好使的,但是在專案中使用需要自己重寫一下才能使用。還是EditText比較適合!