17

Sto lavorando all'applicazione Android in cui sto utilizzando ActionBar quindi ce n'è uno per l'icona del cassetto di navigazione per aprirlo e il titolo di ActionBar in ActionBar. Voglio impostare un ascoltatore di clic sul titolo ActionBar in modo che inizi un nuovo Activity e imposta il listener dei clic diverso sull'icona del riquadro di navigazione per aprire il menu del cassetto di navigazione.Impostare Listener OnClick su Action Bar Titolo in Android

Ho ottenuto un clic sull'icona del riquadro di navigazione ma quando faccio clic sul titolo ActionBar, si apre anche il menu del cassetto di navigazione. C'è un modo per impostare diversi click listener sul titolo ActionBar.

Grazie in anticipo.

+0

È lo stesso che stai cercando? [Come posso rilevare un clic sul titolo ActionBar?] (Http://stackoverflow.com/questions/7981394/how-can-i-detect-a-click-on-the-actionbar-title) –

+0

@PareshMayani così non è possibile ? –

risposta

18

Prova ad aggiungere questo codice sotto la funzione onCreate(). Questo raccoglierà la risorsa sotto il titolo della barra delle azioni e assegnerà un ID che è possibile utilizzare per aggiungere un OnClickListener. Fammi sapere come va!

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 Trucco davvero meraviglioso. Mai immaginato Grazie. –

+0

Ciao, questo approccio non funziona su Android OS 2.3, non sono sicuro di 4.0-4.3, ho provato che funziona su Android 4.4.4. si prega di assistere –

+0

@Williams 2.3 non ha una barra delle azioni. Puoi usare: 'your.R.id.action_bar_title' invece di' getIdentifier' se usi 'appcompat-v7'. Puoi chiedere entrambi gli ID e utilizzare quello esistente. – TWiStErRob

13

Si potrebbe utilizzare un layout personalizzato per il titolo e assegnare un ascoltatore ad esso:

@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

Purtroppo in questo modo perdi la capacità di 'getActionBar(). SetTitle() 'e devi implementare anche i sottotitoli handler, ma altrimenti questa è la soluzione giusta. Sarebbe bello se qualcuno pubblicasse una sintesi di un 'ActionBarTitles' come una visualizzazione personalizzata sostitutiva sostitutiva che supporta il titolo/sottotitolo e la lettura del tema. – TWiStErRob

6

Se si utilizza Toolbar con il supporto V7: 21. Scopri il seguente codice:

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

Credo Simas's answer è il migliore, ma qui è una versione hacky nel caso in cui si preferisce che.

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

Questo uno dovrebbe essere universale in quanto funziona con:

  • magazzino Android ActionBar
  • Theme.AppCompat supporto ActionBar
  • V21 in stile setActionBar
    uso <Toolbar android:id="@+id/action_bar"
    o passare nel gonfiata Toolbar come root
  • V21 in stile setSupportActionBar
    uso <android.support.v7.widget.Toolbar android:id="@id/action_bar"
    o passare nelle gonfiati Toolbar come root
  • personalizzato Toolbar implementazioni potrebbe essere necessario un piccolo aggiustamento,
    ma allora si potrebbe incapsulare questo in quella classe personalizzata.

Anche se ho provato solo con supporto: 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

È possibile che 'resourceName' cambi nelle future versioni della libreria di supporto? –

+0

@bwicks Molto improbabile, ma si. Probabilmente non ha importanza, perché i nomi delle risorse sono bloccati al momento della compilazione. Quindi, anche se rilasciano una nuova versione di supporto per la lib, la tua app dovrebbe essere sicura, perché contiene quella vecchia. Cioè, finché non aggiorni le tue dipendenze, costruisci e ripubblichi. Si noti inoltre che 'R.id.action_bar_title' è una risorsa pubblica, mentre' android.R.id.action_bar_title' è mirroring, non lo è (ecco perché viene usato 'getIdentifier'). Dovresti essere più preoccupato che la piattaforma Android cambi il nome in cui non si applica la protezione in fase di compilazione. – TWiStErRob

2

Lo si può fare facilmente usando barra degli strumenti.Definire barra degli strumenti in file XML di layout come indicato di seguito:

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

quindi è possibile impostare l'ascoltatore in attività utilizzando questo codice:

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

Se si conosce il testo vero e proprio che è nel tuo titolo, e si sono ragionevolmente sicuri che nessun altro TextView sullo schermo condivide tale titolo, è possibile utilizzare una ricerca ad albero ricorsiva della vista per trovarlo.

Questa è un'ottima soluzione perché non richiede la riflessione della conoscenza interna di come Toolbar è costruita e consente l'accesso diretto allo 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; 
} 

La vista più affidabile per chiamare questo su è la vista arredamento, ma sentitevi liberi di sperimentare ciò che funziona meglio per i vostri scopi, la tua situazione potrebbe essere diversa.

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