How to filter listview using Searchview in an activity when the list view is in fragments

别来无恙 提交于 2019-12-18 13:31:21

问题


I want to implement the following screen:

As you can see here that SearchView is in the activity which contains three tabs.Each tab is implemented using fragment which in turn contain listview.I have View Pager in the activity containing search view .View Pager is populated through fragments by using FragmentStatePagerAdapter.I want to filter the list view of the active tab by using search view.

Code of Activity containing SearchView:

   @Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.menu_friend_list_activity, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_search:
            Toast.makeText(getApplicationContext(), "Search button clicked", Toast.LENGTH_SHORT).show();

            // Associate searchable configuration with the SearchView
            SearchManager searchManager = (SearchManager) FriendsListActivity.this.getSystemService(Context.SEARCH_SERVICE);
            if (item != null) {
                searchView = (SearchView) item.getActionView();
            }
            if (searchView != null) {
                searchView.setSearchableInfo(searchManager.getSearchableInfo(FriendsListActivity.this.getComponentName()));
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }

}

menu_friend_list_activity.java

  <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/search"
        android:orderInCategory="100"
        android:title="@string/action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always|collapseActionView" />
</menu>

I am using the above mentioned code.I think i am doing something wrong here.Please help me to filter listview contained in fragment using searchview in the activity.

Edited Working Code:

After a lot of research ,i have managed to fix my issue.I am adding my code for the future reference :

1. Code of Activity containing SearchView( FriendsListActivity.java in my case)

   @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_friend_list_activity, menu);
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        if (null != searchView) {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);
        }

        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
            public boolean onQueryTextChange(String newText) {
                // this is your adapter that will be filtered
                Log.e("Text",newText);
                return false;
            }

            public boolean onQueryTextSubmit(String query) {
                //Here u can get the value "query" which is entered in the search box.

               // Log.e("Query",query);
                PagerAdapter pagerAdapter = (PagerAdapter) viewPager.getAdapter();
                for(int i = 0; i < pagerAdapter.getCount(); i++) {

                    Fragment viewPagerFragment = (Fragment) viewPager.getAdapter().instantiateItem(viewPager, i);
                    if(viewPagerFragment != null && viewPagerFragment.isAdded()) {

                        if (viewPagerFragment instanceof ChatFragment){
                            ChatFragment chatFragment = (ChatFragment) viewPagerFragment;
                            if (chatFragment != null){
                                chatFragment.beginSearch(query); // Calling the method beginSearch of ChatFragment
                            }
                        }else if (viewPagerFragment instanceof GroupsFragment){
                            GroupsFragment groupsFragment = (GroupsFragment) viewPagerFragment;
                            if (groupsFragment != null){
                                groupsFragment.beginSearch(query); // Calling the method beginSearch of GroupsFragment
                            }
                        }else if (viewPagerFragment instanceof ContactsFragment){
                            ContactsFragment contactsFragment = (ContactsFragment) viewPagerFragment;
                            if (contactsFragment != null){
                                contactsFragment.beginSearch(query); // Calling the method beginSearch of ContactsFragment
                            }
                        }
                    }
                }

                return false;

            }
        };
        searchView.setOnQueryTextListener(queryTextListener);

        return super.onCreateOptionsMenu(menu);
    }

I have used this link to find the fragment which is currently displayed in the view pager.

You can see in the above mentioned code that i am passing the query string from searchview of activity to fragment using a method name beginSearch() inside Fragment.

2.Method inside Fragment(ContactsFragment.java in my case)

public void beginSearch(String query) {
    Log.e("QueryFragment", query);
    adapter_contacts.getFilter().filter(query);
}

Here adapter_contacts is the adapter which is populating the list view of Fragment named ContactsFragment.

3.Code of Adapter(Adapter_Contacts.java in my case)

public class Adapter_Contacts extends BaseAdapter implements Filterable {
private Context context;
private List<Bean_Contacts> listContacts;
private LayoutInflater inflater;
private ApiConfiguration apiConfiguration;
List<Bean_Contacts> mStringFilterList;
ValueFilter valueFilter;


public Adapter_Contacts(Context context, List<Bean_Contacts> listContacts) {
    this.context = context;
    this.listContacts = listContacts;
    mStringFilterList = listContacts;
}


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

@Override
public Object getItem(int i) {
    return listContacts.get(i);
}

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

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    if (inflater == null)
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (view == null)
        view = inflater.inflate(R.layout.feed_item_contact_list, null);

    //Getting views
    ImageView img = (ImageView) view.findViewById(R.id.imgContact);
    TextView txtName = (TextView) view.findViewById(R.id.txtNam);
    TextView txtStatus = (TextView) view.findViewById(R.id.stats);

    Bean_Contacts bean_contacts = listContacts.get(i);
    String name = bean_contacts.getName();
    Log.e("NameAdapter", name);
    String url = bean_contacts.getUrl();
    Log.e("URLAdapter", url);
    String extension = bean_contacts.getExtension();
    String status = bean_contacts.getStatus();

    apiConfiguration = new ApiConfiguration();
    String api = apiConfiguration.getApi();
    String absoluteURL = api + "/" + url + "." + extension;
    Log.e("AbsoluteURLAdapter", absoluteURL);

    Picasso.with(context).load(absoluteURL).error(R.drawable.default_avatar).into(img); //Loading image into the circular Image view using Picasso
    txtName.setText(name);
    txtStatus.setText(status);

    return view;
}

@Override
public Filter getFilter() {
    if (valueFilter == null) {
        valueFilter = new ValueFilter();
    }
    return valueFilter;
}

private class ValueFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        String str = constraint.toString().toUpperCase();
        Log.e("constraint", str);
        FilterResults results = new FilterResults();

        if (constraint != null && constraint.length() > 0) {
            ArrayList<Bean_Contacts> filterList = new ArrayList<Bean_Contacts>();
            for (int i = 0; i < mStringFilterList.size(); i++) {
                if ((mStringFilterList.get(i).getName().toUpperCase())
                        .contains(constraint.toString().toUpperCase())) {
                    Bean_Contacts bean_contacts = mStringFilterList.get(i);
                    filterList.add(bean_contacts);
                }
            }
            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) {
        listContacts = (ArrayList<Bean_Contacts>) results.values;
        notifyDataSetChanged();
    }

}

}

Here i am using Filterable interface and Filter class.This is what i have done to implement searching contents of fragment using a single SearchView inside Activity .Please note that My Activity contains SearchView ,3 tabs and ViewPager.ViewPager is populated through fragments using FragmentStatePagerAdapter.

来源:https://stackoverflow.com/questions/36301738/how-to-filter-listview-using-searchview-in-an-activity-when-the-list-view-is-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!