Установить OnClick Listener на заголовке панели действий в Android

Я работаю над приложением Android, где я использую ActionBar так что есть значок навигации, чтобы открыть его и название ActionBar в ActionBar, Я хочу установить прослушиватель кликов по названию ActionBar такой, чтобы начать новый Activity и установите щелчок слушателя на значке навигационной панели, чтобы открыть меню навигационной панели.

Я нажал на значок навигационной панели, но когда я нажал на заголовок ActionBar Кроме того, можно открыть меню навигации. Есть ли способ установить другой слушатель клика по названию ActionBar,

Заранее спасибо.

11 ответов

Решение

Попробуйте добавить этот код в функцию onCreate(). Это захватит ресурс, под которым находится заголовок панели действий, и назначит ему идентификатор, который вы можете использовать для добавления OnClickListener. Дайте мне знать, как это происходит!

final int abTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
findViewById(abTitleId).setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
    //Do something
    }
});

Вы можете использовать собственный макет для заголовка и назначить для него слушателя:

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

    ActionBar actionBar = getActionBar();
    if (actionBar != null) {
        // Disable the default and enable the custom
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
        View customView = getLayoutInflater().inflate(R.layout.actionbar_title, null);
        // Get the textview of the title
        TextView customTitle = (TextView) customView.findViewById(R.id.actionbarTitle);


        // Change the font family (optional)
        customTitle.setTypeface(Typeface.MONOSPACE);
        // Set the on click listener for the title
        customTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.w("MainActivity", "ActionBar's title clicked.");
            }
        });
        // Apply the custom view
        actionBar.setCustomView(customView);
    }
}

actionbar_title.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:id="@+id/actionbarTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="@string/app_name"/>

</LinearLayout>

Я думаю, что ответ Симаса - лучший, но вот хакерская версия, если вы предпочитаете это.

ViewTools.findActionBarTitle(getWindow().getDecorView()).setOnClickListener(...);

Этот должен быть универсальным в том, что он работает с:

  • фондовый Android ActionBar
  • Theme.AppCompat служба поддержки ActionBar
  • v21-стиль setActionBar
    использование <Toolbar android:id="@+id/action_bar"
    или перейти в раздутый Toolbar как root
  • v21-стиль setSupportActionBar
    использование <android.support.v7.widget.Toolbar android:id="@id/action_bar"
    или перейти в раздутый Toolbar как root
  • обычай Toolbar реализации могут потребовать небольшой корректировки,
    но тогда вы можете заключить это в этот пользовательский класс.

Хотя я тестировал только с поддержкой:v22.

/** @param root usually Activity.getWindow().getDecorView() or your custom Toolbar */
public static @Nullable View findActionBarTitle(@NonNull View root) {
    return findActionBarItem(root, "action_bar_title", "mTitleTextView");
}
/** @param root usually Activity.getWindow().getDecorView() or your custom Toolbar */
public static @Nullable View findActionBarSubTitle(@NonNull View root) {
    return findActionBarItem(root, "action_bar_subtitle", "mSubtitleTextView");
}

private static @Nullable View findActionBarItem(@NonNull View root,
        @NonNull String resourceName, @NonNull String toolbarFieldName) {
    View result = findViewSupportOrAndroid(root, resourceName);

    if (result == null) {
        View actionBar = findViewSupportOrAndroid(root, "action_bar");
        if (actionBar != null) {
            result = reflectiveRead(actionBar, toolbarFieldName);
        }
    }
    if (result == null && root.getClass().getName().endsWith("widget.Toolbar")) {
        result = reflectiveRead(root, toolbarFieldName);
    }
    return result;
}

@SuppressWarnings("ConstantConditions")
private static @Nullable View findViewSupportOrAndroid(@NonNull View root, @NonNull String resourceName) {
    Context context = root.getContext();
    View result = null;
    if (result == null) {
        int supportID = context.getResources().getIdentifier(resourceName, "id", context.getPackageName());
        result = root.findViewById(supportID);
    }
    if (result == null) {
        int androidID = context.getResources().getIdentifier(resourceName, "id", "android");
        result = root.findViewById(androidID);
    }
    return result;
}

@SuppressWarnings("unchecked")
public static <T> @Nullable T reflectiveRead(@NonNull Object object, @NonNull String fieldName) {
    try {
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return (T)field.get(object);
    } catch (Exception ex) {
        Log.w("HACK", "Cannot read " + fieldName + " in " + object, ex);
    }
    return null;
}

Если вы используете панель инструментов с поддержкой v7:21. Проверьте следующий код:

Field titleField = Toolbar.class.getDeclaredField("mTitleTextView");
        titleField.setAccessible(true);
        TextView barTitleView = (TextView) titleField.get(mToolbar);
        barTitleView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });

Вы можете сделать это легко с помощью панели инструментов. Определите панель инструментов в файле макета XML, как показано ниже:

 <android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize"
    android:background="?colorPrimary"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <TextView
        android:id="@+id/toolbarTitle"
        style="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
        android:background="?attr/selectableItemBackground"
        android:layout_width="wrap_content"
        android:gravity="center_vertical"
        android:layout_height="match_parent" />
</android.support.v7.widget.Toolbar>

Затем вы можете установить слушателя в Activity, используя этот код:

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

TextView toolbarTitle= (TextView) findViewById(R.id.toolbarTitle);
toolbarTitle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // DO SOMETHING HERE
        }
    });

Если вы хотите использовать существующую в данный момент панель действий, а не панель инструментов, используйте следующее:

ActionBar actBar = getSupportActionBar();
if(actBar != null) {
    actBar.setTitle(R.string.your_ab_title);
 }

//Set actions to take when the AB is clicked
Toolbar ab = findViewById(R.id.action_bar);
if(ab != null){
    for (int i= 0; i < ab.getChildCount(); i++){

        View child = ab.getChildAt(i);

        if(child instanceof TextView || child instanceof ImageView) {
            child.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String url = "http://www.HoverDroids.com";

                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(url));
                    startActivity(i);
                }
            });
        }
     }
}    

Я знаю, что уже слишком поздно, но для тех, кто использует SupportActionBar вот так и до сих пор не нашли чистого решения:

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

Для конфигурации по умолчанию без логотипа и пользовательских представлений, 1-й элемент (индекс 0) будет Home / Back ImageView, 2-й элемент будет нашим Title TextView, а 3-й элемент будет OptionMenu Imageview.

Получение дочернего элемента по индексу 1 вернет заголовок. Добавление OnClickListener ребенку заставит работать как чрам:

          Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    toolbar.getChildAt(1).setOnClickListener(v -> {
       // title is clicked, call ur function here
       
       // can also verify that the view is title itself by converting it to textview
       try {
            String title  = ((TextView)v).getText().toString();
            // title will be your activity title 
        } catch (Exception e) {
            e.printStackTrace();
            // if you got an exception, the view is not title. 
            // Check changing the index, in case you have custom views in the toolbar.
        }
    });

Если вы знаете фактический текст, который есть в вашем названии, и вы достаточно уверены, что никакой другой TextView на экране разделяет этот заголовок, вы можете использовать рекурсивный поиск по дереву, чтобы найти его.

Это отличное решение, потому что оно не требует отражения внутренних знаний о том, как строится панель инструментов, и дает вам прямой доступ к TextView,

@Nullable
public static TextView findTextViewWithText(@Nullable View toCheck, String toFind) {

    if (toCheck instanceof TextView) {
        String foundText = ((TextView) toCheck).getText().toString();
        if (foundText.equals(toFind)) {
            return (TextView) toCheck;
        }

    } else if (toCheck instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) toCheck).getChildCount(); i++) {
            TextView found = findTextViewWithText(((ViewGroup) toCheck).getChildAt(i), toFind);
            if (found != null) {
                return found;
            }
        }
    }
    return null;
}

Самый надежный вид, которым можно это назвать, - это вид декора, но не стесняйтесь экспериментировать, что лучше всего подходит для ваших целей, ваш пробег может варьироваться.

View found = findTextViewWithText(
    getActivity().getWindow().getDecorView(), "My Title");
if (found != null) {
  // Do something, like set a click listener
}

Существует класс ToolbarUtils:

Он предоставляет методыgetTitleTextView()иgetSubtitleTextView(), однако вам нужно добавить@SuppressLint({"RestrictedApi"})к вашему методу, так как в противном случае он не скомпилируется.

Я знаю, что уже очень поздно комментировать здесь, но я столкнулся с этим вопросом, когда искал, как добавить заголовок OnClick для панели действий. Ниже я нашел и работал для меня, надеюсь, это поможет кому-то вроде меня.

Я написал его для фрагмента в своем приложении.

        ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
        actionBar.setTitle(""); 
        ((AppCompatActivity) getActivity()).setSupportActionBar((Toolbar) getActivity().findViewById(R.id.toolbar));
        TextView toolbarTitle = (TextView) getActivity().findViewById(R.id.toolbarTitle);
        toolbarTitle.setText("New title");
        toolbarTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              // Action bar title clicked
            }
        });
        actionBar.show();

Вы можете сделать это легко с помощью панели инструментов. Определите панель инструментов в файле макета XML, как показано ниже:

    <android.support.v7.widget.Toolbar
    android:id="@+id/MainActivityToolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    app:layout_scrollFlags="scroll|enterAlways"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="@string/app_name"
            android:textSize="30sp"
            tools:ignore="RelativeOverlap"

            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            />
        <Button
            android:id="@+id/LogOutButton"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"

            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"

            android:text="@string/logout" />
    </RelativeLayout>

</android.support.v7.widget.Toolbar>

Затем вы можете установить слушателя в Activity, используя этот код:

setSupportActionBar((Toolbar) findViewById(R.id.MainActivityToolbar));

logOutButton =  findViewById(R.id.LogOutButton);
logOutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
   //define your function for logout or something else 
   LogOut();
 }
});