[英]Set OnClick Listener on Action Bar Title in Android
我正在開發使用ActionBar
android 應用程序,因此有一個導航抽屜圖標可以打開它,以及ActionBar
中ActionBar
標題。 我想在ActionBar
標題上設置一個單擊偵聽器,以便它啟動一個新的Activity
並在導航抽屜圖標上設置不同的單擊偵聽器以打開導航抽屜菜單。
我點擊了導航抽屜圖標,但是當我點擊ActionBar
標題的標題時,它也會打開導航抽屜菜單。 有沒有辦法在ActionBar
標題上設置不同的點擊偵聽器。
提前致謝。
嘗試在 onCreate() 函數下添加此代碼。 這將獲取操作欄標題所在的資源,並為其分配一個可用於添加 OnClickListener 的 ID。 讓我知道事情的后續!
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>
我認為Simas 的答案是最好的答案,但如果您願意,這里有一個 hacky 版本。
ViewTools.findActionBarTitle(getWindow().getDecorView()).setOnClickListener(...);
這個應該是通用的,因為它適用於:
ActionBar
Theme.AppCompat
支持ActionBar
setActionBar
<Toolbar android:id="@+id/action_bar"
root
身份傳入膨脹的Toolbar
setSupportActionBar
<android.support.v7.widget.Toolbar android:id="@id/action_bar"
root
身份傳入膨脹的Toolbar
Toolbar
實現可能需要一些調整,雖然我只測試了 support: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 而不是 Toolbar,請使用以下命令:
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);
}
});
}
}
}
如果您知道標題中的實際文本,並且您有理由確定屏幕上沒有其他TextView
共享該標題,則可以使用遞歸視圖樹搜索來查找它。
這是一個很好的解決方案,因為它不需要反映如何構建 Toolbar 的內部知識,並且可以讓您直接訪問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
}
您可以使用工具欄輕松完成此操作。 在布局 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();
}
});
我知道在這里發表評論已經很晚了,但是當我搜索如何為操作欄標題添加 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();
我知道為時已晚,但是對於像這樣使用SupportActionBar
並且仍然沒有找到干凈的解決方案的人:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
對於沒有徽標和自定義視圖的默認配置,第一項(索引 0)將是 Home/Back ImageView,第二項將是我們的 Title TextView,第三項將是 OptionMenu Imageview。
在索引 1 處獲取孩子將返回標題。 向孩子添加一個OnClickListener
將使它像一個 chram 一樣工作:
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.
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.