17

I have a library that requires to use the color of the TextView for the ActionBar title. Prior to AppCompat v7 r21 I could just findViewById() and get the color from the view directly. However, for some reason now that does not work. The view is always null. I've written code that parses the entire view hierarchy and prints out the IDs, types and values for all TextViews. The title view had no ID, which I find very weird.

One thing I noticed was when I tried to get the ActionBar what was returned was a Toolbar (even though I didn't use a Toolbar in my app). So I iterated over the Toolbar's children views and whenever a TextView was found I compared its text value with the toolbar.getTitle() to make sure that's the TextView I'm looking for. Not ideal and I'm not sure if it'll work for all cases.

Does anyone know what could be the safest solution?

Dmitrii Leonov
  • 1,331
  • 1
  • 15
  • 25
Ahmed Nawara
  • 349
  • 1
  • 4
  • 10

5 Answers5

25

No need for creating your own TextView, just loop through toolbar children to get the built-in title.

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

// loop through all toolbar children right after setting support 
// action bar because the text view has no id assigned

// also make sure that the activity has some title here
// because calling setText() with an empty string actually
// removes the text view from the toolbar

TextView toolbarTitle = null;
for (int i = 0; i < toolbar.getChildCount(); ++i) {
    View child = toolbar.getChildAt(i);

    // assuming that the title is the first instance of TextView
    // you can also check if the title string matches
    if (child instanceof TextView) {
        toolbarTitle = (TextView)child;
        break;
    }
}
headsvk
  • 2,726
  • 1
  • 19
  • 23
24

Typically when using the Toolbar in my cases, if I am doing something custom with the title, I will just inflate the title view manually, then set its attributes in XML. The point of Toolbar is to prevent things like this from happening, so you can have more control over what your toolbar looks like

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/my_awesome_toolbar"
        android:layout_height="@dimen/standard_vertical_increment"
        android:layout_width="match_parent"
        android:minHeight="@dimen/standard_vertical_increment"
        android:background="@drawable/actionbar_background">


        <TextView
            style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/Red" />

    </android.support.v7.widget.Toolbar>

Then in code, you would do something like this:

Toolbar toolbar = findViewById(R.id.my_awesome_toolbar);
//Get rid of the title drawn by the toolbar automatically
toolbar.setTitle("");
TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
toolbarTitle.setTextColor(Color.BLUE);

I know this is an older post, but this has been the best way I have found for allowing custom textc color and fonts in the Toolbar

Jawnnypoo
  • 993
  • 12
  • 18
  • 1
    Thank you. This way, I can change color Toolbar from anywhere activity in my app. – danigonlinea Feb 26 '15 at 14:06
  • How do I make it move when scrolling, using the new design library, and CollapsingToolbarLayout ? I need to use both title and subtitle, but sadly it seems that the subtitle doesn't appear when using the new design library – android developer Nov 04 '15 at 13:04
3

edit (september 2018): dont use it as of Android P reflection on android SDK may throw exception!

I got it using reflection.

toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Title"); //important step to set it otherwise getting null
TextView title = null;
try{
        Field f = toolbar.getClass().getDeclaredField("mTitleTextView");
        f.setAccessible(true);
        title = (TextView) f.get(toolbar);
        title.setText("I have title TextView");
} catch(Exception e){
        e.printStackTrace();
}

Please note that is works if I toolbar is not set to support ActionBar...

setSupportActionBar(toolbar); // with this set text view behave differently 
                              //and text may not be visible...
smory
  • 324
  • 3
  • 12
2

You can do lik this.

Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
TextView title=(TextView )toolbar.getChildAt(0);

This is work for me.

Rahul Giradkar
  • 1,818
  • 1
  • 17
  • 28
  • and how do i set getChildAt(0)? For example, i want to load an email, like **todo@so.com**, with code above how do i do? – pnet Feb 28 '18 at 19:14
0

Here is a future proof way of getting the title, in case Android changes the order of icon and text.

//If you just want to set the text
ActionBar actBar = getSupportActionBar();
if(actBar != null) {
    actBar.setTitle(R.string.your_ab_title);
}

//If you want to customize more than the text    
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) {
            //You now have the title textView. Do something with it
        }
     }
}
Chris Sprague
  • 3,158
  • 33
  • 24