Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SearchView with multiple fragments using viewpager in android

I want to implement SearchView with multiple fragments present in a viewPager. All fragemnts contains lists and I want to filter those lists and create a new ListView which has categorization of results based upon which fragment it belongs to.

But my searchView is not working with one fragment.

Here is my main activity:

package com.codeon.directory;

import android.app.SearchManager;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import com.codeon.directory.fragments.FiveFragment;
import com.codeon.directory.fragments.FourFragment;
import com.codeon.directory.fragments.OneFragment;
import com.codeon.directory.fragments.SixFragment;
import com.codeon.directory.fragments.ThreeFragment;
import com.codeon.directory.fragments.TwoFragment;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Nikhil Jain on 21-Sep-15.
 */
public class TabEffect extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager viewPager;
    public String pic[] = {"1","2","3","1","2","3","1","2","3","1","2","3","1","2","3"};
    public String state[] = {"A","B","C"};
    public String city[] = {"P","Q","R"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tablayout);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.tab, menu);

        // Associate searchable configuration with the SearchView
        SearchManager searchManager =
                (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView =
                (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));
        return true;
    }

    private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        Bundle bundle = new Bundle();
        bundle.putStringArray("pic", pic);
        bundle.putStringArray("district", city);
        bundle.putStringArray("state", state);
        adapter.addFragment(new OneFragment(), "ONE FRAGMENT", bundle);
        adapter.addFragment(new TwoFragment(), "TWO FRAGMENT", bundle);
        adapter.addFragment(new ThreeFragment(), "THREE FRAGMENT", bundle);
        adapter.addFragment(new FourFragment(), "FOUR FRAGMENT", bundle);
        adapter.addFragment(new FiveFragment(), "FIVE FRAGMENT", bundle);
        adapter.addFragment(new SixFragment(), "SIX FRAGMENT", bundle);
        viewPager.setAdapter(adapter);
    }

    class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

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

        public void addFragment(Fragment fragment, String title, Bundle args) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
            fragment.setArguments(args);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }
}

This is my first fragment :

package com.codeon.directory.fragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.codeon.directory.R;
import com.codeon.directory.RecyclerAdapter;
import com.codeon.directory.customadapters.Listitems_new;

import java.util.ArrayList;

/**
 * Created by Nikhil Jain on 21-Sep-15.
 */
public class OneFragment extends Fragment {

    ListView list;
    private ArrayAdapter<String> listAdapter ;

    public OneFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        RecyclerView rootView = (RecyclerView) inflater.inflate(R.layout.fragment_one, container, false);
        // Inflate the layout for this fragment
        Bundle extras = getArguments();
        String pic[] = extras.getStringArray("pic");
        String state[] = extras.getStringArray("state");
        Log.e("VALUE",pic[0]+pic[1]+pic[2]);

        rootView.setLayoutManager(new LinearLayoutManager(rootView.getContext()));
        //listAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, pic);
        rootView.setAdapter(new RecyclerAdapter(pic));
        return rootView;
    }
}

My SearchActivity:

package com.codeon.directory;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

/**
  * Created by Nikhil Jain on 21-Sep-15.
*/
public class SearchActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search);

    // Get the intent, verify the action and get the query
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        doMySearch(query);
        Log.e("QUERY", query);
    }
}

private void doMySearch(String query) {

}
}

This is my AndroidManifest.xml:

<activity
        android:name=".TabEffect"
        android:label="@string/tablayout"
        android:theme="@style/AppTheme" >
    </activity>
    <activity android:name=".SearchActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
            android:resource="@layout/searchable"/>
    </activity>

This is my Searchable layout:

<?xml version="1.0" encoding="utf-8"?>
<searchable
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/search_hint"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"/>

For simple, I want to implement searchView like in Whatsapp.

enter image description here

like image 766
Nikhil Jain Avatar asked Sep 24 '15 14:09

Nikhil Jain


People also ask

What is difference between ViewPager and ViewPager2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .

How do you get ViewPager fragments?

ViewPager save Fragment in FragmentManager with particular tags, So We can get ViewPager's fragment by FragmentManager class by providing tag. And ViewPager provide tag to each fragment by following syntax : Fragment page = getSupportFragmentManager(). findFragmentByTag("android:switcher:" + R.


1 Answers

@Chintan is right. We need to use ViewModel. Follow this.

  1. Create SearchViewModel:

'''

private MutableLiveData<String> query= new MutableLiveData<String>();

public void setQuery(String queryData)
{
    query.setValue(queryData);
}

public LiveData<String> getQuery() {
    return query;
}

'''

  1. SearchParentFragment

'''

public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    inflater.inflate(R.menu.search_menu, menu);
    super.onCreateOptionsMenu(menu, inflater);

    final MenuItem myMenuItem = menu.findItem(R.id.search_icon);

    searchViewModel = new ViewModelProvider(requireActivity()).get(SearchViewModel.class);

    searchView = (SearchView) myMenuItem.getActionView();
    searchView.setQueryHint("Search");
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            searchViewModel.setQuery(newText);
            return false;
        }
    });
}

'''

  1. For each Child Fragment (tabs)

'''

public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    searchViewModel = new ViewModelProvider(requireActivity()).get(SearchViewModel.class);
    searchViewModel.getQuery().observe(getViewLifecycleOwner(), new Observer<String>() {
        @Override
        public void onChanged(String s) {
            if (s!=null)
            {adapter.getFilter().filter(s);
        }
    });
}

'''

A single query will work for all tabs.) I studied it for a long time, but this solution works for me.

like image 196
Любовь Avatar answered Sep 23 '22 17:09

Любовь