Название панели инструментов Android и собственный шрифт


366

Я пытаюсь найти правильный способ использовать собственный шрифт для заголовка панели инструментов и центрировать его на панели инструментов (требование клиента).

В данный момент я использую старый добрый ActionBar, и я устанавливал заголовок на пустое значение и использовал, setCustomViewчтобы поместить свой собственный шрифт TextView и отцентрировать его, используя ActionBar.LayoutParams.

Есть ли лучший способ сделать это? Использование новой панели инструментов в качестве моего ActionBar.

Ответы:


719

Чтобы использовать пользовательский заголовок, Toolbarвам нужно только помнить, что Toolbarэто просто модная ViewGroup, поэтому вы можете добавить пользовательский заголовок следующим образом:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >


     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Toolbar Title"
        android:layout_gravity="center"
        android:id="@+id/toolbar_title" />


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

Это означает, что вы можете стилизовать то, что TextViewзахотите, потому что это просто обычный текст TextView. Таким образом, в вашей деятельности вы можете получить доступ к названию следующим образом:

Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);
TextView mTitle = (TextView) toolbarTop.findViewById(R.id.toolbar_title);

5
предлагаем вместо этого использовать android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_gravity = "center".
SteelBytes

194
Если кто-то еще не может удалить заголовок имени приложения по умолчанию, сделайте следующее: 1. Вызовите setSupportActionBar (yourToolbar) 2. Вызовите getSupportActionBar (). SetDisplayShowTitleEnabled (false);
Рик Санчес

75
Чтобы продолжать использовать стили по умолчанию для настроенного TextView, попробуйте что-то вроде style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"( см. Этот ответ ).
Jonik

5
добавление android: paddingRight = "? attr / actionBarSize" может помочь центрировать текст по центру экрана в случае, если у вас есть кнопка (дом, навигационный ящик и т. д.)
Гордак

5
Что произойдет, когда на панели инструментов появится значок «Гамбургер»? Он не будет в центре полной ширины панели инструментов, он будет в центре ToolbarWidth - HamburgerIconWidth .
Акшай

75

Название панели инструментов является стилем. Любая настройка, которую вы делаете, должна быть сделана в теме. Я приведу вам пример.

Макет панели инструментов:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    style="@style/ToolBarStyle.Event"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="@dimen/abc_action_bar_default_height_material" />

Стили:

<style name="ToolBarStyle" parent="ToolBarStyle.Base"/>

<style name="ToolBarStyle.Base" parent="">
    <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
    <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style>

<style name="ToolBarStyle.Event" parent="ToolBarStyle">
    <item name="titleTextAppearance">@style/TextAppearance.Widget.Event.Toolbar.Title</item>
</style>

<style name="TextAppearance.Widget.Event.Toolbar.Title" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
    <!--Any text styling can be done here-->
    <item name="android:textStyle">normal</item>
    <item name="android:textSize">@dimen/event_title_text_size</item>
</style>

59
Это правильный путь. Добавление другого TextViewявляется немного хакерским, но ответный ответ - просто зло.
DariusL

9
Чисто, но вы не можете установить собственный шрифт из стиля. К сожалению.
niqueco

20
Вы также не можете изменить выравнивание заголовка.
Терри

7
@ user1560102 нет ничего плохого в добавлении TextView на панель инструментов. Вот для чего он был разработан.
Тим Малсид

107
Это не центрирует текст.
Себастьян Рот

69

Это просто, чтобы помочь объединить все части, используя @ MrEngineer13 ответ с комментариями @Jonik и @Rick Sanchez с правильным порядком, чтобы помочь легко достичь центрированного заголовка !!

Макет с TextAppearance.AppCompat.Widget.ActionBar.Title:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay">

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

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

Способ достижения с правильным заказом:

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);

    setSupportActionBar(toolbar);
    mTitle.setText(toolbar.getTitle());

    getSupportActionBar().setDisplayShowTitleEnabled(false);

Пожалуйста, не забудьте высказать ответ @ MrEngineer13 !!!

Вот пример проекта ToolbarCenterTitleSample

введите описание изображения здесь

Надеюсь помочь кому-нибудь еще;)


5
если я установил setDisplayHomeAsUpEnabled (true) и setDisplayShowHomeEnabled (true); облагородить стрелку назад. Тогда название не приходит в центр. Я попытался, как установка actionBar.setTitle (""); и setDisplayShowTitleEnabled (false). Но все еще не в состоянии решить проблему
Прашант Деббадвар

Вы проверяли это для Scrolling Activity?

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

52

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

  private TextView getActionBarTextView() {
    TextView titleTextView = null;

    try {
        Field f = mToolBar.getClass().getDeclaredField("mTitleTextView");
        f.setAccessible(true);
        titleTextView = (TextView) f.get(mToolBar);
    } catch (NoSuchFieldException e) {
    } catch (IllegalAccessException e) {
    }
    return titleTextView;
}

3
Хотя это и нехорошо, это решение работает для меня после попытки найти способ получить доступ к текстовому представлению панели инструментов. Спасибо.
falc0nit3

1
Хорошо сработало для титула. Но когда попытался получить mSubtitleTextView, как это, это привело к исключению. Вызывается: java.lang.NullPointerException: попытка вызвать виртуальный метод «void android.widget.TextView.setTypeface (android.graphics.Typeface)» для ссылки на пустой объект
Vinod

5
Примечание. Доступ к полю «mTitleTextView» можно получить только после того, как вы установили заголовок панели инструментов! Поле лениво инициализируется при первом его использовании.
funcoder

2
Что делать, если вы запутываете свой код с ProGuard и mTitleTextViewстановится abcde12345?
voghDev

1
В этом случае @voghDev getDeclaredField вызовет исключение NoSuchFieldException, в результате чего код не будет работать.
Джереми

30

Здесь текст заголовка зависит от подхода, чтобы найти TextViewэкземпляр из Toolbar.

  public static TextView getToolbarTitleView(ActionBarActivity activity, Toolbar toolbar){
    ActionBar actionBar = activity.getSupportActionBar();
    CharSequence actionbarTitle = null;
    if(actionBar != null)
        actionbarTitle = actionBar.getTitle();
    actionbarTitle = TextUtils.isEmpty(actionbarTitle) ? toolbar.getTitle() : actionbarTitle;
    if(TextUtils.isEmpty(actionbarTitle)) return null;
    // can't find if title not set
    for(int i= 0; i < toolbar.getChildCount(); i++){
        View v = toolbar.getChildAt(i);
        if(v != null && v instanceof TextView){
            TextView t = (TextView) v;
            CharSequence title = t.getText();
            if(!TextUtils.isEmpty(title) && actionbarTitle.equals(title) && t.getId() == View.NO_ID){
                //Toolbar does not assign id to views with layout params SYSTEM, hence getId() == View.NO_ID
                //in same manner subtitle TextView can be obtained.
                return t;
            }
        }
    }
    return null;
}

28

Определите следующий класс:

public class CenteredToolbar extends Toolbar {

    private TextView centeredTitleTextView;

    public CenteredToolbar(Context context) {
        super(context);
    }

    public CenteredToolbar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CenteredToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setTitle(@StringRes int resId) {
        String s = getResources().getString(resId);
        setTitle(s);
    }

    @Override
    public void setTitle(CharSequence title) {
        getCenteredTitleTextView().setText(title);
    }

    @Override
    public CharSequence getTitle() {
        return getCenteredTitleTextView().getText().toString();
    }

    public void setTypeface(Typeface font) {
        getCenteredTitleTextView().setTypeface(font);
    }

    private TextView getCenteredTitleTextView() {
        if (centeredTitleTextView == null) {
            centeredTitleTextView = new TextView(getContext());
            centeredTitleTextView.setTypeface(...);
            centeredTitleTextView.setSingleLine();
            centeredTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
            centeredTitleTextView.setGravity(Gravity.CENTER);
            centeredTitleTextView.setTextAppearance(getContext(), R.style.TextAppearance_AppCompat_Widget_ActionBar_Title);

            Toolbar.LayoutParams lp = new Toolbar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            lp.gravity = Gravity.CENTER;
            centeredTitleTextView.setLayoutParams(lp);

            addView(centeredTitleTextView);
        }
        return centeredTitleTextView;
    }
}

... а затем просто используйте его вместо обычного, Toolbarкак это:

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent">

        <your.packagename.here.CenteredToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:theme="?attr/actionBarTheme"
            app:title="@string/reset_password_page_title"/>

        <!-- Other views -->

</RelativeLayout>

Вам все еще нужны эти 2 строки кода в вашем Activity(как со стандартными Toolbar):

Toolbar toolbar = (Toolbar) findViewByid(R.id.toolbar); // note that your activity doesn't need to know that it is actually a custom Toolbar
setSupportActionBar(binding.toolbar);

Это оно! Вам не нужно скрывать стандартный заголовок с выравниванием по левому краю, не нужно дублировать один и тот же XML-код снова и снова и т. Д., Просто используйтеCenteredToolbar как если бы это было по умолчанию Toolbar. Вы также можете установить свой собственный шрифт программно, поскольку теперь у вас есть прямой доступ к TextView. Надеюсь это поможет.


1
Спасибо! Лучшее решение, только чтобы не забыть импортировать на панель инструментов «v7.widget»
David

Я знаю, что это довольно старый, но ... как я могу изменить цвет текста? Я пробовал в XML с app: titleTextColor и в коде с centteredTitleTextView.setColor. Есть идеи, @fraggjkee?
Дженаро Альберто Канчино Эррера

centeredTitleTextView.setTextColor(...)должен работать
fraggjkee

Не должно ли это быть LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)?
пороговый

16

Никто не упомянул об этом, но есть некоторые атрибуты для Toolbar:

app:titleTextColor для настройки цвета текста заголовка

app:titleTextAppearance для настройки внешнего вида текста заголовка

app:titleMargin для установки маржи

И есть другие определенные поля стороны, такие как marginStart, и т. Д.


1
Идеальное решение ... если вы знаете о FontOverride , просто создайте стиль в styles.xml <style name="customFontTextAppearanceStyle"> <item name="android:textSize">18sp</item> <item name="android:typeface">monospace</item> и примените его на панели инструментов app:titleTextAppearance="@styles/customFontTextAppearanceStyle"
Chinmay Thoriya

2
Я использовал этот метод, но ничего не случилось с моей панелью инструментов! я создал новый '<style>' и установил его app:titleTextAppearanc="style name" на android.support.v7.widget.ToolbarTAG
AN

12

Я использую это решение:

static void centerToolbarTitle(@NonNull final Toolbar toolbar) {
    final CharSequence title = toolbar.getTitle();
    final ArrayList<View> outViews = new ArrayList<>(1);
    toolbar.findViewsWithText(outViews, title, View.FIND_VIEWS_WITH_TEXT);
    if (!outViews.isEmpty()) {
        final TextView titleView = (TextView) outViews.get(0);
        titleView.setGravity(Gravity.CENTER);
        final Toolbar.LayoutParams layoutParams = (Toolbar.LayoutParams) titleView.getLayoutParams();
        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        toolbar.requestLayout();
        //also you can use titleView for changing font: titleView.setTypeface(Typeface);
    }
}

1
Работает очень хорошо, но по некоторым причинам он не центрируется должным образом с панелями инструментов, на которых нет кнопки элемента.
Муниб

1
Дополнение: если у вас есть панель навигации или значок возврата на панели инструментов, заголовок не будет оставаться точно в центре. Я добавляю пустой значок меню настроек для этой ситуации. Мой пустой элемент меню: <item android: id = "@ + id / empty" android: orderInCategory = "100" android: icon = "@ android: color / transparent" app: showAsAction = "always" tools: ignore = " MenuTitle "/>
Встреча

10

Без панели инструментов TextView мы можем настроить шрифт, используя приведенный ниже код

getSupportActionBar().setDisplayShowTitleEnabled(false);
or
getActionBar().setDisplayShowTitleEnabled(false);

public void updateActionbar(String title){
    SpannableString spannableString = new SpannableString(title);
    spannableString.setSpan(new TypefaceSpanString(this,  "futurastdmedium.ttf"),
            0, spannableString.length(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    mToolbar.setTitle(spannableString);
}

1
Если вам просто нужно изменить шрифт, это кажется самым чистым решением. ПРИМЕЧАНИЕ: TypefaceSpanString - это просто: stackoverflow.com/a/17961854
Мохиб Иршад

8
    public class TestActivity extends AppCompatActivity {
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_test);

        toolbar = (Toolbar) findViewById(R.id.tool_bar); // Attaching the layout to the toolbar object
        setSupportActionBar(toolbar);

        customizeToolbar(toolbar);
    }

    public void customizeToolbar(Toolbar toolbar){
        // Save current title and subtitle
        final CharSequence originalTitle = toolbar.getTitle();
        final CharSequence originalSubtitle = toolbar.getSubtitle();

        // Temporarily modify title and subtitle to help detecting each
        toolbar.setTitle("title");
        toolbar.setSubtitle("subtitle");

        for(int i = 0; i < toolbar.getChildCount(); i++){
            View view = toolbar.getChildAt(i);

            if(view instanceof TextView){
                TextView textView = (TextView) view;


                if(textView.getText().equals("title")){
                    // Customize title's TextView
                    Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT);
                    params.gravity = Gravity.CENTER_HORIZONTAL;
                    textView.setLayoutParams(params);

                    // Apply custom font using the Calligraphy library
                    Typeface typeface = TypefaceUtils.load(getAssets(), "fonts/myfont-1.otf");
                    textView.setTypeface(typeface);

                } else if(textView.getText().equals("subtitle")){
                    // Customize subtitle's TextView
                    Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT);
                    params.gravity = Gravity.CENTER_HORIZONTAL;
                    textView.setLayoutParams(params);

                    // Apply custom font using the Calligraphy library
                    Typeface typeface = TypefaceUtils.load(getAssets(), "fonts/myfont-2.otf");
                    textView.setTypeface(typeface);
                }
            }
        }

        // Restore title and subtitle
        toolbar.setTitle(originalTitle);
        toolbar.setSubtitle(originalSubtitle);
    }
}

1
Решение прекрасно работает, когда вы выводите последние две строки кода, оно не должно быть внутри цикла for: // Восстановление заголовка и субтитров toolbar.setTitle (originalTitle); toolbar.setSubtitle (originalSubtitle);
Иван Стойкович

5

Планировка:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >

     <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Toolbar Title"
        android:layout_gravity="center"
        android:gravity="center"
        android:id="@+id/toolbar_title" />
</android.support.v7.widget.Toolbar>

Код:

    Toolbar mToolbar = parent.findViewById(R.id.toolbar_top);
    TextView mToolbarCustomTitle = parent.findViewById(R.id.toolbar_title);

    //setup width of custom title to match in parent toolbar
    mToolbar.postDelayed(new Runnable()
    {
        @Override
        public void run ()
        {
            int maxWidth = mToolbar.getWidth();
            int titleWidth = mToolbarCustomTitle.getWidth();
            int iconWidth = maxWidth - titleWidth;

            if (iconWidth > 0)
            {
                //icons (drawer, menu) are on left and right side
                int width = maxWidth - iconWidth * 2;
                mToolbarCustomTitle.setMinimumWidth(width);
                mToolbarCustomTitle.getLayoutParams().width = width;
            }
        }
    }, 0);

1
Я думаю, что "int width = maxWidth - titleWidth * 2;" должно быть "int width = maxWidth - iconWidth * 2;", думает!
oldfeel

4

Я решил это решение, и это следующие коды:

<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Order History"
            android:layout_gravity="center"
            android:id="@+id/toolbar_title"
            android:textSize="17sp"
            android:textStyle="bold"
            android:textColor="@color/colorWhite"
            />

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

И вы можете изменить заголовок / метку, в Activity, напишите следующие коды:

Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);

TextView mTitle = (TextView) toolbarTop.findViewById (R.id.toolbar_title); mTitle.setText ( "@ строки / ....");


4

Вы можете использовать как следующее

 <android.support.v7.widget.Toolbar
    android:id="@+id/top_actionbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppThemeToolbar">

    <TextView
        android:id="@+id/pageTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />
</android.support.v7.widget.Toolbar>

если я установил setDisplayHomeAsUpEnabled (true) и setDisplayShowHomeEnabled (true); облагородить стрелку назад. Тогда название не приходит в центр. Я попытался, как установка actionBar.setTitle (""); и setDisplayShowTitleEnabled (false). Но все еще не в состоянии решить проблему
Прашант Деббадвар

4

Очень быстрый и простой способ установить пользовательский шрифт - использовать пользовательский titleTextAppearanceс fontFamily:

Добавьте в styles.xml :

<style name="ToolbarTitle" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
    <item name="android:textSize">16sp</item>
    <item name="android:textColor">#FF202230</item>
    <item name="android:fontFamily">@font/varela_round_regular</item>
</style>

В папке res создайте папку шрифтов (например, varela_round_regular.ttf )

Прочтите официальное руководство, чтобы узнать больше https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html


3

Я не знаю, изменилось ли что-нибудь в библиотеке appcompat, но это довольно тривиально, не нужно размышлять.

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

3

Решение, которое я использовал для этой проблемы:

 public static void applyFontForToolbarTitle(Activity a){
        Toolbar toolbar = (Toolbar) a.findViewById(R.id.app_bar);
        for(int i = 0; i < toolbar.getChildCount(); i++){
            View view = toolbar.getChildAt(i);
            if(view instanceof TextView){
                TextView tv = (TextView) view;
                if(tv.getText().equals(a.getTitle())){
                    tv.setTypeface(getRuneTypefaceBold(a));
                    break;
                }
            }
        }
    }

Для центра тяжести я думаю, что было бы необходимо изменить параметры макета на match_parent по горизонтали, а затем:

tv.setGravity(Gravity.CENTER);

3

Обновление от ответа @ MrEngineer13: чтобы выровнять центр заголовка в любых случаях, включая значок гамбургера, меню опций, вы можете добавить FrameLayoutпанель инструментов следующим образом:

   <android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >

         <FrameLayout android:layout_width="match_parent"
                    android:layout_height="match_parent">

              <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="Toolbar Title"
               android:layout_gravity="center"
               style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
               android:id="@+id/toolbar_title" />

        </FrameLayout>

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

3

В XML попробуйте это:

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="@color/action_bar_bkgnd"
app:theme="@style/ToolBarTheme" >


 <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Toolbar Title"
    android:layout_gravity="center"
    android:id="@+id/toolbar_title" />


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

В коде:

Toolbar myToolbar= (Toolbar) findViewById(R.id.toolbar);
TextView mTitle = (TextView) mytoolbar.findViewById(R.id.toolbar_title);

2

Хотя добавление текстового представления на панель инструментов может решить проблему ограничения стиля заголовка, с ним есть проблема. Поскольку мы не добавляем его в макет, мы не слишком контролируем его ширину. Мы можем использовать либо wrap_content, либо match_parent.

Теперь рассмотрим сценарий, в котором у нас есть searchView как кнопка на правом краю панели инструментов. Если содержание заголовка больше, оно будет сверху кнопки, скрывая его. Нет никакого способа контролировать этот недостаток, устанавливая ширину надписи, и это то, что вы не хотите делать, если хотите иметь адаптивный дизайн.

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

Убедитесь, что вы установили панель инструментов, чтобы не показывать заголовок.

Вот XML для этого решения:

<RelativeLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="?attr/colorPrimary">

                    <android.support.v7.widget.Toolbar
                        android:theme="@style/ThemeOverlay.AppCompat.Dark"
                        android:id="@+id/activity_toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="?attr/actionBarSize"
                        android:background="?attr/colorPrimary"
                        android:titleTextAppearance="@style/AppTheme.TitleTextView"
                        android:layout_marginRight="40dp"
                        android:layoutMode="clipBounds">

                        <android.support.v7.widget.SearchView
                            android:id="@+id/search_view"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="right"
                            android:layout_centerVertical="true"
                            android:layout_alignParentRight="true"
                            android:foregroundTint="@color/white" />
                        </android.support.v7.widget.Toolbar>

                    <TextView
                        android:id="@+id/toolbar_title"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="90dp"
                        android:text="@string/app_name"
                        android:textSize="@dimen/title_text_size"
                        android:textColor="@color/white"
                        android:lines="1"
                        android:layout_marginLeft="72dp"
                        android:layout_centerVertical="true" />

                </RelativeLayout>

Решает проблему @ ankur-chaudhary, упомянутую выше.


2

Так как android.support.v7.appcompat 24.2 Toolbarимеет метод, setTitleTextAppearanceи вы можете установить его шрифт без внешнегоtextview .

создать новый стиль в styles.xml

<style name="RobotoBoldTextAppearance">
        <item name="android:fontFamily">@font/roboto_condensed_bold</item>
</style>

и использовать это

mToolbar.setTitleTextAppearance(this, R.style.RobotoBoldTextAppearance);

2

Я провел несколько дней в поисках универсального решения. Моя панель инструментов работает с меню Android и значком навигации.

Сначала вам нужно создать собственный класс панели инструментов. Этот класс должен рассчитывать позиции по центру заголовка (отступы):

    class CenteredToolbar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
    : Toolbar(context, attrs, defStyleAttr) {

    init {
        addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
            override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {
                val titleTextView = findViewById<TextView>(R.id.centerTitle)

                val x = titleTextView.x.toInt()
                val x2 = x + titleTextView.width

                val fullWidth = width
                val fullCenter = fullWidth / 2

                val offsetLeft = Math.abs(fullCenter - x)
                val offsetRight = Math.abs(x2 - fullCenter)
                val differOffset = Math.abs(offsetLeft - offsetRight)

                if (offsetLeft > offsetRight) {
                    titleTextView.setPadding(differOffset, 0, 0, 0)
                } else if (offsetRight > offsetLeft) {
                    titleTextView.setPadding(0, 0, differOffset, 0)
                }

                removeOnLayoutChangeListener(this)
            }
        })
    }

    override fun setTitle(resId: Int) = getTitleView().setText(resId)

    override fun setTitle(title: CharSequence?) = getTitleView().setText(title)

    fun getTitleView(): TextView = findViewById(R.id.centerTitle)

}

Во-вторых, вам нужно создать макет панели инструментов:

<CenteredToolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar">

    <TextView
        android:id="@+id/centerTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</CenteredToolbar>

Это все


2

Попробуйте взять панель инструментов и титл в отдельном представлении. Взгляните на правый конец и дайте им вес, равный весу панели инструментов. Таким образом, ваша грудь окажется в центре.

<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay"
    android:background="@color/white_color">
  <LinearLayout
   android:id="@+id/toolbar_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@color/white_color">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/white_color"
        app:popupTheme="@style/AppTheme.PopupOverlay"
        app:contentInsetLeft="0dp"
        app:contentInsetStart="0dp"
        android:layout_weight="0.2"

        app:contentInsetStartWithNavigation="0dp"
        app:navigationIcon="@color/greyTextColor">
       </android.support.v7.widget.Toolbar>


        <com.an.customfontview.CustomTextView
            android:id="@+id/headingText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.6"
            android:gravity="center"
            android:text="Heading"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:textColor="@color/colorPrimary"
            android:textSize="@dimen/keyboard_number"
            android:layout_gravity="center_horizontal|center_vertical"
            app:textFontPath="fonts/regular.ttf" />
            <ImageView
                android:id="@+id/search_icon"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:visibility="visible"
                android:layout_weight="0.2"
                android:layout_gravity="center_horizontal|center_vertical"
                android:src="@drawable/portfolio_icon"/>
        </LinearLayout>

       </android.support.design.widget.AppBarLayout>

2

Вы можете вставить этот код в свой XML-файл

 <androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryDark"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Toolbar Title"
        android:textColor="#000000"
        android:textSize="20dp"
        android:id="@+id/toolbar_title" />

</androidx.appcompat.widget.Toolbar>

Привет Узаир. Какой XML-файл? Я использую проект Android Studio 3.6.3, созданный из шаблона «Пустое действие». Спасибо.
Любовь и мир - Джо Кодсвелл

1
private void makeTitleCenter(String title, Toolbar toolbar) {
    if (title != null && !TextUtils.isEmpty(title.trim())) {
        final String tag = " ";
        if (getSupportActionBar() != null) {
            getSupportActionBar().setTitle(tag);
        }
        TextView titleTv = null;
        View leftBtn = null;
        for (int i = 0; i < toolbar.getChildCount(); i++) {
            View view = toolbar.getChildAt(i);
            CharSequence text = null;
            if (view instanceof TextView && (text = ((TextView) view).getText()) != null && text.equals(tag)) {
                titleTv = (TextView) view;
            } else if (view instanceof ImageButton) {
                leftBtn = view;
            }
        }
        if (titleTv != null) {
            final TextView fTitleTv = titleTv;
            final View fLeftBtn = leftBtn;
            fTitleTv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    fTitleTv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    int leftWidgetWidth = fLeftBtn != null ? fLeftBtn.getWidth() : 0;
                    fTitleTv.setPadding(DimenUtil.getResources().getDisplayMetrics().widthPixels / 2 - leftWidgetWidth - fTitleTv.getWidth() / 2, 0, 0, 0);
                    fTitleTv.requestLayout();
                }
            });
        }
    }
}

1

Настройка android:gravity="center"работала для меня

Нет стайлинга ничего. Панель инструментов - это ViewGroupвсе, что вам нужно сделать, это установить гравитацию элементов в ней.

        <android.support.v7.widget.Toolbar
            android:id="@+id/htab_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="top"
            android:background="@color/partial_transparent"
            android:gravity="center"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

8
Не работает сandroidx.appcompat.widget.Toolbar
tmm1

1

для пользовательского шрифта на панели инструментов вы можете переопределить шрифт textView в стиле, а затем каждый текстовый вид в вашем приложении также автоматически изменял шрифт заголовка панели инструментов, я проверил его в Android Studio 3.1.3

в стиле сделать это:

<style name="defaultTextViewStyle" parent="android:Widget.TextView">
        <item name="android:fontFamily">@font/your_custom_font</item>
</style>

а затем в вашей теме используйте это:

<item name="android:textViewStyle">@style/defaultTextViewStyle</item>

1

Я нашел другой способ добавить пользовательскую панель инструментов без какого-либо дополнительного кода Java / Kotlin.

  • Во-первых: создайте XML с вашим собственным макетом панели инструментов с AppBarLayout в качестве родителя:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.AppBarLayout                     
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
    
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay">
    
        <ImageView
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginEnd="@dimen/magin_default"
            android:src="@drawable/logo" />
    
    </android.support.v7.widget.Toolbar>

  • Второе: включите панель инструментов в свой макет:

    <?xml version="1.0" encoding="utf-8"?>                
    <android.support.constraint.ConstraintLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/blue"
        tools:context=".app.MainAcitivity"
        tools:layout_editor_absoluteY="81dp">
    
        <include
            layout="@layout/toolbar_inicio"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <!-- Put your layout here -->
    
    </android.support.constraint.ConstraintLayout>

1

На мой взгляд, у вас есть два варианта:

1) Редактировать панель инструментов XML. Когда ваша панель инструментов добавляется в XML, она обычно выглядит так:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:elevation="4dp"
    app:popupTheme="@style/AppTheme.PopupOverlay"/>

если вы хотите настроить его, просто удалите «/» в конце и сделайте так:

<android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:elevation="4dp"
            app:popupTheme="@style/AppTheme.PopupOverlay">

            <android.support.constraint.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <ImageView
                    android:id="@+id/toolbar_iv"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:src="@mipmap/ic_launcher"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <TextView
                    android:id="@+id/toolbar_tv"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="20dp"
                    android:gravity="center"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toRightOf="@+id/toolbar_iv"
                    app:layout_constraintTop_toTopOf="parent" />

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

Таким образом, вы можете иметь панель инструментов и настроить текстовое представление и логотип.

2) Программно изменить родной текстовый вид и значок:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setIcon(R.drawable.ic_question_mark);
getSupportActionBar().setTitle("Title");

убедитесь, что ваша панель инструментов не является нулевой, прежде чем устанавливать в нее что-либо.


1

Вы можете иметь пользовательский TextViewна панели инструментов, как это:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >

     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:layout_gravity="center"
        android:id="@+id/toolbar_title" />


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

Таким образом, это будет центрировать текст. Если вы хотите добавить собственный шрифт в обычный Toolbar, сделайте <style>:

<style android:name="ToolbarFont">
    <item android:fontFamily = "@font/fontName" />
</style>

И добавьте его на панель инструментов:

toolbar.setTitleTextAppearance(this, R.style.ToolbarFont);

Для просмотра текста на панели инструментов вы можете определить его с помощью fontFamilyатрибута:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >

     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:layout_gravity="center"
        android:id="@+id/toolbar_title"
        android:fontFamily="@font/fontFamily" />


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

1

Я столкнулся с той же проблемой, исправленной в MainActivity.

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);

И во фрагменте

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    if (view == null) {
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.fragment_example, container, false);
        init();
    }
    getActivity().setTitle("Choose Fragment");
    return view;
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.example_menu, menu);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.