web-dev-qa-db-fra.com

Définir OnClick Listener sur le titre de la barre d’action sous Android

Je travaille sur une application Android où j'utilise ActionBar. Il y a donc une icône de tiroir de navigation pour l'ouvrir et le titre de ActionBar dans ActionBar. Je souhaite définir un écouteur de clic sur le titre de ActionBar, de sorte qu'il lance une nouvelle Activity et définisse un écouteur de clic différent sur l'icône du tiroir de navigation pour ouvrir le menu du tiroir de navigation.

J'ai réussi à cliquer sur l'icône du tiroir de navigation, mais lorsque je clique sur le titre de ActionBar titre également, le menu du tiroir de navigation s'ouvre. Est-il possible de définir différents écouteurs de clic sur le titre de ActionBar.

Merci d'avance.

22
N Sharma

Essayez d'ajouter ce code sous la fonction onCreate (). Cela récupérera la ressource sous laquelle se trouve le titre de la barre d'action et lui assignera un identifiant que vous pourrez utiliser pour ajouter un OnClickListener. Laissez-moi savoir comment ça se passe!

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

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

Vous pouvez utiliser une présentation personnalisée pour le titre et lui affecter un écouteur:

@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>
15
Simas

Je pense que la réponse de Simas est la meilleure, mais voici une version hacky au cas où vous préféreriez cela.

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

Ceci devrait être universel en ce sens qu'il fonctionne avec:

  • stock Android ActionBar
  • Theme.AppCompat support ActionBar
  • v21-style setActionBar
    utiliser <Toolbar Android:id="@+id/action_bar"
    ou passer la Toolbar gonflée comme root
  • v21-style setSupportActionBar
    utiliser <Android.support.v7.widget.Toolbar Android:id="@id/action_bar"
    ou passer la Toolbar gonflée comme root
  • les implémentations personnalisées Toolbar peuvent nécessiter un petit ajustement,
    mais vous pourriez alors encapsuler ceci dans cette classe personnalisée.

Bien que je n'ai testé qu'avec le 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;
}
9
TWiStErRob

Si vous utilisez Toolbar avec le support v7: 21 ..__, vérifiez le code suivant:

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

            }
        });
7
Dejavu

Vous pouvez le faire facilement en utilisant la barre d’outils. Définissez la barre d’outils dans le fichier XML de mise en page comme indiqué ci-dessous:

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

Ensuite, vous pouvez définir l'auditeur dans Activity à l'aide de ce code:

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
jimmy0251

Si vous souhaitez utiliser le ActionBar existant et non la barre d'outils, utilisez les éléments suivants:

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);
                }
            });
        }
     }
}    
1
Chris Sprague

Vous pouvez le faire facilement en utilisant la barre d’outils. Définissez la barre d’outils dans le fichier XML de mise en page comme indiqué ci-dessous:

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

Ensuite, vous pouvez définir l'auditeur dans Activity à l'aide de ce code:

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

Si vous connaissez le texte réel qui se trouve dans votre titre et que vous êtes raisonnablement sûr qu'aucune autre variable TextView à l'écran ne partage ce titre, vous pouvez utiliser une recherche arborescente récursive pour le rechercher. 

C'est une excellente solution car elle ne nécessite pas de réflexion sur la connaissance interne de la manière dont la barre d'outils est construite et vous donne un accès direct à la variable 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 vue la plus fiable est la vue de la décoration, mais n'hésitez pas à expérimenter ce qui convient le mieux à vos objectifs, votre kilométrage peut varier.

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