无法捕捉工具栏主页button单击事件

我已经实现了最新的appcompat库,并使用Toolbar作为操作栏。 但问题是我不能赶上主页button/汉堡包图标点击事件。 我已经试过,看起来一切,但似乎并没有发现类似的问题。

这是我的Activity类:

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

这是我的NavigationDrawerFragment类:

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

当我点击一个菜单项时,日志“select项”被调用。 但是,当我点击主页button,它会打开导航抽屉,但日志“家选”永远不会被调用。 我也在我的Activity设置了onOptionsItemSelected方法,但是它仍然没有被调用。

如果你想知道什么时候点击家是一个AppCompatActivity那么你应该这样尝试:

首先告诉Android你想用你的Toolbar作为你的ActionBar

 setSupportActionBar(toolbar); 

然后设置Home来显示通过setDisplayShowHomeEnabled像这样:

 getSupportActionBar().setDisplayShowHomeEnabled(true); 

最后像往常一样收听android.R.id.home上的点击事件:

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

如果您想知道何时在AppCompatActivity以外的类中的Toolbar上单击导航button,则可以使用这些方法设置导航图标并监听点击事件。 导航图标将显示在Toolbar左侧的“主页”button所在的位置。

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

如果您想知道何时单击汉堡包以及何时抽屉打开,您已经通过onDrawerOpenedonDrawerClosed侦听这些事件,因此您需要查看这些callback是否符合您的要求。

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

在我的这个代码工作完美

这就是我如何返回到正确的片段,否则,如果您有同一级别上的多个片段,它将返回到第一个,如果你不覆盖工具栏后退button的行为。

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

我认为支持库21的正确解决scheme如下

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

我已经处理了导航抽屉里的后面和主页button

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

并在每个onViewCreated我打电话

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

我改变了DrawerLayout来获取事件,并能够消耗和事件,如果你想使用actionToggle作为回来,如果你在详细视图:

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

我们可以做的最简单的方法是将主图标更改为已知的图标,并比较可绘制的(因为android.R.id.home图标可以不同于不同的api版本

所以设置一个工具栏作为操作栏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 } } } 

在我的情况下,我不得不把图标使用:

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

然后使用默认的onOptionsItemSelected和android.R.id.home id来监听点击事件

对于任何寻找Xamarin实现的人来说(因为事件在C#中完成的方式不同),我简单地创build了这个NavClickHandler类,如下所示:

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

然后,分配一个自定义的汉堡包菜单button,如下所示:

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

最后,为抽屉菜单指定一个我之前创build的类types的ToolbarNavigationClickListener:

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

然后你有一个自定义的菜单button,处理点击事件。

试试这个代码

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

将下面的代码添加到你的onCreate()方法中

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

这就是我实现它的前材料devise,它现在似乎仍然工作,我已经切换到新的Toolbar 。 在我的情况下,我想login用户,如果他们尝试在注销时打开侧边导航(并捕获事件,所以侧导航不会打开)。 在你的情况下,你不能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); }