Не удается уловить событие нажатия кнопки кнопки панели инструментов
Я реализовал новейшую библиотеку appcompat и использовал Toolbar
качестве Toolbar
действий. Но проблема в том, что я не могу поймать значок кнопки home / hamburger icon click. Я пробовал и смотрел все, но, похоже, не нашел подобной проблемы.
Это мой class 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); }
И это мой class NavigationDrawerFragment:
- Как оживить Burger в Arrow с помощью Appcompat v7 21, панели инструментов и DrawerLayout
- Избегайте панели в autoHide в расширении Firefox
- В каком порядке панели наиболее эффективны с точки зрения времени и производительности?
- Панель c # для рисования графики и прокрутки
- Как скрыть строку состояния iOS
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); }
когда я щелкнул элемент меню, вызывается журнал «item selected». Но когда я нажимаю на кнопку «домой», она открывает навигационный ящик, но журнал «home selected» никогда не вызывается. Я также установил метод onOptionsItemSelected
внутри своей Activity
, но он все равно не вызван.
- Панель навигации под панелью инструментов
- Создание SearchView, который выглядит как руководство по разработке материалов
- Изменить размер для строки состояния вызова?
- Как скрыть навигационную панель постоянно в андроид-активности?
- Изменение цвета фона отдельных элементов меню навигации
- Контекстные стили Actionbar
- Добавление вертикальной полосы прокрутки в AlertDialog в Android?
- Чат клиента смайликов окно JAVA
Если вы хотите узнать, когда нажимается домашняя страница, это 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); }
Если вы хотите узнать, нажата ли кнопка навигации на Toolbar
в classе, отличном от AppCompatActivity
вы можете использовать эти методы для установки значка навигации и прослушивания событий клика на нем. Значок навигации появится в левой части Toolbar
где раньше использовалась кнопка «home».
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"); } });
Если вы хотите узнать, когда щелкнул гамбургер, и когда откроется ящик, вы уже слушаете эти события через onDrawerOpened
и onDrawerClosed
чтобы вы захотели узнать, соответствуют ли эти обратные вызовы вашим требованиям.
mActionBarDrawerToggle = mNavigationDrawerFragment.getActionBarDrawerToggle(); mActionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // event when click home button } });
в моем коде этот код работает отлично
Вот как я делаю это, чтобы вернуться к правильному fragmentу, иначе, если у вас есть несколько fragmentов на одном уровне, они вернутся к первому, если вы не переопределите поведение кнопки панели инструментов.
toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { finish(); } });
Я думаю, что правильное решение с библиотекой поддержки 21 является следующим
// 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 } }); }
Я обратился к кнопке «Домой» в навигационном ящике, как
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"); }
Именно так я реализовал его до материального дизайна, и, похоже, он все еще работает, теперь я переключился на новую Toolbar
. В моем случае я хочу войти в систему, если они попытаются открыть боковой навигатор во время выхода из системы (и поймать событие, чтобы сторона nav не открывалась). В вашем случае вы не можете 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); }
Я немного изменил 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
* NOTE: 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
* NOTE: 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 #), я просто создал этот class 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); } } }
Затем назначается пользовательская кнопка меню гамбургера:
SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetDefaultDisplayHomeAsUpEnabled(false); this.drawerToggle.DrawerIndicatorEnabled = false; this.drawerToggle.SetHomeAsUpIndicator(Resource.Drawable.MenuButton);
И, наконец, назначил меню ящика toggler ToolbarNavigationClickListener типа classа, который я создал ранее:
this.drawerToggle.ToolbarNavigationClickListener = new NavClickHandler(this);
И тогда у вас есть пользовательская кнопка меню, с обработкой кликов.
Попробуйте этот код
@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);