博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多重搜索算法_Android多重搜寻,例如传送,搜寻联络人
阅读量:2531 次
发布时间:2019-05-11

本文共 29292 字,大约阅读时间需要 97 分钟。

多重搜索算法

In this tutorial, we’ll discuss and implement a search feature that displays the matched results in a drop-down beside allowing to filter the ListView results based on the searched string. This type of UI is commonly seen in Food Delivery apps that have plenty of options to choose from. The user can search based on a certain tag/category to quickly find their desired result.

在本教程中,我们将讨论并实现搜索功能,该功能将在下拉菜单中显示匹配的结果,并允许根据搜索到的字符串过滤ListView结果。 这种界面通常出现在“食物交付”应用程序中,该应用程序有很多可供选择的选项。 用户可以基于某个标签/类别进行搜索以快速找到他们想要的结果。

At the end of this tutorial, you’ll be able to come up with a working application similar to the one given below.

在本教程的最后,您将能够提出一个与下面给出的应用程序相似的工作应用程序。

Android多重搜寻 (Android Multi Search)

For the above application, we’ll NOT be using a SearchView. Instead, we’ll be using an EditText wrapped inside a CardView. The dropdown that pops up with a list of suggestions will be a RecyclerView.

对于上述应用程序,我们将不使用SearchView。 相反,我们将使用CardView中包装的EditText。 弹出的建议列表下拉列表将是RecyclerView。

项目结构 (Project Structure)

(Code)

The activity_main.xml layout is given below.

下面是activity_main.xml布局。

In the above code, the CardView is a Custom SearchView UI with a back button on the left. The ListView would display all the restaurants from the adapter.

在上面的代码中,CardView是一个Custom SearchView UI,左侧带有一个后退按钮。 ListView将显示适配器中的所有餐厅。

The Data Source for the restaurants and the type of cuisines is defined in the Model.java file as shown below.

餐厅和菜肴类型的数据源在Model.java文件中定义,如下所示。

package com.journaldev.efficientsearch;import java.util.List;public class Model {    public String name;    public String id;    public List cuisines;    public boolean isCuisine;    public int numberOfCuisine;    public Model(String id, String name, List cuisines, boolean isCuisine, int numberOfCuisine) {        this.name = name;        this.id = id;        this.cuisines = cuisines;        this.isCuisine = isCuisine;        this.numberOfCuisine = numberOfCuisine;    }}

The parameter that differentiates between a restaurant and a cuisine is isCuisine which is of type Boolean.

区分餐厅和美食的参数是isCuisine ,其类型为Boolean。

The MainActivity.java is given below.

MainActivity.java在下面给出。

package com.journaldev.efficientsearch;import android.content.Context;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.CardView;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.Toolbar;import android.text.Editable;import android.text.TextWatcher;import android.util.Log;import android.view.KeyEvent;import android.view.MenuItem;import android.view.View;import android.view.inputmethod.EditorInfo;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;import android.widget.ImageView;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;public class MainActivity extends AppCompatActivity implements CuisineSearchAdapter.ItemListener {    Toolbar toolbar;    private ImageView image_search_back;    private RelativeLayout view_search;    private EditText edit_text_search;    private CardView card_search;    private View line_divider, toolbar_shadow;    RecyclerView recyclerView;    ListView listView;    String text = "";    List modelsList, filterModels;    List cuisinesModels;    ListViewAdapter listViewAdapter;    CuisineSearchAdapter cuisineSearchAdapter;    ShowSearchView showSearchView;    boolean editTextChangedFromClick = false;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        showSearchView = new ShowSearchView();        toolbar = (Toolbar) findViewById(R.id.toolbar);        toolbar.inflateMenu(R.menu.menu_main);        image_search_back = (ImageView) findViewById(R.id.image_search_back);        view_search = (RelativeLayout) findViewById(R.id.view_search);        edit_text_search = (EditText) findViewById(R.id.edit_text_search);        card_search = (CardView) findViewById(R.id.card_search);        line_divider = findViewById(R.id.line_divider);        toolbar_shadow = findViewById(R.id.toolbar_shadow);        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);        listView = (ListView) findViewById(R.id.listView);        TextView no_results = (TextView) findViewById(R.id.txtNoResultsFound);        listView.setEmptyView(no_results);        populateRestaurantsAndCuisines();        image_search_back.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                text = "";                showSearchView.handleToolBar(MainActivity.this, card_search, toolbar, view_search, recyclerView, edit_text_search, line_divider);                toolbar_shadow.setVisibility(View.VISIBLE);                listViewAdapter = new ListViewAdapter(modelsList);                listView.setAdapter(listViewAdapter);            }        });        edit_text_search.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                text = s.toString();                if (editTextChangedFromClick) {                    editTextChangedFromClick = false;                    if (recyclerView.getVisibility() == View.VISIBLE)                        recyclerView.setVisibility(View.GONE);                                    } else {                                        if (recyclerView.getVisibility() != View.VISIBLE)                        recyclerView.setVisibility(View.VISIBLE);                                        if (s.toString().length() > 0) {                        performFiltering(filterModels);                    } else {                        CuisineSearchAdapter cuisineSearchAdapter = new CuisineSearchAdapter(cuisinesModels, modelsList, MainActivity.this, MainActivity.this, text);                        cuisineSearchAdapter.notifyDataSetChanged();                        recyclerView.setAdapter(cuisineSearchAdapter);                                                listViewAdapter = new ListViewAdapter(modelsList);                        listView.setAdapter(listViewAdapter);                    }                }                            }            @Override            public void afterTextChanged(Editable s) {            }        });        edit_text_search.setOnEditorActionListener(new TextView.OnEditorActionListener() {            @Override            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {                if (actionId == EditorInfo.IME_ACTION_SEARCH) {                    // Your piece of code on keyboard search click                    recyclerView.setVisibility(View.GONE);                    ((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view_search.getWindowToken(), 0);                    listViewAdapter.getFilter().filter(v.getText().toString());                    return true;                }                return false;            }        });        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {            @Override            public boolean onMenuItemClick(MenuItem item) {                int menuItem = item.getItemId();                switch (menuItem) {                    case R.id.action_search:                        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));                        cuisineSearchAdapter = new CuisineSearchAdapter(cuisinesModels, filterModels, MainActivity.this, MainActivity.this, text);                        recyclerView.setAdapter(cuisineSearchAdapter);                        showSearchView.handleToolBar(MainActivity.this, card_search, toolbar, view_search, recyclerView, edit_text_search, line_divider);                        break;                    default:                        break;                }                return false;            }        });    }    private void populateRestaurantsAndCuisines() {        modelsList = new ArrayList();        cuisinesModels = new ArrayList();        List cuisinesList = new ArrayList();        for (int i = 0; i < 7; i++)            cuisinesList.add("Cafes");        for (int i = 0; i < 4; i++)            cuisinesList.add("Burgers");        for (int i = 0; i < 4; i++)            cuisinesList.add("Bars");        modelsList.add(new Model("1", "McDonalds", new ArrayList(Arrays.asList("Cafes", "Burgers")), false, -1));        modelsList.add(new Model("2", "KFC", new ArrayList(Arrays.asList("Cafes", "Burgers")), false, -1));        modelsList.add(new Model("3", "Burger King", new ArrayList(Arrays.asList("Cafes", "Burgers")), false, -1));        modelsList.add(new Model("4", "Subway", new ArrayList(Arrays.asList("Burgers")), false, -1));        modelsList.add(new Model("5", "Cafe Coffee Day", new ArrayList(Arrays.asList("Cafes")), false, -1));        modelsList.add(new Model("6", "Costa", new ArrayList(Arrays.asList("Cafes")), false, -1));        modelsList.add(new Model("7", "Coffee Beans", new ArrayList(Arrays.asList("Cafes")), false, -1));        modelsList.add(new Model("8", "Starbucks", new ArrayList(Arrays.asList("Cafes")), false, -1));        modelsList.add(new Model("9", "Blues", new ArrayList(Arrays.asList("Bars")), false, -1));        modelsList.add(new Model("10", "Hard Rock Cafe", new ArrayList(Arrays.asList("Bars", "Cafe")), false, -1));        modelsList.add(new Model("11", "The Backyard Underground", new ArrayList(Arrays.asList("Bars")), false, -1));        modelsList.add(new Model("12", "Downtown", new ArrayList(Arrays.asList("Bars")), false, -1));        Map cuisineMap = new HashMap();        for (String cuisine : cuisinesList) {            Integer n = cuisineMap.get(cuisine);            n = (n == null) ? 1 : ++n;            cuisineMap.put(cuisine, n);        }        for (Map.Entry entry : cuisineMap.entrySet()) {            Model model = new Model("", entry.getKey(), null, true, entry.getValue());            modelsList.add(model);            cuisinesModels.add(model);        }        filterModels = new ArrayList(modelsList);        initialiseAdapters();    }    private void initialiseAdapters() {        listViewAdapter = new ListViewAdapter(filterModels);        listView.setAdapter(listViewAdapter);    }    @Override    public void onItemClick(Model model) {        editTextChangedFromClick = true;        if (model.isCuisine) {            edit_text_search.setText(model.name);            listViewAdapter.getFilter().filter(model.name);        } else {            edit_text_search.setText(model.name);            showSearchView.handleToolBar(MainActivity.this, card_search, toolbar, view_search, recyclerView, edit_text_search, line_divider);            Toast.makeText(getApplicationContext(), model.name + " was selected.", Toast.LENGTH_LONG).show();        }    }    public void performFiltering(List filteredSuggestions) {        filteredSuggestions.clear();        for (Model model : modelsList) {            if (model.name.toLowerCase().contains(text.toLowerCase())) {                filteredSuggestions.add(model);            }        }        CuisineSearchAdapter cuisineSearchAdapter = new CuisineSearchAdapter(cuisinesModels, filteredSuggestions, MainActivity.this, MainActivity.this, text);        cuisineSearchAdapter.notifyDataSetChanged();        recyclerView.setAdapter(cuisineSearchAdapter);    }}

The Toolbar layout is set from the menu_main.xml file as shown below.

可以从menu_main.xml文件设置工具栏布局,如下所示。

Before analysing the MainActivity.java class in detail, let’s glance at the code for ListViewAdapter with a filter. Something that we’ve already implemented .

在详细分析MainActivity.java类之前,让我们看一下带有过滤器的ListViewAdapter的代码。 我们已经实现一些东西。

The code for the ListViewAdapter.java class is given below.

下面给出了ListViewAdapter.java类的代码。

package com.journaldev.efficientsearch;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Filter;import android.widget.Filterable;import android.widget.TextView;import java.util.ArrayList;import java.util.List;public class ListViewAdapter extends BaseAdapter implements Filterable {    private List modelList;    private List mStringFilterList;    private ValueFilter valueFilter;    private class ViewHolder {        TextView vendorName;    }    public ListViewAdapter(List modelList) {        this.modelList = modelList;        mStringFilterList = modelList;    }    @Override    public int getCount() {        if (modelList != null)            return modelList.size();        else            return 0;    }    @Override    public Model getItem(int position) {        return modelList.get(position);    }    @Override    public long getItemId(int position) {        Model object = getItem(position);        if (object.isCuisine) {            return -1;        } else            return Integer.parseInt(object.id);    }    @Override    public View getView(int position, View convertView, final ViewGroup parent) {        ViewHolder holder = null;        Model vendorModel = getItem(position);        if (vendorModel.isCuisine) {            return LayoutInflater.from(parent.getContext()).inflate(R.layout.row_null, null);        } else {            if (convertView == null) {                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row_model, parent, false);                holder = new ViewHolder();                holder.vendorName = ((TextView) convertView.findViewById(R.id.txt_vendor_name));                convertView.setTag(holder);            } else {                if (holder == null) {                    convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row_model, parent, false);                    holder = new ViewHolder();                    holder.vendorName = ((TextView) convertView.findViewById(R.id.txt_vendor_name));                    convertView.setTag(holder);                } else                    holder = (ViewHolder) convertView.getTag();            }            holder.vendorName.setText(vendorModel.name);            return convertView;        }    }    @Override    public Filter getFilter() {        if (valueFilter == null) {            valueFilter = new ValueFilter();        }        return valueFilter;    }    private class ValueFilter extends Filter {        @Override        protected FilterResults performFiltering(CharSequence constraint) {            FilterResults results = new FilterResults();            if (constraint != null && constraint.length() > 0) {                List filterList = new ArrayList();                for (int i = 0; i < mStringFilterList.size(); i++) {                    if (!mStringFilterList.get(i).isCuisine) {                        if (mStringFilterList.get(i).cuisines.contains(constraint)) {                            Model model = new Model(mStringFilterList.get(i).id, mStringFilterList.get(i).name, mStringFilterList.get(i).cuisines, false, -1);                            filterList.add(model);                        }                    }                }                if (filterList.size() == 0) {                    for (int i = 0; i < mStringFilterList.size(); i++) {                        if ((mStringFilterList.get(i).name.toUpperCase())                                .contains(constraint.toString().toUpperCase()) && !mStringFilterList.get(i).isCuisine) {                            Model model = new Model(mStringFilterList.get(i).id, mStringFilterList.get(i).name, mStringFilterList.get(i).cuisines, false, -1);                            if (!model.isCuisine)                                filterList.add(model);                        }                    }                }                results.count = filterList.size();                results.values = filterList;            } else {                results.count = mStringFilterList.size();                results.values = mStringFilterList;            }            return results;        }        @Override        protected void publishResults(CharSequence constraint,                                      FilterResults results) {            modelList = (List) results.values;            notifyDataSetChanged();        }    }}

In the above class, we check the isCuisine param on each Model instance. If it’s true we add an empty row with 0 height. Else list_row_model.xml is added. The xml code for each of the layouts is given below.

在上面的类中,我们检查每个Model实例上的isCuisine参数。 如果为真,则添加一个高度为0的空行。 否则添加了list_row_model.xml 。 下面给出了每种布局的xml代码。

Clicking the search icon from the Toolbar inflates our custom Search UI and populates the RecyclerView under. To do this, the handleToolbar method is invoked on an instance from the ShowSearchView class.

The code for the ShowSearchView.java is given below.

单击工具栏中的搜索图标,将使我们的自定义搜索UI膨胀,并在下面填充RecyclerView。 为此,在ShowSearchView类的实例上调用handleToolbar方法。

下面给出了ShowSearchView.java的代码。

package com.journaldev.efficientsearch;import android.animation.Animator;import android.content.Context;import android.content.res.Resources;import android.os.Build;import android.support.v7.widget.CardView;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.Toolbar;import android.util.DisplayMetrics;import android.view.View;import android.view.ViewAnimationUtils;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;public class ShowSearchView {    public static void handleToolBar(final Context context, final CardView search, Toolbar toolbarMain, final View view, final RecyclerView recyclerView, final EditText editText, final View line_divider) {        final Animation fade_in = AnimationUtils.loadAnimation(context.getApplicationContext(), android.R.anim.fade_in);        final Animation fade_out = AnimationUtils.loadAnimation(context.getApplicationContext(), android.R.anim.fade_out);        if (search.getVisibility() == View.VISIBLE) {            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                final Animator animatorHide = ViewAnimationUtils.createCircularReveal(search,                        search.getWidth() - (int) convertDpToPixel(56, context),                        (int) convertDpToPixel(23, context),                        (float) Math.hypot(search.getWidth(), search.getHeight()),                        0);                animatorHide.addListener(new Animator.AnimatorListener() {                    @Override                    public void onAnimationStart(Animator animation) {                    }                    @Override                    public void onAnimationEnd(Animator animation) {                        view.startAnimation(fade_out);                        view.setVisibility(View.INVISIBLE);                        search.setVisibility(View.GONE);                        ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), 0);                        recyclerView.setVisibility(View.GONE);                    }                    @Override                    public void onAnimationCancel(Animator animation) {                    }                    @Override                    public void onAnimationRepeat(Animator animation) {                    }                });                animatorHide.setDuration(300);                animatorHide.start();            } else {                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), 0);                view.startAnimation(fade_out);                view.setVisibility(View.INVISIBLE);                search.setVisibility(View.GONE);            }            editText.setText("");            toolbarMain.getMenu().clear();            toolbarMain.inflateMenu(R.menu.menu_main);            search.setEnabled(false);        } else {            toolbarMain.getMenu().clear();            toolbarMain.setNavigationIcon(null);            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                final Animator animator = ViewAnimationUtils.createCircularReveal(search,                        search.getWidth() - (int) convertDpToPixel(56, context),                        (int) convertDpToPixel(23, context),                        0,                        (float) Math.hypot(search.getWidth(), search.getHeight()));                animator.addListener(new Animator.AnimatorListener() {                    @Override                    public void onAnimationStart(Animator animation) {                    }                    @Override                    public void onAnimationEnd(Animator animation) {                        view.setVisibility(View.VISIBLE);                        view.startAnimation(fade_in);                        ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);                    }                    @Override                    public void onAnimationCancel(Animator animation) {                    }                    @Override                    public void onAnimationRepeat(Animator animation) {                    }                });                search.setVisibility(View.VISIBLE);                if (search.getVisibility() == View.VISIBLE) {                    animator.setDuration(300);                    animator.start();                    search.setEnabled(true);                }                fade_in.setAnimationListener(new Animation.AnimationListener() {                    @Override                    public void onAnimationStart(Animation animation) {                    }                    @Override                    public void onAnimationEnd(Animation animation) {                        editText.requestFocus();                        recyclerView.setVisibility(View.VISIBLE);                    }                    @Override                    public void onAnimationRepeat(Animation animation) {                    }                });            } else {                search.setVisibility(View.VISIBLE);                search.setEnabled(true);                recyclerView.setVisibility(View.VISIBLE);                editText.requestFocus();                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);            }        }    }    public static float convertDpToPixel(float dp, Context context) {        Resources resources = context.getResources();        DisplayMetrics metrics = resources.getDisplayMetrics();        return dp * (metrics.densityDpi / 160f);    }}

The handleToolbar method shows/hides the custom UI depending upon the search icon/back arrow clicked respectively. The view animates in/out in the form of circular reveal animation.

handleToolbar方法根据分别单击的搜索图标/后退箭头来显示/隐藏自定义UI。 视图以圆形显示动画的形式进行动画进/出。

The RecyclerView is populated with the cuisines as well as restaurants. Though only the cuisines are displayed until the user types anything.

RecyclerView充满了美食和餐厅。 尽管仅显示美食,直到用户键入任何内容。

The adapter for the RecyclerView is defined in the class CuisinesSearchAdapter.java as shown below.

用于RecyclerView适配器在该类中定义CuisinesSearchAdapter.java如下所示。

package com.journaldev.efficientsearch;import android.content.Context;import android.graphics.Color;import android.support.v7.widget.RecyclerView;import android.text.Spannable;import android.text.SpannableString;import android.text.style.ForegroundColorSpan;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import java.text.Normalizer;import java.util.List;import java.util.Locale;public class CuisineSearchAdapter extends RecyclerView.Adapter {    Context mContext;    ItemListener mListener;    String prefix = "";    private List allVendors, cuisines;    public CuisineSearchAdapter(List cuisines, List vendorModels, Context context, ItemListener itemListener, String text) {        this.allVendors = vendorModels;        this.cuisines = cuisines;        this.mContext = context;        this.mListener = itemListener;        prefix = text;    }    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {        ImageView icon;        TextView textView;        View parent;        Model vendorModel;        MyViewHolder(View itemView) {            super(itemView);            this.parent = itemView.findViewById(R.id.parentView);            this.textView = (TextView) itemView.findViewById(R.id.textView);            this.icon = (ImageView) itemView.findViewById(R.id.imageView);            itemView.setOnClickListener(this);        }        void setData(Model model, MyViewHolder holder) {            textView = holder.textView;            icon = holder.icon;            this.vendorModel = model;            if (prefix.length() > 0) {                if (model.isCuisine) {                    textView.setText(highlight(prefix, model.name + " (" + model.numberOfCuisine + ")"));                    icon.setImageResource(R.mipmap.ic_local_offer);                } else {                    textView.setText(highlight(prefix, model.name));                    icon.setImageResource(R.mipmap.ic_local_dining);                }            } else {                if (model.isCuisine) {                    textView.setText(model.name + " (" + model.numberOfCuisine + ")");                    icon.setImageResource(R.mipmap.ic_local_offer);                }            }        }        @Override        public void onClick(View view) {            if (mListener != null) {                mListener.onItemClick(vendorModel);            }        }    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        final View view = LayoutInflater.from(parent.getContext())                .inflate(R.layout.recyclerview_list_row, parent, false);        MyViewHolder myViewHolder = new MyViewHolder(view);        return myViewHolder;    }    @Override    public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {        if (prefix.length() > 0)            holder.setData(allVendors.get(holder.getAdapterPosition()), holder);        else            holder.setData(cuisines.get(holder.getAdapterPosition()), holder);    }    @Override    public int getItemCount() {        if (prefix.length() > 0)            return allVendors.size();        else            return cuisines.size();    }    private static CharSequence highlight(String search, String originalText) {        // ignore case and accents        // the same thing should have been done for the search text        String normalizedText = Normalizer                .normalize(originalText, Normalizer.Form.NFD)                .replaceAll("\\p{InCombiningDiacriticalMarks}+", "")                .toLowerCase(Locale.ENGLISH);        int start = normalizedText.indexOf(search.toLowerCase(Locale.ENGLISH));        if (start = 0) {                int spanStart = Math.min(start, originalText.length());                int spanEnd = Math.min(start + search.length(),                        originalText.length());                highlighted.setSpan(new ForegroundColorSpan(Color.BLUE),                        spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);                start = normalizedText.indexOf(search, spanEnd);            }            return highlighted;        }    }    public interface ItemListener {        void onItemClick(Model model);    }}

The layout for each row of the RecyclerView is defined in the xml code below.

RecyclerView每行的布局在下面的xml代码中定义。

  • As the user enters text, the RecyclerView data is filtered from the performFiltering method inside the MainActivity.java class. The substrings in the RecyclerView rows that match the typed text are then highlighted.

    当用户输入文本时,将从MainActivity.java类中的performFiltering方法中过滤RecyclerView数据。 然后,RecyclerView行中与键入的文本匹配的子字符串将突出显示。
  • Clicking on a cuisine would filter the list to display all the restaurants having that cuisine as a type.
    Clicking a restaurant shall display its name in a Toast message.

    单击美食会过滤列表,以显示所有以该美食为类型的餐馆。
    单击餐厅应在​​吐司消息中显示其名称。

This brings an end to this tutorial. You can download the Android EfficientSearch Project from the link below.

本教程到此结束。 您可以从下面的链接下载Android EfficientSearch项目

翻译自:

多重搜索算法

转载地址:http://symzd.baihongyu.com/

你可能感兴趣的文章
Centos安装Python3
查看>>
PHP批量插入
查看>>
laravel连接sql server 2008
查看>>
Ubuntu菜鸟入门(五)—— 一些编程相关工具
查看>>
valgrind检测linux程序内存泄露
查看>>
Hadoop以及组件介绍
查看>>
1020 Tree Traversals (25)(25 point(s))
查看>>
第一次作业
查看>>
“==”运算符与equals()
查看>>
单工、半双工和全双工的定义
查看>>
Hdu【线段树】基础题.cpp
查看>>
时钟系统
查看>>
BiTree
查看>>
5个基于HTML5的加载动画推荐
查看>>
水平权限漏洞的修复方案
查看>>
静态链接与动态链接的区别
查看>>
Android 关于悬浮窗权限的问题
查看>>
如何使用mysql
查看>>
linux下wc命令详解
查看>>
敏捷开发中软件测试团队的职责和产出是什么?
查看>>