问题
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