通过SearchView过滤多个ListView

时间:2015-03-02 22:33:30

标签: android android-listview filter

我已经根据SearchView输入正确实现了一个ListView(附带标题)过滤。现在我打算让SearchView过滤几个ListViews,我想知道该怎么做。我被困住了,没有任何想法。过滤的主要原则是这样的: 我们有几个类别(即住宿,名胜古迹),它们作为标题(基本上是类别的图片)显示,每个类别都附有ListView。当用户输入搜索查询时,应用程序需要立即过滤所有ListView。窗口的结构如下:

- >当前类别的标头

ListView#1

当用户输入输入时,将显示所有可用类别,并为其应用过滤器:

- >当前类别的标头

过滤后的ListView#1

- >标题#2

过滤后的ListView#2

...

- >标题#8

过滤后的ListView#8

我寻求最清晰/最天才的方式来执行此操作。值得一提的是,我们知道确切的类别数量。

我正在发布我的代码片段(ONE ListView(附带标题)根据SearchView输入进行过滤)。此外,如果搜索没有返回任何结果,我打印该消息,以便用户可以联系我们,如果他愿意的话。 list_header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/top"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_weight="1"
        android:gravity="center">

        <View
            android:id="@+id/line_left1"
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="0.45"
            android:background="#FFFFFF" />

        <ImageView
            android:id="@+id/small_icon"
            android:layout_width="60dp"
            android:layout_height="80dp"
            android:layout_weight="0.1"
            android:src="@drawable/pavalgyk" />

        <View
            android:id="@+id/line_left2"
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="0.45"
            android:background="#FFFFFF" />

    </LinearLayout>
</LinearLayout>

alllists.xml

<?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"
    android:paddingBottom="5dp"
    android:background="@drawable/background"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:paddingTop="5dp">


    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <RelativeLayout
        android:id="@+id/relativeLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_centerHorizontal="true"
            android:layout_alignParentTop="true"
            android:background="@drawable/card"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/search_window_text"
            android:textSize="16dp"
            android:textStyle="normal"
            android:autoLink="email"
            android:fontFamily="sans-serif-light" />

    </RelativeLayout>
</LinearLayout>

AllLists.java

public class AllLists extends android.support.v4.app.Fragment {

    private TypedArray navMenuIcons;
    private Context context = null;
    private int position = 0;
    private String location;
    private List<Item> items = new ArrayList<Item>();
    private List<Item> tmp_items = new ArrayList<Item>();
    private ListView listView;
    private CustomListAdapter adapter;
    private SearchView mSearchView;
    private String tmp_s = "";
    private static Locale myLocale;
    private EasyTracker easyTracker = null;
    private RelativeLayout relativeLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.alllists, container, false);
        View header = inflater.inflate(R.layout.list_header, null);
        ImageView image = (ImageView) header.findViewById(R.id.small_icon);
        relativeLayout = (RelativeLayout) rootView.findViewById(R.id.relativeLayout);
        relativeLayout.setVisibility(View.GONE);
        setLanguage();
        navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
        Bundle bundle = getArguments();
        position = bundle.getInt("position");
        location = bundle.getString("location");
        image.setImageDrawable(navMenuIcons.getDrawable(position));
        context = getActivity().getApplicationContext();
        easyTracker = EasyTracker.getInstance(context);
        DatabaseHandler db = new DatabaseHandler(context);
        items = db.getAllItems(location);
        tmp_items = db.getAllItems(location);
        listView = (ListView) rootView.findViewById(R.id.list);
        adapter = new CustomListAdapter(context, items);
        listView.addHeaderView(header, "", false);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int list_position, long id) {
                easyTracker.send(MapBuilder.createEvent("List",
                        location, adapter.getItems().get(list_position - 1).getName(), null).build());
                if (location.equals("accommodation") || location.equals("eat") || location.equals("events")
                        || location.equals("entertainment") || location.equals("places") || location.equals("cinema")) {
                    Intent i = new Intent(context, ItemScreen.class);
                    i.putExtra("position", list_position - 1);
                    i.putExtra("location", location);
                    i.putExtra("name", adapter.getItems().get(list_position - 1).getRealName());
                    startActivity(i);
                } else if (location.equals("taxi")) {
                    Intent intent = new Intent(Intent.ACTION_DIAL);
                    intent.setData(Uri.parse("tel:" + adapter.getItems().get(list_position - 1).getType()));
                    PackageManager manager = context.getPackageManager();
                    List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
                    if (infos.size() > 0)
                        startActivity(intent);
                    else
                        Toast.makeText(context, R.string.cant_handle, Toast.LENGTH_SHORT).show();
                }
            }
        });
        setHasOptionsMenu(true);
        return rootView;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                easyTracker.send(MapBuilder.createEvent("Search",
                        "search", s, null).build());
                if (TextUtils.isEmpty(s)) {
                    adapter = new CustomListAdapter(context, tmp_items);
                    listView.setAdapter(adapter);
                }
                if (tmp_s.length() > s.length()) {
                    adapter.getFilter(tmp_items, true).filter(s, new Filter.FilterListener() {
                        public void onFilterComplete(int count) {
                            if (count == 0)
                                relativeLayout.setVisibility(View.VISIBLE);
                            else
                                relativeLayout.setVisibility(View.GONE);
                        }
                    });
                } else {
                    adapter.getFilter(tmp_items, false).filter(s, new Filter.FilterListener() {
                        @Override
                        public void onFilterComplete(int count) {
                            if (count == 0)
                                relativeLayout.setVisibility(View.VISIBLE);
                            else
                                relativeLayout.setVisibility(View.GONE);
                        }
                    });
                }
                tmp_s = s;
                return false;
            }
        });
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        mSearchView.setQuery("", false);
    }
}

CustomListAdapted.java

public class CustomListAdapter extends BaseAdapter {

    private Context context;
    private List<Item> items;
    private LayoutInflater inflater;
    private ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    public CustomListAdapter(Context context, List<Item> items) {
        this.context = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (inflater == null)
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_item, null);
        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();
        NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image);
        TextView name = (TextView) convertView.findViewById(R.id.name);
        TextView type = (TextView) convertView.findViewById(R.id.type);
        Item i = items.get(position);

        image.setImageUrl(i.getIcon(), imageLoader);
        if(items.get(0).getName().contains("taksi"))
            image.setDefaultImageResId(R.drawable.telefonas);
        else
            image.setDefaultImageResId(R.drawable.be_fono);
        name.setText(i.getRealName());
        type.setText(i.getType());
        return convertView;
    }

    public List<Item> getItems(){
        return items;
    }

    public Filter getFilter(final List<Item> all_items, final boolean deleted) {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults results = new FilterResults();
                if (charSequence == null || charSequence.length() == 0) {
                    results.values = items;
                    results.count = items.size();
                } else {
                    List<Item> filtered_items = new ArrayList<Item>();
                    if(deleted)
                        items = all_items;
                    for (int i = 0; i < items.size(); i++) {
                        String modifiedName = items.get(i).getRealName().toLowerCase();
                        String modifiedQuery = charSequence.toString().toLowerCase();
                        modifiedName = encode_lithuanian(modifiedName);
                        modifiedQuery = encode_lithuanian(modifiedQuery);
                        if (modifiedName.contains(modifiedQuery))
                            filtered_items.add(items.get(i));
                    }
                    results.values = filtered_items;
                    results.count = filtered_items.size();
                }
                return results;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                items = (List<Item>) filterResults.values;
                notifyDataSetChanged();
            }

            public int show_size(){
                return items.size();
            }
        };
    }
}

2 个答案:

答案 0 :(得分:0)

为不同的列表视图创建适配器。 然后在edittext aftertextchange监听器中为所有适配器应用文本过滤器。看看:

http://www.androidbegin.com/tutorial/android-search-listview-using-filter/

adapter1 = new ListViewAdapter(this, arraylist1);
list1.setAdapter(adapter1);
adapter2 = new ListViewAdapter(this, arraylist2);
list2.setAdapter(adapter2);    

editsearch.addTextChangedListener(new TextWatcher() {

@Override
public void afterTextChanged(Editable arg0) {
    //TODO Auto-generated method stub
    String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
    adapter1.filter(text);
    adapter2.filter(text);
    ....
}

答案 1 :(得分:0)

@ Riasat的回答激发了我的灵感,我认为可以在没有任何代码重复的情况下做到这一点:当然对于每个列表视图,你有一个适配器将或多或少相同。但是创建一个通知器可能会很棒,该通知器会对所有适配器进行刷新。类似的东西:

作为您唯一要求的接口:

/**
* Created by laurentmeyer on 03/03/15.
*/
public interface RefreshInterface {
     void refresh();
     void searchForText(String searchedText);
     void searchWithSomethingElse(Object SomethingElse);
}

然后修改适配器:

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;

/**
 * Created by laurentmeyer on 03/03/15.
 */
public class CustomListAdapter extends BaseAdapter implements RefreshInterface{
    private Context context;
    private List<Item> items;
    private LayoutInflater inflater;
    private ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    public CustomListAdapter(Context context, List<Item> items) {
        this.context = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (inflater == null)
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_item, null);
        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();
        NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image);
        TextView name = (TextView) convertView.findViewById(R.id.name);
        TextView type = (TextView) convertView.findViewById(R.id.type);
        Item i = items.get(position);

        image.setImageUrl(i.getIcon(), imageLoader);
        if(items.get(0).getName().contains("taksi"))
            image.setDefaultImageResId(R.drawable.telefonas);
        else
            image.setDefaultImageResId(R.drawable.be_fono);
        name.setText(i.getRealName());
        type.setText(i.getType());
        return convertView;
    }

    public List<Item> getItems(){
        return items;
    }

    public Filter getFilter(final List<Item> all_items, final boolean deleted) {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults results = new FilterResults();
                if (charSequence == null || charSequence.length() == 0) {
                    results.values = items;
                    results.count = items.size();
                } else {
                    List<Item> filtered_items = new ArrayList<Item>();
                    if(deleted)
                        items = all_items;
                    for (int i = 0; i < items.size(); i++) {
                        String modifiedName = items.get(i).getRealName().toLowerCase();
                        String modifiedQuery = charSequence.toString().toLowerCase();
                        modifiedName = encode_lithuanian(modifiedName);
                        modifiedQuery = encode_lithuanian(modifiedQuery);
                        if (modifiedName.contains(modifiedQuery))
                            filtered_items.add(items.get(i));
                    }
                    results.values = filtered_items;
                    results.count = filtered_items.size();
                }
                return results;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                items = (List<Item>) filterResults.values;
                notifyDataSetChanged();
            }

            public int show_size(){
                return items.size();
            }
        };
    }

    // What you'll do when you'll want to refresh (why not?)
    @Override
    public void refresh() {

    }

    // What you'll do when you'll want to search from SearchView
    @Override
    public void searchForText(String searchedText) {
    }

    // What you'll do when you'll want to have a look with another cool Object like a LatLong or some other stuff (optional, of course)
    @Override
    public void searchWithSomethingElse(Object SomethingElse) {

    }
}

然后你的片段也会改变一点,但不会像其他解决方案那样多:

import java.util.ArrayList;

/**
 * Created by laurentmeyer on 03/03/15.
 */
public class AllLists extends android.support.v4.app.Fragment {

    private TypedArray navMenuIcons;
    private Context context = null;
    private int position = 0;
    private String location;
    private List<Item> items = new ArrayList<Item>();
    private List<Item> tmp_items = new ArrayList<Item>();
    private ListView listView;
    private CustomListAdapter adapter;
    private SearchView mSearchView;
    private String tmp_s = "";
    private static Locale myLocale;
    private EasyTracker easyTracker = null;
    private RelativeLayout relativeLayout;
    /*
    Here is a modification
     */
    // Create a ArrayList containing all the adapters (which are directly connected to the listViews)
    // which will need to be refreshed by the search view. I made it static because maybe you can use
    // it in other instances and it could be easier.
    public static ArrayList<RefreshInterface> toBeRefreshed;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.alllists, container, false);
        View header = inflater.inflate(R.layout.list_header, null);
        ImageView image = (ImageView) header.findViewById(R.id.small_icon);
        relativeLayout = (RelativeLayout) rootView.findViewById(R.id.relativeLayout);
        relativeLayout.setVisibility(View.GONE);
        setLanguage();
        navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
        Bundle bundle = getArguments();
        position = bundle.getInt("position");
        location = bundle.getString("location");
        image.setImageDrawable(navMenuIcons.getDrawable(position));
        context = getActivity().getApplicationContext();
        easyTracker = EasyTracker.getInstance(context);
        DatabaseHandler db = new DatabaseHandler(context);
        items = db.getAllItems(location);
        tmp_items = db.getAllItems(location);
        listView = (ListView) rootView.findViewById(R.id.list);
        adapter = new CustomListAdapter(context, items);
        /*
        Here is a modification
         */
        toBeRefreshed.add(adapter);
        listView.addHeaderView(header, "", false);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int list_position, long id) {
                easyTracker.send(MapBuilder.createEvent("List",
                        location, adapter.getItems().get(list_position - 1).getName(), null).build());
                if (location.equals("accommodation") || location.equals("eat") || location.equals("events")
                        || location.equals("entertainment") || location.equals("places") || location.equals("cinema")) {
                    Intent i = new Intent(context, ItemScreen.class);
                    i.putExtra("position", list_position - 1);
                    i.putExtra("location", location);
                    i.putExtra("name", adapter.getItems().get(list_position - 1).getRealName());
                    startActivity(i);
                } else if (location.equals("taxi")) {
                    Intent intent = new Intent(Intent.ACTION_DIAL);
                    intent.setData(Uri.parse("tel:" + adapter.getItems().get(list_position - 1).getType()));
                    PackageManager manager = context.getPackageManager();
                    List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
                    if (infos.size() > 0)
                        startActivity(intent);
                    else
                        Toast.makeText(context, R.string.cant_handle, Toast.LENGTH_SHORT).show();
                }
            }
        });
        setHasOptionsMenu(true);
        return rootView;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                easyTracker.send(MapBuilder.createEvent("Search",
                        "search", s, null).build());
                if (TextUtils.isEmpty(s)) {
                    adapter = new CustomListAdapter(context, tmp_items);
                    listView.setAdapter(adapter);
                }
                if (tmp_s.length() > s.length()) {
                    /*
                    Here call the logic you implemented in your adapter functions like:
                    for (RefreshInterface r : toBeRefreshed){
                        r.filter(String)
                    }
                     */
                } else {
                   /*
                   Same as above
                    */
                }
                tmp_s = s;
                return false;
            }
        });
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        mSearchView.setQuery("", false);
    }
}