Как я могу обнаружить щелчок по заголовку ActionBar?

Для конкретных требований клиента мне нужно разрешить пользователю моего приложения (не будет опубликовано в Market) щелкнуть заголовок ActionBar для выполнения некоторых действий.

Я искал в источнике Android, но не могу найти идентификатор для названия actionBar TextView.

Есть ли правильный способ обработки таких кликов?


person Waza_Be    schedule 02.11.2011    source источник


Ответы (3)


Название не кликабельно, AFAIK. Значок/логотип кликабельны — вы получите это через android.R.id.home в onOptionsItemSelected(). Предположительно, название также ведет таким образом, хотя они не упоминают об этом, и я бы не стал на это полагаться.

Похоже, вы хотите, чтобы Spinner пользователь выбирал действия для выполнения. Если это так, используйте setListNavigationCallbacks(). Если вы хотите удалить заголовок как ненужный, используйте setDisplayOptions(0, DISPLAY_SHOW_TITLE).

Если вы хотите что-то другое, кроме Spinner в левой части панели действий, используйте setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM) и setCustomView(). Обратите внимание, что этот подход не рекомендуется ("Избегайте использования пользовательских режимов навигации в панель действий"), так как она может плохо работать с телефонами, особенно в портретном режиме.

Другой возможностью было бы удалить заголовок и использовать логотип вместо значка, а в логотипе сделать «заголовок» частью изображения. Весь логотип должен быть кликабельным, подниматься через onOptionsItemSelected().

person CommonsWare    schedule 02.11.2011
comment
Вы сказали, что можете обнаружить событие, когда пользователь щелкнул логотип Android ActionBar, добавив следующее: @Override public boolean onOptionsItemSelected (элемент MenuItem) { if(item.getItemId() == android.R.id.home) {/ /Пользователь нажал на логотип ActionBar } return true;// остановить системную обработку } Но для меня это не работает. Также я пробовал с onTouchEvent X и Y события (не очень хорошо...), но это тоже не работает. Я был бы признателен, если бы вы могли помочь мне там - person OlivierM; 17.10.2012
comment
@OlivierM: Вам нужно позвонить setHomeButtonEnabled() на ActionBar, если вы работаете на Android 4.0 или выше. В Android 3.x такого метода не существовало и он был не нужен. - person CommonsWare; 17.10.2012
comment
К вашему сведению, начиная с 4.2.2 заголовок и значок рассматриваются как один элемент. - person Flynn81; 20.06.2013
comment
Хотя я понимаю, почему вы не должны реализовывать свои собственные пользовательские режимы навигации, как еще я могу установить определенный шрифт для своего заголовка, кроме как с помощью setCustomView с моими собственными TextView? Не приятно, правда... - person Zordid; 24.06.2013
comment
Но в приложении WhatsApp вы обнаружите, что название также кликабельно. - person Rojesh; 27.01.2014
comment
Спиннеры (раскрывающиеся меню ActionBar) описаны здесь: developer.android. com/guide/topics/ui/actionbar.html#Dropdown - person caw; 12.02.2014
comment
Можно ли как настроить счетчик (сделанный setNavigationMode(ActionBar.NAVIGATION_MODE_LIST)) , так и получить ссылку на него, чтобы программно обрабатывать некоторые операции с ним? - person android developer; 22.05.2014
comment
@androiddeveloper: нет поддерживаемого способа получить файл Spinner. Технически это вообще не должно быть реализовано Spinner. - person CommonsWare; 22.05.2014
comment
@CommonsWare Так что лучше всего использовать setCustomView и делать все так, как вы хотите, верно? Думаю, это к лучшему. - person android developer; 22.05.2014
comment
@androiddeveloper: До тех пор, пока вы не сделаете что-то, что заставит ваших пользователей сходить с ума? Риск сделать что-то подобное NAVIGATION_MODE_LIST без того, чтобы на самом деле быть NAVIGATION_MODE_LIST, — это сверхъестественная долина, где ваш подход отличается тонкими способами, которые вызывают тревогу у пользователей. - person CommonsWare; 22.05.2014
comment
@CommonsWare Я рассматривал возможность использования NAVIGATION_MODE_LIST только потому, что не знал о setCustomView, поэтому я планировал сделать его похожим на title&subtitle и сам обрабатывать щелчки. Предполагалось, что это будет обходной путь, и пользовательский интерфейс (как я и планировал) будет выглядеть так же. Я делаю это для компании, которая хочет иметь что-то вроде WhatsApp, в котором щелчок по заголовку позволяет настроить текущую группу. Я высказал свое мнение, что это немного странно, но это их выбор. Во всяком случае, setCustomView работает нормально, поэтому нет необходимости в этом странном обходном пути (который мне даже не удалось сделать). - person android developer; 22.05.2014
comment
не забудьте установитьHasOptionsMenu(true); в onCreate() фрагмента, чтобы onOptionsItemSelected() работал. - person Robert; 24.09.2014

// при создании

ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayShowTitleEnabled(false);
//        View actionBarView = getLayoutInflater().inflate(R.layout.action_bar_custom_view, null);
        actionBar.setCustomView(actionBarView);
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

//your logic for click listner
 setListenerForActionBarCustomView(actionBarView);

 private void setListenerForActionBarCustomView(View actionBarView) {
        ActionBarCustomViewOnClickListener actionBarCustomViewOnClickListener = new ActionBarCustomViewOnClickListener();
        actionBarView.findViewById(R.id.text_view_title).setOnClickListener(actionBarCustomViewOnClickListener);
}
 private class ActionBarCustomViewOnClickListener implements OnClickListener {
        public void onClick(View v) {       
        switch(v.getId()) {
            case R.id.text_view_title:

                //finish();
                break;
    }
}
person Padma Kumar    schedule 02.11.2011
comment
Можно ли точно имитировать способ отображения заголовка и подзаголовка панели действий, чтобы он выглядел как щелчок по обычным? - person android developer; 21.05.2014

Вы можете настроить пользовательскую панель инструментов из библиотеки поддержки, объявив <android.support.v7.widget.Toolbar> в своем макете (см. ответ Криса Бейнса для полного макета панели инструментов) пример).

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- We use a Toolbar so that our drawer can be displayed
             in front of the action bar -->
        <android.support.v7.widget.Toolbar
            android:id="@+id/my_awesome_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/main_toolbar" 
            android:minHeight="?attr/actionBarSize" />

       <FrameLayout 
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />


</LinearLayout>

После того, как вы можете добавить прослушиватель кликов в свою активность, как и в большинство других представлений.

Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
toolbar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MyActivity.this, "Test", Toast.LENGTH_LONG).show();
            }
        });

Если вы хотите зафиксировать события прикосновения к заголовку:

toolbar.setOnTouchListener(new View.OnTouchListener() {
            Rect hitrect = new Rect();
            public boolean onTouch(View v, MotionEvent event) {
                if (MotionEvent.ACTION_DOWN == event.getAction()) {
                    boolean hit = false;
                    for (int i = toolbar.getChildCount() - 1; i != -1; i--) {
                        View view = toolbar.getChildAt(i);
                        if (view instanceof TextView) {
                            view.getHitRect(hitrect);
                            if (hitrect.contains((int)event.getX(), (int)event.getY())) {
                                hit = true;
                                break;
                            }
                        }
                    }
                    if (hit) {
                        //Hit action
                    }
                }
                return false;
            }
        });
person Boris Treukhov    schedule 10.11.2015