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

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

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

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

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

    

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

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

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

Расположение панели:

   

Стили:

     

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

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

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

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

     

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

  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

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

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

Ниже приведен подход, основанный на заголовке текста, для поиска экземпляра 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; } 

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

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

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

app:titleMargin для установки поля

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

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

 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 следующим образом:

     

Вам все еще нужны эти 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 . Надеюсь это поможет.

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

 static void centerToolbarTitle(@NonNull final Toolbar toolbar) { final CharSequence title = toolbar.getTitle(); final ArrayList 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); } } 
  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); } } 

Без панели инструментов 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); } 

Планировка:

    

Код:

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

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

     

Я не знаю, было ли что-то изменено в библиотеке 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; } } 

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

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

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

    

И вы можете изменить название / метку в Activity, напишите нижеприведенные коды:

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

TextView mTitle = (TextView) toolbarTop.findViewById (R.id.toolbar_title); mTitle.setText ( “@ строка / ….”);

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

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

  

и использовать его

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

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

Добавить в стили.xml :

  

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

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

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

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

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

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

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

       

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

Пытаться

 @Override public void onBackPressed() { if(getTitle().equals(getResources().getString(R.string.app_name))) { super.onBackPressed();} else { //set visiblity } } 
 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(); } }); } } } 

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

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

   

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

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

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

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

    

Это все

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

       
     

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

Попробуйте этот код:

getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getSupportActionBar().setCustomView(R.layout.toolbar_home);

 Typeface face= Typeface.createFromAsset(getAssets(), "font/font.ttf"); // your custom font Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTypeface(face); setSupportActionBar(toolbar); 

Другой учебник:

  1. Пример панели инструментов Android
  2. Использование пользовательского шрифта в Android
  3. Учебное пособие по ActionBar с примером
  • Равномерно разнесенные пункты меню на Панели инструментов
  • CollapsingToolbarLayout setTitle () не обновляется, если не свернут
  • Как использовать TabLayout с панелью инструментов внутри CollapsingToolbarLayout?
  • Панель инструментов Android Добавление элементов меню для разных fragmentов
  • На панели инструментов нет тени по умолчанию?
  • Создание экрана предпочтений с поддержкой (v21) Панели инструментов
  • Как изменить значки меню навигации и переполнения панели инструментов (appcompat v7)?
  • Давайте будем гением компьютера.