Android仿饿了么搜索功能

仿饿了么搜索框

在这里插入图片描述

这里采用的是pupupWindow来实现,一个全屏的popupWindow里面放各个View做对应操作

首先是activity_popup.xml布局,很简单,就一个带背景的TextView,点击弹出popupWindow,这里都用的ConstraintLayout布局,以减少View的层数,对ConstraintLayout不了解可以无视(界面使用什么ViewGeoup搭建都一样,主要是代码逻辑)

	<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:padding="20dp"
    tools:context=".PopupActivity">
    <TextView
        android:id="@+id/search_btn"
        android:gravity="center"
        android:paddingBottom="5dp"
        android:paddingTop="5dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="@drawable/search_bg"
        android:text="搜索"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints" />
</android.support.constraint.ConstraintLayout>

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;
    // 存放标签
    List<String> mHistoryList = new ArrayList<>();
    List<String> mHotList = 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<SearchTagAdapter.CustomViewHolder> {
    private List<String> mTagList;
    public SearchTagAdapter(List<String> tagList) {
        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布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
    <ImageView
        android:id="@+id/back"
        android:src="@drawable/icon_back"
        app:layout_constraintTop_toTopOf="@id/edit_query"
        app:layout_constraintBottom_toBottomOf="@id/edit_query"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_width="20dp"
        android:layout_height="30dp"
        tools:ignore="MissingConstraints" />

    <TextView
        android:id="@+id/search"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/edit_query"
        app:layout_constraintBottom_toBottomOf="@id/edit_query"
        android:text="搜索"
        android:textSize="18sp"
        android:textColor="#000000"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints" />

    <EditText
        android:id="@+id/edit_query"
        android:background="@drawable/search_bg"
        app:layout_constraintLeft_toRightOf="@id/back"
        app:layout_constraintRight_toLeftOf="@id/search"
        android:padding="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:hint="输入搜索内容"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints" />

    <RelativeLayout
        android:id="@+id/history"
        app:layout_constraintTop_toBottomOf="@id/edit_query"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints">
        <TextView
            android:layout_marginTop="20dp"
            android:textColor="#000000"
            android:textSize="15dp"
            android:text="历史搜索"
            android:layout_centerVertical="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:ignore="MissingConstraints" />
        <ImageView
            android:id="@+id/clear_history"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            app:layout_constraintRight_toRightOf="parent"
            android:src="@drawable/icon_clear"
            android:layout_width="20dp"
            android:layout_height="40dp"
            tools:ignore="MissingConstraints" />
    </RelativeLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/history_content"
        app:layout_constraintTop_toBottomOf="@id/history"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints"/>

    <TextView
        android:id="@+id/hot"
        app:layout_constraintTop_toBottomOf="@id/history_content"
        android:layout_marginTop="20dp"
        android:textColor="#000000"
        android:textSize="15dp"
        android:text="热门搜索"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/hot_content"
        app:layout_constraintTop_toBottomOf="@id/hot"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints"/>
</android.support.constraint.ConstraintLayout>

搜索标签布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginBottom="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
    <TextView
        android:id="@+id/tag_text"
        android:textSize="15sp"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textColor="#565656"
        android:lines="1"
        android:maxEms="9"
        android:ellipsize="end"
        android:background="@drawable/tag_bg"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints" />
</android.support.constraint.ConstraintLayout>

search_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
    <solid android:color="#F1F1F1"/>
</shape>

tag_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#F7F7F7"/>
    <corners android:radius="5dp" />
</shape>

搜索界面的基本功能差不多实现了,接下来使用可以根据需要自己封装或者添加其它功能,我进行了一个简单的功能封装,可以直接拿来使用
https://github.com/jayjunLiao/SearchPopupWindow

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值