ChatGPT解决这个技术问题 Extra ChatGPT

Android 工具栏中心标题和自定义字体

我正在尝试找出使用自定义字体作为工具栏标题的正确方法,并将其置于工具栏中(客户要求)。

目前,我正在使用旧的 ActionBar,并将标题设置为空值,并使用 setCustomView 放置我的自定义字体 TextView 并使用 ActionBar.LayoutParams 将其居中。

有没有更好的方法来做到这一点?使用新的工具栏作为我的操作栏。

MaterialToolbar 支持居中工具栏,也支持更改字体,参见:material.io/components/app-bars-top/…

S
Sushil

要在 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="?android: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);

建议改用 android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" 。
如果其他人无法删除默认应用名称标题,请执行以下操作: 1. 调用 setSupportActionBar(yourToolbar) 2. 调用 getSupportActionBar().setDisplayShowTitleEnabled(false);
要继续使用自定义 TextView 的默认样式,请尝试使用 style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" (see this answer) 之类的方法。
添加 android:paddingRight="?attr/actionBarSize" 可以帮助在您有按钮(主页、导航抽屉等)的情况下将文本置于屏幕中间
工具栏上有汉堡包图标时会发生什么?它不会位于完整工具栏宽度的中心,而是位于 ToolbarWidth - HamburgerIconWidth 的中心。
G
Gueorgui Obregon

这只是为了帮助使用 @MrEngineer13 answer 与 @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 answer点赞!!!

这是一个示例项目 ToolbarCenterTitleSample

https://i.stack.imgur.com/T1B7t.png

希望能帮助别人;)


如果我设置 setDisplayHomeAsUpEnabled(true) 和 setDisplayShowHomeEnabled(true);启用后退箭头。然后标题不是中心。我试过设置 actionBar.setTitle("");和 setDisplayShowTitleEnabled(false)。但仍然无法解决问题
您是否针对 Scrolling Activity 对其进行了测试?
确实,使用后退箭头,标题没有居中(它向右偏离后退箭头宽度的一半)。我想如果我真的确定我会根据需要以编程方式在文本框的右侧添加足够的边距以使文本居中。
B
Binoy Babu

工具栏标题是可设置样式的。您进行的任何自定义都必须在主题中进行。我给你举个例子。

工具栏布局:

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

这是正确的方法。添加另一个 TextView 有点笨拙,但反射答案简直是邪恶的。
干净,但您不能从样式中设置自定义字体。可悲的是。
你也不能改变标题的对齐方式。
这不会使文本居中。
不按照 OP 的要求将文本居中。
A
Akash Singh

我们无法直接访问 ToolBar 标题 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;
}

尽管这很 hacky,但在尝试找到访问工具栏文本视图的方法后,此解决方案对我有用。谢谢你。
为标题工作得很好。但是当试图像这样获取 mSubtitleTextView 时,它导致了一个异常。原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'void android.widget.TextView.setTypeface(android.graphics.Typeface)'
注意:设置工具栏标题后,您只能访问“mTitleTextView”字段!该字段在第一次使用时被延迟初始化。
如果您使用 ProGuard 混淆您的代码并且 mTitleTextView 变成 abcde12345 怎么办?
@voghDev getDeclaredField 在这种情况下会抛出 NoSuchFieldException,导致代码无法工作。
f
fraggjkee

定义以下类:

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>

您的 Activity 中仍需要这 2 行代码(与标准 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。希望这可以帮助。


谢谢!最好的解决方案,只是不要忘记将“v7.widget”导入工具栏
我知道这已经很老了,但是...如何更改文本颜色?我已经尝试在 XML 中使用 app:titleTextColor 并在代码中使用 centeredTitleTextView.setColor。有什么想法吗,@fraggjkee?
centeredTitleTextView.setTextColor(...) 应该可以工作
不应该是LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)吗?
嗨什么是绑定?
N
Nikola Despotoski

这是从 Toolbar 中查找 TextView 实例的依赖于标题文本的方法。

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

u
user3210008

Material Components 1.4.0-alpha02 中的 MaterialToolbar 现在可以通过将 titleCentered 属性设置为 true 来使工具栏的标题居中:

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appBarLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/topAppBar"
        style="@style/Widget.MaterialComponents.Toolbar.Primary"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:titleCentered="true" />

</com.google.android.material.appbar.AppBarLayout>

这是有史以来最好的答案。请投票以帮助其他人看到它👍🏼
得到错误属性titleCentered not found
A
Ali Bdeir

没有人提到这一点,但 Toolbar 有一些属性:

app:titleTextColor 用于设置标题文本颜色

app:titleTextAppearance 用于设置标题文本外观

app:titleMargin 用于设置边距

还有其他特定边距,例如 marginStart 等。


完美解决方案.. 如果您知道 FontOverride,只需在 styles.xml <style name="customFontTextAppearanceStyle"> <item name="android:textSize">18sp</item> <item name="android:typeface">monospace</item> 中创建样式并将其应用到工具栏 app:titleTextAppearance="@styles/customFontTextAppearanceStyle"
我使用了这种方法,但我的工具栏没有任何反应!我创建了一个新的“<style>”并在 android.support.v7.widget.Toolbar TAG 上将其设置为 app:titleTextAppearanc="style name"
居中的东西呢?
V
Vadim Kotov

我使用这个解决方案:

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

效果很好,但由于某种原因,它不能与没有项目按钮的工具栏正确居中。
另外:如果您在工具栏上有导航抽屉或后退图标,则标题不会完全居中。我为这种情况添加了一个空的设置菜单图标。我的空菜单项是:
d
dsh

没有工具栏 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);
}

如果您只需要更改字体,这似乎是最干净的解决方案。注意:TypefaceSpanString 就是这样:stackoverflow.com/a/17961854
B
Bishan
    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);
    }
}

当您输出最后两行代码时,解决方案效果很好,它不应该在 for 循环内://恢复标题和副标题 toolbar.setTitle(originalTitle); toolbar.setSubtitle(originalSubtitle);
m
maros136

布局:

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

我认为“int width = maxWidth - titleWidth * 2;”应该是“int width = maxWidth - iconWidth * 2;”,认为!
v
vovahost

设置自定义字体的一种非常快速简单的方法是使用带有 fontFamily 的自定义 titleTextAppearance

添加到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


h
headsvk

我不知道 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;
    }
}

M
Monet_z_Polski

我用于此问题的解决方案:

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

H
Hai Rom

我解决了这个解决方案,这是以下代码:

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

您可以更改 title/label ,在 Activity 中,编写以下代码:

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

TextView mTitle = (TextView) toolbarTop.findViewById(R.id.toolbar_title); mTitle.setText("@string/....");


A
A Sharma

你可以像下面这样使用

 <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)。但仍然无法解决问题
d
ductran

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

D
Deepak G M

尽管在工具栏中添加文本视图可以解决标题样式的限制问题,但它存在一个问题。由于我们没有将其添加到布局中,因此我们对其宽度没有太多控制。我们可以使用 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 问题。


R
Rainmaker

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

V
Valery Boretsky

我花了几天时间寻找一个通用的解决方案。我的工具栏使用 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>

就这样


D
Diya Bhat

尝试将工具栏和标题放在单独的视图中。在右端查看并赋予它们等于工具栏权重的权重。这样,你的标题就会出现在中心位置。

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

U
Uzair Ahmed

您可以将此代码插入到您的 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文件?我正在使用从 Empty Activity 模板创建的 Android Studio 3.6.3 项目。谢谢。
A
Anbuselvan Rocky

要在工具栏中使用自定义标题,您可以添加自定义标题,例如:

<?xml version="1.0" encoding="utf-8"?>
<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/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="5dp"
    app:contentInsetLeft="0dp"
    app:contentInsetStart="0dp"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.Dark">


        <LinearLayout
            android:id="@+id/lnrTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txvHeader"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal|center"
                android:gravity="center"
                android:ellipsize="end"
                android:maxLines="1"
                android:text="Header"
                android:textColor="@color/white"
                android:textSize="18sp" />


        </LinearLayout>


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

Java 代码:

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

setSupportActionBar(toolbar);

if (getSupportActionBar() == null)
    return;

getSupportActionBar().setTitle("Title");

getSupportActionBar().setDisplayHomeAsUpEnabled(true);


标题栏左右有间距...出现了什么效果?
E
Evgenii

使用 com.google.android.material.appbar.MaterialToolbarapp:titleCentered="true" 标记

<com.google.android.material.appbar.MaterialToolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:titleCentered="true" />

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

A
Ali Khaki

对于工具栏中的自定义字体,您可以覆盖样式中的 textView 字体,然后您的应用程序中的每个 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>

Â
Ângelo Polotto

我找到了另一种添加自定义工具栏的方法,无需任何 adicional Java/Kotlin 代码。

首先:使用您的自定义工具栏布局创建一个 XML,其中 AppBarLayout 作为父级:

第二:在布局中包含工具栏:


I
Idan Damri

在我看来,您有两种选择:

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

在您设置任何内容之前,请确保您的工具栏不为空。


G
Gourav

您可以在工具栏中有一个自定义 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>