仿饿了么搜索框
这里采用的是pupupWindow来实现,一个全屏的popupWindow里面放各个View做对应操作
首先是activity_popup.xml布局,很简单,就一个带背景的TextView,点击弹出popupWindow,这里都用的ConstraintLayout布局,以减少View的层数,对ConstraintLayout不了解可以无视(界面使用什么ViewGeoup搭建都一样,主要是代码逻辑)
PopupActivity代码:
public class PopupActivity extends AppCompatActivity implements View.OnClickListener, SearchTagAdapter.OnItemClickListener {
private PopupWindow mPopupWindow;
private View mPopView;
private TextView mSearch;
private SearchTagAdapter mHistoryAdapter;
private SearchTagAdapter mHotAdapter;
private RecyclerView mHistoryRecycler;
private RecyclerView mHotRecycler;
private View mHistoryHeader;
private View mHotHeader;
private EditText mEditQuery;
// 存放标签
ListmHistoryList = new ArrayList<>();
ListmHotList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup);
mSearch = findViewById(R.id.search_btn);
mSearch.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.search_btn:
createPopupWindow();
break;
case R.id.search:
// 获取EditText内容,进行相应操作
Editable editQueryable = mEditQuery.getText();
String editQueryText = "";
if (editQueryable != null) {
editQueryText = editQueryable.toString();
}
mEditQuery.setText("");
mPopupWindow.dismiss();
Toast.makeText(this, editQueryText, Toast.LENGTH_SHORT).show();
break;
case R.id.back:
mPopupWindow.dismiss();
break;
case R.id.clear_history:
// 清空搜索历史,隐藏'历史搜索'头部局
mHistoryList.clear();
mHistoryAdapter.notifyDataChanged();
setHeaderVisibility(View.GONE);
break;
}
}
private void createPopupWindow() {
// 获取屏幕宽高,用于设置popupWindow大小
Resources resources = this.getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
int width = dm.widthPixels;
int height = dm.heightPixels;
// 初始化pupupWindow的各个View
View pupView = LayoutInflater.from(this).inflate(R.layout.item_search_pop, null);
ImageView back = pupView.findViewById(R.id.back);
ImageView clearHistory = pupView.findViewById(R.id.clear_history);
TextView search = pupView.findViewById(R.id.search);
mHistoryHeader = pupView.findViewById(R.id.history);
mHotHeader = pupView.findViewById(R.id.hot);
mEditQuery = pupView.findViewById(R.id.edit_query);
mHistoryRecycler = pupView.findViewById(R.id.history_content);
mHotRecycler = pupView.findViewById(R.id.hot_content);
// 流式布局设置
flexboxConfig(mHistoryRecycler);
flexboxConfig(mHotRecycler);
// 设置标签数据Adapter
String[] tags = {"披萨", "火锅", "海底捞", "芝士蛋糕", "大闸蟹", "黄焖鸡米饭", "沙县小吃"};
mHistoryList.clear();
mHotList.clear();
mHistoryList.addAll(Arrays.asList(tags));
mHotList.addAll(Arrays.asList(tags));
mHistoryAdapter = new SearchTagAdapter(mHistoryList);
mHotAdapter = new SearchTagAdapter(mHotList);
mHistoryRecycler.setAdapter(mHistoryAdapter);
mHotRecycler.setAdapter(mHotAdapter);
/**
* 初始化PopupWindow进行各项设置
*/
mPopupWindow = new PopupWindow(pupView, width, height);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#FFFFFF")));
// 设置可以获取焦点
mPopupWindow.setFocusable(true);
// 设置可以触摸弹出框以外的区域
mPopupWindow.setOutsideTouchable(true);
// 更新popupwindow的状态
mPopupWindow.update();
mPopupWindow.showAtLocation(getWindow().getDecorView(), Gravity.CENTER, 0,0);
mHistoryAdapter.setOnItemClickListener(this);
mHotAdapter.setOnItemClickListener(this);
back.setOnClickListener(this);
search.setOnClickListener(this);
clearHistory.setOnClickListener(this);
}
/**
* 隐藏历史搜索头部
* @param visibility
*/
private void setHeaderVisibility(int visibility) {
mHistoryHeader.setVisibility(visibility);
mHistoryRecycler.setVisibility(visibility);
}
/**
* 流式布局设置
* @param recyclerView
*/
private void flexboxConfig(RecyclerView recyclerView){
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(this);
layoutManager.setFlexWrap(FlexWrap.WRAP);
layoutManager.setFlexDirection(FlexDirection.ROW);
layoutManager.setAlignItems(AlignItems.STRETCH);
layoutManager.setJustifyContent(JustifyContent.FLEX_START);
// 设置item间隔
recyclerView.addItemDecoration(new RecyclerViewItemDecoration(30));
recyclerView.setLayoutManager(layoutManager);
}
@Override
public void onItemClick(String itemStr) {
// 点击标签,将对应的String填入EditText
mEditQuery.setText(itemStr);
mEditQuery.setSelection(mEditQuery.getText().length());
}
}
SearchTagAdapter: 历史搜索/热门搜索标签Adapter,和正常的RecyclerView Adapter没有区别,就是多写一个item监听
public class SearchTagAdapter extends RecyclerView.Adapter{
private ListmTagList;
public SearchTagAdapter(ListtagList) {
this.mTagList = tagList;
}
OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener{
void onItemClick(String itemStr);
}
@NonNull
@Override
public SearchTagAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_tag, viewGroup, false);
return new CustomViewHolder(view, mOnItemClickListener);
}
@Override
public void onBindViewHolder(@NonNull CustomViewHolder customViewHolder, int positon) {
customViewHolder.tagText.setText(mTagList.get(positon));
}
@Override
public int getItemCount() {
return mTagList == null ? 0 : mTagList.size();
}
// RecyclerView没有item点击监听功能,需要自己写
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
public void notifyDataChanged() {
notifyItemChanged(getItemCount());
}
static class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tagText;
OnItemClickListener mItemClickListener;
public CustomViewHolder(@NonNull View itemView, OnItemClickListener onItemClickListener) {
super(itemView);
tagText = itemView.findViewById(R.id.tag_text);
tagText.setOnClickListener(this);
this.mItemClickListener = onItemClickListener;
}
@Override
public void onClick(View v) {
if (mItemClickListener != null && v instanceof TextView) {
mItemClickListener.onItemClick(((TextView)v).getText().toString());
}
}
}
}
RecyclerViewItemDecoration用于设置RecyclerView item间距
public class RecyclerViewItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public RecyclerViewItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.right = space;
}
}
popupWindow布局:
搜索标签布局
search_bg.xml
tag_bg.xml
搜索界面的基本功能差不多实现了,接下来使用可以根据需要自己封装或者添加其它功能,我进行了一个简单的功能封装,可以直接拿来使用
https://github.com/jayjunLiao/SearchPopupWindow