17

Ich arbeite an Android-Anwendung, wo ich ActionBar verwenden, so gibt es eine Navigation Schublade Symbol, um es zu öffnen und Titel ActionBar in ActionBar. Ich möchte einen Klick-Listener auf den Titel ActionBar setzen, so dass es einen neuen Activity startet und Klick-Listener auf das Symbol der Navigationsleiste anders setzt, um das Menü der Navigationsleiste zu öffnen.Set OnClick Listener auf Action Bar Titel in Android

Ich habe einen Klick auf Navigation Schublade Symbol, aber wenn ich auf Titel von ActionBar Titel auch dann öffnen Sie die Navigation Schublade Menü. Gibt es eine Möglichkeit, einen anderen Klick-Listener auf den Titel ActionBar zu setzen.

Vielen Dank im Voraus.

+0

Ist es das gleiche, das Sie suchen? [Wie kann ich einen Klick auf den ActionBar-Titel erkennen?] (Http://stackoverflow.com/questions/7981394/how-can-i-detect-a-click-on-the-actionbar-title) –

+0

@PareshMayani so das ist nicht möglich ? –

Antwort

18

Versuchen Sie, diesen Code unter der onCreate() - Funktion hinzuzufügen. Dies wird die Ressource, unter der der Titel der Aktionsleiste steht, erfassen und ihr eine ID zuweisen, mit der Sie einen OnClickListener hinzufügen können. Lass mich wissen wie es geht!

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

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

+1 Wirklich wundervoller Trick. Nie vorgestellt. Vielen Dank. –

+0

Hallo, dieser Ansatz funktioniert nicht in Android OS 2.3, nicht sicher über 4.0-4.3, ich habe getestet, es funktioniert in Android 4.4.4. Bitte assistieren Sie –

+0

@Williams 2.3 hat keine Aktionsleiste. Sie können: 'your.R.id.action_bar_title' anstelle von' getIdentifier' verwenden, wenn Sie 'appcompat-v7' verwenden. Sie können nach beiden IDs fragen und die vorhandene ID verwenden. – TWiStErRob

13

Sie können ein benutzerdefiniertes Layout für den Titel verwenden und einen Listener zuweisen:

@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> 
+2

Leider verliert man so die Fähigkeit zu "getActionBar(). SetTitle"() 'und Sie müssen auch Untertitelhandling implementieren, aber ansonsten ist dies die richtige Lösung. Es wäre schön, wenn jemand einen Titel von "ActionBarTitles" als Drop-In-Ersatz-Ansicht veröffentlicht, die Titel/Untertitel unterstützt und das Thema liest. – TWiStErRob

6

Wenn Sie Toolbar mit Unterstützung verwenden v7: 21. den folgenden Code Check out:

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 

      } 
     }); 
9

Ich denke Simas's answer ist die beste, aber hier ist eine Hacky Version, falls Sie das bevorzugen.

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

Diese sollte universal sein, dass es funktioniert mit:

  • Lager Android ActionBar
  • Theme.AppCompat Unterstützung ActionBar
  • v21-Stil setActionBar
    Verwendung <Toolbar android:id="@+id/action_bar"
    oder in dem aufgeblasenen Toolbar als root
  • v21-Stil setSupportActionBar
    Verwendung <android.support.v7.widget.Toolbar android:id="@id/action_bar"
    oder Pass in den aufgeblasenen Toolbar als root
  • benutzerdefinierten Toolbar Implementierungen passieren, eine wenig Anpassung benötigt
    aber dann könnte man kapseln das in dieser benutzerdefinierten Klasse.

Obwohl ich nur mit Unterstützung getestet: 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; 
} 
+0

Ist es möglich, dass sich der 'resourceName' in zukünftigen Versionen der Support-Bibliothek ändert? –

+0

@bwicks Sehr unwahrscheinlich, aber ja. Es ist wahrscheinlich nicht wichtig, weil die Ressourcennamen zum Zeitpunkt der Kompilierung gesperrt sind. Obwohl sie eine neue Support-Lib-Version veröffentlichen, sollte Ihre App sicher sein, da sie die alte Version enthält. Das heißt, bis Sie Ihre Abhängigkeiten aktualisieren, erstellen und erneut veröffentlichen. Beachten Sie auch, dass 'R.id.action_bar_title' eine öffentliche Ressource ist, während der' android.R.id.action_bar_title' es nicht spiegelt (deshalb wird 'getIdentifier' verwendet). Sie sollten sich mehr Sorgen darüber machen, dass die Android-Plattform den Namen ändert, für den der Kompilierungszeitschutz nicht gilt. – TWiStErRob

2

Sie können dies tun Toolbar einfach mit.Definieren Sie Symbolleiste in Dateilayout xml wie unten angegeben:

<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> 

Dann Sie den Hörer in Aktivität einstellen können diesen Code verwenden:

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 
     } 
    }); 
0

Wenn Sie den eigentlichen Text kennen, die in Ihrem Titel, und Sie sind ziemlich sicher, dass kein anderer TextView auf dem Bildschirm diesen Titel teilt, können Sie eine rekursive View-Baumsuche verwenden, um es zu finden.

Dies ist eine großartige Lösung, da es keine Reflektion der internen Kenntnisse über die Erstellung der Toolbar erfordert und Ihnen direkten Zugriff auf die TextView gibt.

@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; 
} 

Die zuverlässigste Ansicht, dies zu fordern ist das Dekor Ansicht, aber das Gefühl frei zu experimentieren, was am besten für Ihre Zwecke arbeitet, die Leistung kann variieren.

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