Получение заголовка ActionBar TextView с AppCompat v7 r21

У меня есть библиотека, которая требует использования цвета TextView для заголовка ActionBar. До AppCompat v7 r21 я мог бы просто findViewById и получить цвет из представления напрямую. Однако по какой-то причине сейчас это не работает. Представление всегда равно нулю. Я написал код, который анализирует всю иерархию представлений и выводит идентификаторы, типы и значения для всех текстовых элементов. Заголовок не имел идентификатора, который я нахожу очень странным.

Одна вещь, которую я заметил, это когда я пытался получить ActionBar, что было возвращено, это панель инструментов (хотя я не использовал панель инструментов в своем приложении). Таким образом, я перебирал элементы просмотра на панели инструментов и всякий раз, когда был найден TextView, я сравнивал его текстовое значение с toolbar.getTitle(), чтобы убедиться, что TextView я ищу. Не идеально, и я не уверен, что он будет работать для всех случаев.

Кто-нибудь знает, что может быть самым безопасным решением?

Ответ 1

Не нужно создавать свой собственный TextView, просто зацикливайте дочерние элементы панели инструментов, чтобы получить встроенный заголовок.

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

Ответ 2

Обычно, когда я использую панель инструментов в своих случаях, если я делаю что-то нестандартное с заголовком, я просто буду раздувать представление заголовка вручную, а затем установить его атрибуты в XML. Пункт панели инструментов состоит в предотвращении подобных событий, поэтому вы можете больше контролировать, как выглядит ваша панель инструментов.

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

Затем в коде вы сделаете что-то вроде этого:

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

Я знаю, что это более старая запись, но это был лучший способ, который я нашел для разрешения пользовательских цветов и шрифтов textc на панели инструментов.

Ответ 3

Я получил его, используя отражение.

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

Обратите внимание, что это работает, если я на панели инструментов не настроен для поддержки ActionBar...

setSupportActionBar(toolbar); // with this set text view behave differently 
                              //and text may not be visible...

Ответ 4

Вы можете сделать это.

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

Это работа для меня.