2014-04-20 13 views
6

Nella mia app per Android dispongo di un cassetto di navigazione con scorrimento. Quando un oggetto è selezionato nel pannello di navigazione, carica il nuovo frammento e mette in evidenza l'elemento su cui hai fatto clic nel cassetto di navigazione.Espandi gli elementi di navigazione che rimangono evidenziati

Il mio problema è che nel nuovo frammento che è stato caricato è possibile fare clic su un nuovo oggetto all'interno di quel frammento che carica un nuovo frammento e conserva ancora il cassetto di navigazione.

In questa istanza non ci si trova più su un frammento elencato nel cassetto di navigazione, ma l'ultimo elemento è ancora evidenziato e quindi non è possibile fare nuovamente clic per tornare indietro.

Qualche idea su come posso deselezionare un elemento nel cassetto di navigazione quando non è uno dei miei frammenti principali e quindi essere ri-evidenziato se su uno dei frammenti principali?

Ecco il mio codice di navigazione cassetto:

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(); 
     } 

    } 


} 

allora ho un enum chiamato principale voce di navigazione:

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:

Ho appena provato a commentare queste due linee per disattivare l'evidenziazione in generale in modo che un utente possa nuovamente selezionare un elemento nella mia navigazione cassetto delle istruzioni.

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; 
    } 

All'avvio del app per il tempo abeti ora, nulla è evidenziato, ma quando clicco su qualcosa di venire messo in evidenza e non posso fare di nuovo clic per ricaricare quel frammento. Altre idee?

risposta

4

Capito.Il modo più semplice per non ha un elemento in un pareggio evidenziato è in XML per il linst pareggio, choiceMode dovrebbe essere nessuno:

<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"/> 

+0

O semplicemente non aggiungere choiceMode? – Sarvan

0

Tutte le idee su come posso non-evidenziare un elemento nel cassetto di navigazione quando non è uno dei miei principali frammenti

int toClear=mDrawerList.getCheckedItemPosition(); 

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

e poi essere nuovamente messo in evidenza se da un dei principali frammenti?

chiamata setItemChecked() con la posizione corrispondente al frammento visibile e true per il secondo parametro.

This sample project dimostra questo. L'utilizzo di post() da controllare quando aggiorniamo gli stati controllati nello ListView è un po 'sciatto, ma sarà sufficiente.

+0

Posso inserire questo codice nei frammenti che non voglio le cose evidenziate in? int toClear = mDrawerList.getCheckedItemPosition(); if (toClear> = 0) { mDrawerList.setItemChecked (toClear, false); } – Mike

+0

@Mike: Beh, i frammenti non hanno il cassetto, quindi non hanno 'mDrawerList'. E direi che non è la decisione dei frammenti se sono o meno nel cassetto, in quanto il cassetto è un problema di attività, non un problema di frammentazione. – CommonsWare

+0

quindi sono un po 'confuso su come funziona il codice sopra. Come farebbe a sapere quando non evidenziare un oggetto nel cassetto della nav? – Mike

1

È possibile deselezionare una voce di menu cassetto di navigazione chiamando menuItem.setChecked(false);

2

ho appena raggruppato i miei oggetti come indicato di seguito, Android: checkableBehavior = "none" questa linea è molto importante e assicurarsi che dovrebbe essere nessuno.

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

Problemi correlati