2014-10-27 8 views
88

Ich habe die neueste appcompat-Bibliothek implementiert und die Toolbar als Aktionsleiste verwendet. Aber das Problem ist, dass ich das Home-Button/Hamburger-Icon-Click-Event nicht verstehen kann. Ich habe versucht und alles geschaut, aber scheint kein ähnliches Problem zu finden.Ich kann die Symbolleiste nicht fangen home button click event

Das ist mein Activity Klasse:

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

    toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    // Set up the drawer. 
    navDrawerFragment = 
     (NavigationDrawerFragment) getSupportFragmentManager() 
     .findFragmentById(R.id.navigation_drawer); 
    navDrawerFragment.setUp(
     R.id.navigation_drawer, 
     (DrawerLayout) findViewById(R.id.drawer_layout), 
     toolbar); 
} 

Und das ist meine NavigationDrawerFragment Klasse:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if (savedInstanceState != null) { 
     currentSelectedPosition = savedInstanceState.getInt(
      STATE_SELECTED_POSITION); 
     fromSavedInstanceState = true; 
    } 

    // Select either the default item (0) or the last selected item. 
    selectItem(currentSelectedPosition); 
} 

@Override 
public void onActivityCreated (Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    // Indicate that this fragment would like 
    // to influence the set of actions in the action bar. 
    setHasOptionsMenu(true); 
} 

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     drawerListView = (ListView) inflater.inflate(
      R.layout.fragment_navigation_drawer, container, false); 
     drawerListView.setOnItemClickListener(
      new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, 
       View view, int position, long id) { 
       selectItem(position); 
      } 
     }); 
     //mDrawerListView.setAdapter(); 
     //mDrawerListView.setItemChecked(mCurrentSelectedPosition, true); 
     return drawerListView; 
} 

public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) { 
    fragmentContainerView = getActivity().findViewById(fragmentId); 
    this.drawerLayout = drawerLayout; 

    // set a custom shadow that overlays the main 
    // content when the drawer opens 
    drawerLayout.setDrawerShadow(
     R.drawable.drawer_shadow, GravityCompat.START); 
    // set up the drawer's list view 
    // with items and click listener 

    ActionBar actionBar = getActionBar(); 
    actionBar.setDisplayHomeAsUpEnabled(true); 
    actionBar.setHomeButtonEnabled(true); 

    // ActionBarDrawerToggle ties together the the proper interactions 
    // between the navigation drawer and the action bar app icon. 
    drawerToggle = new ActionBarDrawerToggle(
     getActivity(), 
     drawerLayout, 
     toolbar, 
     R.string.navigation_drawer_open, 
     R.string.navigation_drawer_close) { 
     public void onDrawerClosed(View view) { 
      super.onDrawerClosed(view); 
     } 

     public void onDrawerOpened(View drawerView) { 
      super.onDrawerOpened(drawerView); 
     } 
    }; 

    // If the user hasn't 'learned' about the drawer, 
    // open it to introduce them to the drawer, 
    // per the navigation drawer design guidelines. 
    if (!userLearnedDrawer && !fromSavedInstanceState) { 
     drawerLayout.openDrawer(fragmentContainerView); 
    } 

    // Defer code dependent on restoration of previous instance state. 
    drawerLayout.post(new Runnable() { 
     @Override 
     public void run() { 
      drawerToggle.syncState(); 
     } 
    }); 

    drawerLayout.setDrawerListener(drawerToggle); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition); 
} 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    // Forward the new configuration the drawer toggle component. 
    drawerToggle.onConfigurationChanged(newConfig); 
} 

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    super.onCreateOptionsMenu(menu, inflater); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    Log.d("cek", "item selected"); 
    if (drawerToggle.onOptionsItemSelected(item)) { 
     Log.d("cek", "home selected"); 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

, wenn ich einen Menüpunkt geklickt haben, das Protokoll "Element ausgewählt" aufgerufen wird. Aber wenn ich auf die Home-Taste klicke, öffnet sich die Navigationsleiste, aber das Logbuch "home selected" wird nie aufgerufen. Ich habe auch onOptionsItemSelected Methode in meinem Activity gesetzt, aber es wird immer noch nicht aufgerufen.

Antwort

194

Wenn Sie wissen wollen, wenn zu Hause angeklickt wird, ist ein AppCompatActivity dann sollten Sie es so versuchen:

Erste Android sagen Sie Ihren Toolbar als Ihr verwenden ActionBar:

setSupportActionBar(toolbar); 

Dann Home einstellen, um über setDisplayShowHomeEnabled wie folgt angezeigt zu werden:

getSupportActionBar().setDisplayShowHomeEnabled(true); 

Schließlich hört für Click-Ereignisse auf android.R.id.home wie üblich:

@Override 
public boolean onOptionsItemSelected(MenuItem menuItem) { 
    if (menuItem.getItemId() == android.R.id.home) { 
     Timber.d("Home pressed"); 
    } 
    return super.onOptionsItemSelected(menuItem); 
} 

Wenn Sie wissen möchten, wenn die Navigationstaste auf eine Toolbar in einer anderen Klasse als AppCompatActivity geklickt wird Sie diese Methoden verwenden können, ein Navigationssymbol einstellen und auf Klickereignisse achten. Das Navigationssymbol erscheint auf der linken Seite Ihres Toolbar, wo der "Home" -Knopf war.

toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_nav_back)); 
toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Log.d("cek", "home selected"); 
    } 
}); 

Wenn Sie wissen möchten, wenn der Hamburger geklickt wird und wenn die Schublade geöffnet wird, sind Sie bereits für diese Ereignisse über onDrawerOpened hören und onDrawerClosed so werden Sie sehen wollen, wenn diese Rückrufe Ihren Anforderungen entsprechen.

+1

Versuchte den ersten Teil vor, aber es funktioniert nicht. Versucht den zweiten Teil, und es funktioniert. Aber das Symbol ändert sich nicht, wenn ich die Symbolleiste mit der Nav-Schublade registriere. Noch eine Frage, gibt es dafür einen Ersatz für setDrawerIndicatorEnabled? Ich habe mit dieser neuen Nav-Schublade versucht und Fehler bekommen. Vielen Dank –

+0

Zweite Lösung funktioniert. Aber wie können wir in der zweiten Lösung den Home Button Clicked und den Drawer Button erkennen? Wenn ich auf das Schubladensymbol klicke, wird die Schublade nicht geöffnet. – Dory

+2

Wenn SieNavigationOnClickListener für die Symbolleiste setzen, dann verlieren Sie "native" Schubladenverhalten :( – IlyaEremin

-1

Dies ist, wie ich es vor dem Material-Design implementiert und es scheint immer noch zu arbeiten, jetzt habe ich auf die neue Toolbar gewechselt. In meinem Fall möchte ich den Benutzer anmelden, wenn er versucht, das Seiten-Navi zu öffnen, während es ausgeloggt ist (und das Ereignis abfangen, so dass das Seiten-Nav nicht geöffnet wird). In Ihrem Fall könnten Sie nicht return true;.

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    if (!isLoggedIn() && item.getItemId() == android.R.id.home) { 
     login(); 
     return true; 
    } 
    return mDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item); 
} 
+0

bereits versucht, immer noch nicht funktioniert .. –

+0

Ah, ich habe vergessen, dass ich nicht in der Lage war, den Home-Button in einem Fragment zu fangen. Ich stellte hier eine Frage und schlug eine Problemumgehung vor, die das Event manuell auf alle Fragmente verteilen sollte. http://StackOverflow.com/Q/21938419/1007151 – darnmason

2

ich glaube, die richtige Lösung mit Support-Bibliothek 21 die

// action_bar is def resource of appcompat; 
// if you have not provided your own toolbar I mean 
Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar); 
if (toolbar != null) { 
    // change home icon if you wish 
    toolbar.setLogo(this.getResValues().homeIconDrawable()); 
    toolbar.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //catch here title and home icon click       
     }      
    });     
} 
+0

in 'this.getResValues ​​(). HomeIconDrawable()', Wer ist 'this'? – LuisComS

+0

Dies ist eine Aktivität. Getresvalues ​​ist meine Methode, daher ist es hier nicht relevant. Setlogo akzeptiert eine auszeichnungsfähige Ressourcen-ID. –

+2

das wird Benutzer klicken an jeder wo auf der gesamten Symbolleiste, ich glaube nicht das, was er gefragt hat –

0

ich die DrawerLayout ein wenig verändert finden, die Ereignisse zu bekommen und in der Lage sein, zu konsumieren und Ereignis, wie wenn Sie die actionToggle verwenden möchten wie zurück, wenn Sie sind in der Detailansicht:

public class ListenableDrawerLayout extends DrawerLayout { 

    private OnToggleButtonClickedListener mOnToggleButtonClickedListener; 
    private boolean mManualCall; 

    public ListenableDrawerLayout(Context context) { 
     super(context); 
    } 

    public ListenableDrawerLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public ListenableDrawerLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    /** 
    * Sets the listener for the toggle button 
    * 
    * @param mOnToggleButtonClickedListener 
    */ 
    public void setOnToggleButtonClickedListener(OnToggleButtonClickedListener mOnToggleButtonClickedListener) { 
     this.mOnToggleButtonClickedListener = mOnToggleButtonClickedListener; 
    } 

    /** 
    * Opens the navigation drawer manually from code<br> 
    * <b>NOTE: </b>Use this function instead of the normal openDrawer method 
    * 
    * @param drawerView 
    */ 
    public void openDrawerManual(View drawerView) { 
     mManualCall = true; 
     openDrawer(drawerView); 
    } 

    /** 
    * Closes the navigation drawer manually from code<br> 
    * <b>NOTE: </b>Use this function instead of the normal closeDrawer method 
    * 
    * @param drawerView 
    */ 
    public void closeDrawerManual(View drawerView) { 
     mManualCall = true; 
     closeDrawer(drawerView); 
    } 


    @Override 
    public void openDrawer(View drawerView) { 

     // Check for listener and for not manual open 
     if (!mManualCall && mOnToggleButtonClickedListener != null) { 

      // Notify the listener and behave on its reaction 
      if (mOnToggleButtonClickedListener.toggleOpenDrawer()) { 
       return; 
      } 

     } 
     // Manual call done 
     mManualCall = false; 

     // Let the drawer layout to its stuff 
     super.openDrawer(drawerView); 
    } 

    @Override 
    public void closeDrawer(View drawerView) { 

     // Check for listener and for not manual close 
     if (!mManualCall && mOnToggleButtonClickedListener != null) { 

      // Notify the listener and behave on its reaction 
      if (mOnToggleButtonClickedListener.toggleCloseDrawer()) { 
       return; 
      } 

     } 
     // Manual call done 
     mManualCall = false; 

     // Let the drawer layout to its stuff 
     super.closeDrawer(drawerView); 
    } 

    /** 
    * Interface for toggle button callbacks 
    */ 
    public static interface OnToggleButtonClickedListener { 

     /** 
     * The ActionBarDrawerToggle has been pressed in order to open the drawer 
     * 
     * @return true if we want to consume the event, false if we want the normal behaviour 
     */ 
     public boolean toggleOpenDrawer(); 

     /** 
     * The ActionBarDrawerToggle has been pressed in order to close the drawer 
     * 
     * @return true if we want to consume the event, false if we want the normal behaviour 
     */ 
     public boolean toggleCloseDrawer(); 
    } 

} 
21
mActionBarDrawerToggle = mNavigationDrawerFragment.getActionBarDrawerToggle(); 
    mActionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      // event when click home button 
     } 
    }); 

in myCASE dieser Code Arbeit perfekt

+0

Sie sind wirklich gut, es hat funktioniert, ich hätte nie gedacht, dass ich Symbolleiste zurück Knopf durch DrawerToggle .. –

+0

Um ActionBarDrawerToggle zu haben .setToolbarNavigationClickListener muss zuerst aufgerufen werden: mActionBarDrawerToggle.setHomeAsUpIndicator (R.drawable.menu_icon); mActionBarDrawerToggle.setDrawerIndicatorEnabled (false); und verwalten Sie die Click-Ereignisse selbst. (Öffnen/Schließen der Schublade beim Klicken) – luky

6

So mache ich es, um zum rechten Fragment zurückzukehren. Wenn Sie sonst mehrere Fragmente auf derselben Ebene haben, kehrt es zur ersten zurück, wenn Sie das Verhalten der Symbolleiste auf der Schaltfläche nicht überschreiben.

toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      finish(); 
     } 
    }); 
1

Ich habe zurück und Home-Taste in Navigationsleiste behandelt wie

public class HomeActivity extends AppCompatActivity 
     implements NavigationView.OnNavigationItemSelectedListener { 
    private ActionBarDrawerToggle drawerToggle; 
    private DrawerLayout drawerLayout; 
    NavigationView navigationView; 
    private Context context; 

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

     setContentView(R.layout.activity_home); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     resetActionBar(); 

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

     //showing first fragment on Start 
     getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).replace(R.id.content_fragment, new FirstFragment()).commit(); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     //listener for home 
     if(id==android.R.id.home) 
     { 
      if (getSupportFragmentManager().getBackStackEntryCount() > 0) 
       onBackPressed(); 
      else 
       drawerLayout.openDrawer(navigationView); 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onBackPressed() { 
     if (drawerLayout.isDrawerOpen(GravityCompat.START)) 
      drawerLayout.closeDrawer(GravityCompat.START); 
     else 
      super.onBackPressed(); 
    } 

    @Override 
    public boolean onNavigationItemSelected(MenuItem item) { 
     // Begin the transaction 

     Fragment fragment = null; 
     // Handle navigation view item clicks here. 
     int id = item.getItemId(); 
     DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
     if (id == R.id.nav_companies_list) { 
      fragment = new FirstFragment(); 
      // Handle the action 
     } 


     // Begin the transaction 
     if(fragment!=null){ 

      if(item.isChecked()){ 
       if(getSupportFragmentManager().getBackStackEntryCount()==0){ 
        drawer.closeDrawers(); 
      }else{ 
        removeAllFragments(); 
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE).replace(R.id.WikiCompany, fragment).commit(); 
        drawer.closeDrawer(GravityCompat.START); 
       } 

      }else{ 
       removeAllFragments(); 
       getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE).replace(R.id.WikiCompany, fragment).commit(); 
       drawer.closeDrawer(GravityCompat.START); 
      } 
     } 

     return true; 
    } 

    public void removeAllFragments(){ 
     getSupportFragmentManager().popBackStackImmediate(null, 
       FragmentManager.POP_BACK_STACK_INCLUSIVE); 
    } 

    public void replaceFragment(final Fragment fragment) { 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) 
       .replace(R.id.WikiCompany, fragment).addToBackStack("") 
       .commit(); 
    } 


    public void updateDrawerIcon() { 
     final Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Log.i("", "BackStackCount: " + getSupportFragmentManager().getBackStackEntryCount()); 
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) 
         drawerToggle.setDrawerIndicatorEnabled(false); 
        else 
         drawerToggle.setDrawerIndicatorEnabled(true); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }, 50); 
    } 

    public void resetActionBar() 
    { 
     //display home 
     getSupportActionBar().setDisplayShowHomeEnabled(true); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     getSupportActionBar().setHomeButtonEnabled(true); 
    } 

    public void setActionBarTitle(String title) { 
     getSupportActionBar().setTitle(title); 
    } 
} 

und jeder in onViewCreated Ich nenne

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    ((HomeActivity)getActivity()).updateDrawerIcon(); 
    ((HomeActivity) getActivity()).setActionBarTitle("List"); 
} 
0

Der einfachste Ansatz, den wir ändern tun können, ist das Home-Symbol zu einem bekannten Symbol und vergleichen Sie Zeichen (weil android.R.id.home-Symbol kann zu verschiedenen API-Versionen abweichen

also eine Symbolleiste als Aktionsleiste festlegen SetSupportActionBar (_toolbar);

_toolbar.NavigationIcon = your_known_drawable_here; 

    for (int i = 0; i < _toolbar.ChildCount; i++) 
      { 
       View v = _toolbar.GetChildAt(i); 
       if (v is ImageButton) 
       { 
        ImageButton imageButton = v as ImageButton; 

        if (imageButton.Drawable.GetConstantState().Equals(_bookMarkIcon.GetConstantState())) 
        { 
         //here v is the widget that contains the home icon you can add your click events here 
        } 
       } 
      } 
0

In meinem Fall hatte ich das Symbol setzen mit:

toolbar.setNavigationIcon(R.drawable.ic_my_home); 
setSupportActionBar(toolbar); 
getSupportActionBar().setDisplayShowHomeEnabled(true); 
getSupportActionBar().setHomeButtonEnabled(true); 

Und dann hören Ereignisse mit Standard onOptionsItemSelected und android.R.id.home id

+1

Dies funktioniert nicht. 'android.R.id.home' niemals feuern – Trancer

0

Für jedermann zu klicken suchen für eine Xamarin-Implementierung (da Ereignisse in C# anders ausgeführt werden), habe ich einfach diese NavClickHandler Klasse wie folgt erstellt:

public class NavClickHandler : Java.Lang.Object, View.IOnClickListener 
{ 
    private Activity mActivity; 
    public NavClickHandler(Activity activity) 
    { 
     this.mActivity = activity; 
    } 
    public void OnClick(View v) 
    { 
     DrawerLayout drawer = (DrawerLayout)mActivity.FindViewById(Resource.Id.drawer_layout); 
     if (drawer.IsDrawerOpen(GravityCompat.Start)) 
     { 
      drawer.CloseDrawer(GravityCompat.Start); 
     } 
     else 
     { 
      drawer.OpenDrawer(GravityCompat.Start); 
     } 
    } 
} 

Dann Taste eine benutzerdefinierte Hamburger Menü zugewiesen, wie folgt aus:

 SupportActionBar.SetDisplayHomeAsUpEnabled(true); 
     SupportActionBar.SetDefaultDisplayHomeAsUpEnabled(false); 
     this.drawerToggle.DrawerIndicatorEnabled = false; 
     this.drawerToggle.SetHomeAsUpIndicator(Resource.Drawable.MenuButton); 

Und schließlich zugewiesen, die Schublade Menü toggler eine ToolbarNavigationClickListener der Klassentyp habe ich früher:

 this.drawerToggle.ToolbarNavigationClickListener = new NavClickHandler(this); 

Und dann haben Sie Ich habe eine benutzerdefinierte Menüschaltfläche erhalten, bei der Click-Ereignisse behandelt wurden.

0

diesen Code Versuchen

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    int id = item.getItemId(); 
    if(id == android.R.id.home){ 
     //You can get 
    } 
    return super.onOptionsItemSelected(item); 
} 

Code unten in Ihre onCreate() metod

ActionBar ab = getSupportActionBar(); 
    ab.setDisplayHomeAsUpEnabled(true);