Extend navigation items highlighted

In my Android application, I have a navigation drawer. When an item is selected in the navigation box, it loads a new fragment and selects the element that you clicked in the navigation box.

My problem is that in a new loaded fragment, you can click on a new element inside this fragment, which loads the new fragment and still saves the navigation box.

In this instance, you are no longer on the fragment that is indicated in the navigation box, but the last item is still selected, and then you cannot click it again to return.

Any ideas on how I can highlight an item in the navigation box if it is not one of my main fragments, and then re-highlights if on one of the main fragments?

Here is my navigation box code:

public class MainDrawer2 extends FragmentActivity { private static final String EXTRA_NAV_ITEM = "extraNavItem"; private static final String STATE_CURRENT_NAV = "stateCurrentNav"; private ActionBarDrawerToggle mDrawerToggle; private DrawerLayout mDrawerLayout; private NavDrawerListAdapter mDrawerAdapter; private ListView mDrawerList; private CharSequence mTitle; private CharSequence mDrawerTitle; private MainNavItem mCurrentNavItem; public static Intent createLaunchFragmentIntent(Context context, MainNavItem navItem) { return new Intent(context, MainDrawer2.class) .putExtra(EXTRA_NAV_ITEM, navItem.ordinal()); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main); Crashlytics.start(this); mTitle = mDrawerTitle = getTitle(); mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); mDrawerList = (ListView)findViewById(R.id.drawer); getActionBar().setDisplayHomeAsUpEnabled(true); enableHomeButtonIfRequired(); mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext()); mDrawerList.setAdapter(mDrawerAdapter); mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { displayNavFragment((MainNavItem)parent.getItemAtPosition(position)); } }); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.app_name, R.string.app_name) { public void onDrawerClosed(View view) { getActionBar().setTitle(mTitle); invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle(mDrawerTitle); invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); if(getIntent().hasExtra(EXTRA_NAV_ITEM)){ MainNavItem navItem = MainNavItem.values() [getIntent().getIntExtra(EXTRA_NAV_ITEM, MainNavItem.STATISTICS.ordinal())]; displayNavFragment(navItem); } else if(savedInstanceState != null){ mCurrentNavItem = MainNavItem.values() [savedInstanceState.getInt(STATE_CURRENT_NAV)]; setCurrentNavItem(mCurrentNavItem); } else{ displayNavFragment(MainNavItem.STATISTICS); } } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) private void enableHomeButtonIfRequired() { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){ getActionBar().setHomeButtonEnabled(true); } } public void setActionBarTitle(String title) { getActionBar().setTitle(title); } @Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggles mDrawerToggle.onConfigurationChanged(newConfig); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } /* @Override public boolean onPrepareOptionsMenu(Menu menu) { // if nav drawer is opened, hide the action items boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_settings).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } */ private void displayNavFragment(MainNavItem navItem) { if(navItem == mCurrentNavItem){ return; } Fragment fragment = Fragment.instantiate(this, navItem.getFragClass().getName()); if(fragment != null){ getSupportFragmentManager().beginTransaction() .replace(R.id.main, fragment) .commit(); setCurrentNavItem(navItem); } } private void setCurrentNavItem(MainNavItem navItem) { int position = navItem.ordinal(); // If navItem is in DrawerAdapter if(position >= 0 && position < mDrawerAdapter.getCount()){ mDrawerList.setItemChecked(position, true); } else{ // navItem not in DrawerAdapter, de-select current item if(mCurrentNavItem != null){ mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false); } } mDrawerLayout.closeDrawer(mDrawerList); setTitle(navItem.getTitleResId()); mCurrentNavItem = navItem; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: if(mDrawerLayout.isDrawerOpen(mDrawerList)) { mDrawerLayout.closeDrawer(mDrawerList); } else { mDrawerLayout.openDrawer(mDrawerList); } return true; default: return super.onOptionsItemSelected(item); } } public void goToSearch(MenuItem item){ //go to search page Fragment Fragment_one; FragmentManager man= getSupportFragmentManager(); FragmentTransaction tran = man.beginTransaction(); Fragment_one = new Search(); tran.replace(R.id.main, Fragment_one);//tran. tran.addToBackStack(null); tran.commit(); } public void scanBarcode(MenuItem item){ //open scanner IntentIntegrator scanIntegrator = new IntentIntegrator(this); scanIntegrator.initiateScan(); } public void onActivityResult(int requestCode, int resultCode, Intent intent) { //retrieve scan result IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanningResult != null) { //we have a result String scanContent = scanningResult.getContents(); //todo: set scan content into setting, load new fragment which calls async task below. New //todo: fragment will have same ui as search. :-) Fragment Fragment_one; FragmentManager man= this.getSupportFragmentManager(); FragmentTransaction tran = man.beginTransaction(); Fragment_one = new BarcodeFrag(scanContent); tran.replace(R.id.main, Fragment_one);//tran. tran.addToBackStack(null); //tran.commit(); tran.commitAllowingStateLoss(); } else{ Toast toast = Toast.makeText(getApplicationContext(), "No scan data received!", Toast.LENGTH_SHORT); toast.show(); } } } 

then I have an enumeration called the main navigation element:

 public enum MainNavItem { // Displayed in NavDrawerListAdapter STATISTICS("Your Statistics", R.layout.statistics_pagelayout, StatisticsTab.class), DISCOVER ("Discover", R.layout.activity_discover, DiscoverTab.class), PORTFOLIO ("Portfolio", R.layout.activity_portfolio, Portfolio.class), LISTS ("Your Lists", R.layout.activity_search, AllLists.class), NEWS ("News", R.layout.activity_news, NewsWeb.class), Find ("Nearby Breweries", R.layout.beer_location_list, FindBrewery.class), CONTACT ("Contact", R.layout.activity_contact, ContactPage.class), // Items NOT displayed in NavDrawerListAdapter SEARCH ("Search", R.layout.activity_search, Search.class), ; private static MainNavItem LAST_NAV_ITEM = CONTACT; private String mTitleResId; private int mLayoutResId; private Class<? extends Fragment> mFragClass; private MainNavItem(String titleResId, int layoutResId, Class<? extends Fragment> fragClass) { mTitleResId = titleResId; mLayoutResId = layoutResId; mFragClass = fragClass; } public int getLayoutResId() { return mLayoutResId; } public String getTitleResId() { return mTitleResId; } public Class<? extends Fragment> getFragClass() { return mFragClass; } public static MainNavItem[] getNavAdapterItems() { int count = LAST_NAV_ITEM.ordinal() + 1; MainNavItem[] adapterItems = new MainNavItem[count]; for(int i = 0; i < count; i++){ adapterItems[i] = values()[i]; } return adapterItems; } } 

UPDATE:

I just tried to comment on these two lines in order to turn off the highlighting as a whole, so that the user could select an item in his navigation box again.

 private void setCurrentNavItem(MainNavItem navItem) { int position = navItem.ordinal(); // If navItem is in DrawerAdapter if(position >= 0 && position < mDrawerAdapter.getCount()){ //mDrawerList.setItemChecked(position, true); } else{ // navItem not in DrawerAdapter, de-select current item if(mCurrentNavItem != null){ //mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false); } } mDrawerLayout.closeDrawer(mDrawerList); setTitle(navItem.getTitleResId()); mCurrentNavItem = navItem; } 

When the application loads for the first time, nothing is highlighted, but when I click on something, it is highlighted, and I can’t click it again to reload this fragment. Any other ideas?

+6
source share
4 answers

Figured it out. The easiest way to not highlight an element in your draw in your xml for drawing linst, choiceMode should not be:

 <FrameLayout android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout> <ListView android:id="@+id/drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:divider="@android:color/white" android:background="@android:color/black" android:choiceMode="none"/> 

+4
source

I just grouped my elements as below, android: checkableBehavior = "none" . This line is very important and make sure it should be none .

 <group android:checkableBehavior="none"> <item android:id="@+id/nav_home" android:icon="@drawable/left_menu_home" android:title="@string/home" /> <item android:id="@+id/nav_account_settings" android:icon="@drawable/left_menu_account_settings" android:title="@string/accountSettings" /> </group> 

+2
source

You can deselect the menu item of the navigation explorer by calling menuItem.setChecked(false);

+1
source

Any ideas on how I can highlight an item in the navigation drawer if it is not one of my main snippets

  int toClear=mDrawerList.getCheckedItemPosition(); if (toClear >= 0) { mDrawerList.setItemChecked(toClear, false); } 

and then re-highlighted if on one of the main fragments?

Call setItemChecked() with a position that matches the visible fragment, and true for the second parameter.

This sample project demonstrates this. My use of post() to control when updating checked states in ListView bit messy, but that will be enough.

0
source

All Articles