Установите OnClick Listener на заголовок Action Bar в Android
Я работаю над андроидным приложением, где я использую ActionBar
, поэтому есть значок навигационного ящика, чтобы открыть его и заголовок ActionBar
в ActionBar
. Я хочу настроить прослушиватель кликов на заголовок ActionBar
таким образом, чтобы он запускал новый Activity
и устанавливал кнопку прослушивания, различную для значка навигационного ящика, чтобы открыть меню навигационного ящика.
Я получил щелчок на значке навигационного ящика, но когда я нажимаю заголовок ActionBar
title, тогда он открывает меню ящика навигации. Есть ли способ установить различный прослушиватель кликов на заголовок ActionBar
.
Спасибо заранее.
Ответы
Ответ 1
Попробуйте добавить этот код под функцию 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
}
});
Ответ 2
Вы можете использовать собственный макет для заголовка и назначить ему прослушиватель:
@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 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>
Ответ 3
Я думаю, Simas answer является лучшим, но здесь взломанная версия, если вы этого предпочтете.
ViewTools.findActionBarTitle(getWindow().getDecorView()).setOnClickListener(...);
Этот должен быть универсальным, поскольку он работает с:
- stock 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;
}
Ответ 4
Если вы используете панель инструментов с поддержкой 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
}
});
Ответ 5
Вы можете легко сделать это с помощью панели инструментов. Определите панель инструментов в 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
}
});
Ответ 6
Если вы знаете фактический текст, который находится в вашем заголовке, и вы уверены, что никакие другие 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
}