Implement Searchview with Navigation Drawer and Fragment inside

蹲街弑〆低调 提交于 2019-12-31 06:56:07

问题


I want to implement SearchView on the toolbar in Navigation-Drawer and there is Fragment Activity like in the picture. I've tried SearchView on regular Activity and I succeeded, but when I implement it to Fragment Activity, why its code can not run.

This is my Main Activity.java

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

public static final String MAKAN = "makanan";
public static String WHERE = "makanan";
public static int WHERE2;

String mQuery;
ArrayList<Makanan> mlist = new ArrayList<>();
ArrayList<Makanan> mlistAll = new ArrayList<>();
public String mQuery2;
boolean isFiltered;
MakananAdapter mAdapter;
ArrayList<Integer> mListMapFilter = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    View header = ((NavigationView)findViewById(R.id.nav_view)).getHeaderView(0);
    ImageButton ib = (ImageButton)header.findViewById(R.id.imageButton);
    ib.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, MapsActivity.class);
            startActivity(intent);
        }
    });

setTitle("Beranda");
    Hal1 fragment = new Hal1();
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.frame, fragment, "fragment1");
    //WHERE = "11";
    fragmentTransaction.commit();
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        setTitle("About");
        Hal2 fragments = new Hal2();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, fragments, "fragment1");
        fragmentTransaction.commit();
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.frag_all) {
        setTitle("Rekomendasi");
        SecondFragment fragment = new SecondFragment();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, fragment, "fragment1");
        WHERE = "11";
        fragmentTransaction.commit();
    } ...

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}}

And My SecondFragment.java

public class SecondFragment extends Fragment implements MakananAdapter.IMakananAdapter, SearchView.OnQueryTextListener {


public static final String MAKAN = "makanan";
    private AppCompatActivity compat;
private RecyclerView recyclerView;
private MakananAdapter adapter;

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

ArrayList<Makanan> mList = new ArrayList<>();
//MakananAdapter mAdapter;

String mQuery;
ArrayList<Makanan> mlist = new ArrayList<>();
ArrayList<Makanan> mlistAll = new ArrayList<>();
boolean isFiltered;

MakananAdapter mAdapter;
ArrayList<Integer> mListMapFilter = new ArrayList<>();

private SearchView searchView = null;
private SearchView.OnQueryTextListener queryTextListener;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootview = inflater.inflate(R.layout.activity_calling, container, false);
    recyclerView = (RecyclerView) rootview.findViewById(R.id.recyclerView);

    GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 2);
    recyclerView .setHasFixedSize(true);
    recyclerView .setItemAnimator(new DefaultItemAnimator());
    recyclerView .setLayoutManager(gridLayoutManager);

    recyclerView.setLayoutManager(gridLayoutManager);

    adapter = new MakananAdapter(mList);
    recyclerView.setAdapter(adapter);

    return rootview;
}

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

    fillData1();

//if i use this call method, the function is work
//[enter image description here][1]doFilter("roker");


}


private void fillData1() {
    Resources resources = getResources();
    String[] arJudul = resources.getStringArray(R.array.recommend);
    String[] arDeskripsi = resources.getStringArray(R.array.recommend_desc);
    String[] arHarga = resources.getStringArray(R.array.recommend_price);
    String[] arDetail = resources.getStringArray(R.array.recommend_details);
    String[] arLokasi = resources.getStringArray(R.array.recommend_locations);
    String[] arLat = resources.getStringArray(R.array.recommend_lat);
    String[] arLng = resources.getStringArray(R.array.recommend_longi);
    TypedArray a = resources.obtainTypedArray(R.array.recommend_pict);
    String[] arFoto = new String[a.length()];
    for (int i = 0; i < arFoto.length; i++) {
        int id = a.getResourceId(i, 0);

        arFoto[i] = ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
                + resources.getResourcePackageName(id) + '/'
                + resources.getResourceTypeName(id) + '/'
                + resources.getResourceEntryName(id) + '/';
    }
    a.recycle();

    for (int i = 0; i < arJudul.length; i++) {
        mList.add(new Makanan(arJudul[i], arDeskripsi[i], arFoto[i], arHarga[i], arDetail[i], arLokasi[i], arLat[i], arLng[i]));
    }

}



@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.main, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    searchView.setQueryHint("Cari");

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            //Log.i("onQueryTextSubmit", query);
            //mQuery = query.toLowerCase();
            //doFilter(mQuery);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            Log.i("onQueryTextChange", newText);
            mQuery = newText.toLowerCase();
            doFilter(mQuery);
            return true;
        }
    });
    return;
}

//My filter function goes here
public boolean doFilter(String query) {
    if (!isFiltered) {
        mlistAll.clear();
        mlistAll.addAll(mList);
        isFiltered = true;
    }

    mList.clear();
    if (query.isEmpty()) {
        mList.addAll(mlistAll);
        isFiltered = false;
        return false;
    } else {
        mListMapFilter.clear();
        for (int i = 0; i < mlistAll.size(); i++) {
            Makanan makanan = mlistAll.get(i);
            if (makanan.judul.toLowerCase().contains(query) ||
                    makanan.deskripsi.toLowerCase().contains(query)) {
                mList.add(makanan);
                mListMapFilter.add(i);
            }
        }

        return true;
    }

}

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    return true;
}

@Override
public void doClick(int pos) {
    Intent intent = new Intent(getContext(), DetailActivity.class);
    intent.putExtra(MAKAN, mList.get(pos));
    startActivity(intent);
}}

So, my question is how to run the doFilter function with query by user input ? Is that possible ? thanks in advance

Image link [1]: https://ibb.co/fFO3gQ - doFilter not work [2]: https://ibb.co/dYXw1Q - static doFilter work


回答1:


Assuming that you have added searchable.xml into res/xml/ project directory and in your AndroidManifest.xml, you have declared the MainActivity as searchable activity.

1. Add menu.xml into res/menu folder containing menu item that uses SearchView using app:actionViewClass="android.support.v7.widget.SearchView"

<item
    android:id="@+id/action_search"
    android:icon="@drawable/ic_action_search"
    android:title="@string/search_hint"
    app:showAsAction="collapseActionView|ifRoom"
    app:actionViewClass="android.support.v7.widget.SearchView" />

2. Setup SearchView and add SearchView.setOnQueryTextListener to your MainActivity.

3. Ony add a static Filter function into your Fragment class. For example:

    public static void doFilter(String searchQuery) {
        ...........
        ....................
    }

Update your MainActivity as below:

public class MainActivity extends AppCompatActivity {

    Context mContext;

    // Default active navigation menu
    int mActiveMenu;

    // TAGS
    public static final int MENU_FIRST = 0;
    public static final int MENU_SECOND = 1;

    // Action bar search widget
    SearchView searchView;
    String searchQuery = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;

        ................
        ...........................

        // FirstFragment will show when app launch
        mActiveMenu = MENU_FIRST;
        displayViewWithFragment(mActiveMenu);

        // NavigationView
        mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {

                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId())
                {
                    case R.id.navigation_item_first:
                    {
                        // First
                        displayViewWithFragment(MENU_FIRST);

                        return true;
                    }
                    case R.id.navigation_item_second:
                    {
                        // Second
                        displayViewWithFragment(MENU_SECOND);

                        return true;
                    }
                    default:
                        return true;
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);

        // Getting search action from action bar and setting up search view
        MenuItem searchItem = menu.findItem(R.id.action_search);
        searchView = (SearchView)searchItem.getActionView();

        // Setup searchView
        setupSearchView(searchItem);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        // Handle action bar actions click
        switch (item.getItemId())
        {
            case R.id.action_search:
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    // Search widget
    private void setupSearchView(MenuItem searchItem)
    {
        SearchManager searchManager = (SearchManager) this.getSystemService(Context.SEARCH_SERVICE);
        if (searchManager != null)
        {
            SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
            searchView.setSearchableInfo(info);
        }

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String newText)
            {
                searchQuery = newText;

                // Load search data on respective fragment
                if(mActiveMenu == MENU_FIRST)   // First
                {
                    FirstFragment.doFilter(newText);
                }
                else if(mActiveMenu == MENU_SECOND) // Second
                {
                    SecondFragment.doFilter(newText);
                }
                return true;
            }

            @Override
            public boolean onQueryTextSubmit(String query) {
                //searchView.clearFocus();
                return false;
            }
        });

        // Handling focus change of search view
        searchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {

                // Focus changed after pressing back key or pressing done in keyboard
                if (!hasFocus) {
                    searchQuery = "";
                }
            }
        });
    }

    /**
     * Displaying fragment view for selected nav drawer list item
     * */
    private void displayViewWithFragment(final int position) {

        // Active menu
        mActiveMenu = position;

        Fragment fragment = null;
        switch (position)
        {
            case MENU_FIRST:
            {
                // First
                fragment = new FirstFragment();
            }
            break;

            case MENU_SECOND:
            {
                // Second
                fragment = new SecondFragment();
            }
            break;

            default:
                break;
        }

        if (fragment != null)
        {
            mFragmentTransition = getSupportFragmentManager().beginTransaction();
            mFragmentTransition.replace(R.id.frame_container, fragment);
            mFragmentTransition.commit();
        }
    }
}

Add filter function to FirstFragment:

public static void doFilter(String searchQuery)
{
    // Filter codes here
    ...................
    .............................

    // Update RecyclerView
    adapter.notifyDataSetChanged();
}

Hope this will help~



来源:https://stackoverflow.com/questions/43553983/implement-searchview-with-navigation-drawer-and-fragment-inside

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