Tytuł środkowego paska narzędzi Androida i niestandardowa czcionka

366

Próbuję znaleźć właściwy sposób użycia niestandardowej czcionki dla tytułu paska narzędzi i wyśrodkować go na pasku narzędzi (wymaganie klienta).

W tej chwili używam starego, dobrego ActionBar, a ja ustawiałem tytuł na pustą wartość, i setCustomViewużywałem do umieszczenia niestandardowej czcionki TextView i wyśrodkowania jej za pomocą ActionBar.LayoutParams.

Czy jest na to lepszy sposób? Używanie nowego paska narzędzi jako mojego paska działań.

Mathbl
źródło

Odpowiedzi:

718

Aby użyć niestandardowego tytułu we Toolbarwszystkim, co musisz zrobić, pamiętaj, że Toolbarjest to tylko fantazyjna grupa ViewGroup, dzięki czemu możesz dodać niestandardowy tytuł w następujący sposób:

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

Oznacza to, że możesz stylizować w TextViewdowolny sposób, ponieważ jest to zwykły styl TextView. Dzięki temu możesz uzyskać dostęp do tytułu w następujący sposób:

Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);
TextView mTitle = (TextView) toolbarTop.findViewById(R.id.toolbar_title);
MrEngineer13
źródło
5
sugeruj użycie androida: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_gravity = "center" zamiast tego.
SteelBytes
194
Jeśli nikt inny nie może usunąć domyślnego tytułu nazwy aplikacji, wykonaj następujące czynności: 1. Wywołaj setSupportActionBar (yourToolbar) 2. Wywołaj getSupportActionBar (). SetDisplayShowTitleEnabled (false);
Rick Sanchez,
75
Aby nadal używać domyślnych stylów dostosowanego TextView, spróbuj czegoś takiego style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"( zobacz tę odpowiedź ).
Jonik
5
dodanie Androida: paddingRight = "? attr / actionBarSize" może pomóc wyśrodkować tekst na środku ekranu w przypadku, gdy masz przycisk (strona główna, szuflada nawigacji itp.)
Gordak
5
Co się stanie, gdy na pasku narzędzi pojawi się ikona Hamburger? Nie będzie w środku pełnej szerokości paska narzędzi, będzie w środku ToolbarWidth - HamburgerIconWidth .
Akshay
75

Tytuł paska narzędzi można rysować. Wszelkie dostosowania, które wprowadzisz, muszą być wykonane w motywie. Dam ci przykład.

Układ paska narzędzi:

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

<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>
Binoy Babu
źródło
59
To jest właściwy sposób. Dodanie kolejnej TextViewjest trochę hackerskie, ale odpowiedź refleksyjna to po prostu zło.
DariusL
9
Wyczyść, ale nie można ustawić niestandardowej czcionki ze stylu. Niestety
niqueco
20
Nie można również zmienić wyrównania tytułu.
Terry,
7
@ user1560102 nie ma nic dziwnego w dodawaniu TextView do paska narzędzi. Do tego został zaprojektowany.
Tim Malseed,
107
To nie wyśrodkowuje tekstu.
Sebastian Roth,
69

To tylko po to, aby połączyć wszystkie elementy za pomocą odpowiedzi @ MrEngineer13 z komentarzami @Jonik i @Rick Sanchez w odpowiedniej kolejności, aby łatwo osiągnąć tytuł wyśrodkowany !!

Układ z 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>

Sposób na osiągnięcie w odpowiedniej kolejności:

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

Nie zapomnij upvote @ MrEngineer13 odpowiedzieć !!!

Oto przykładowy projekt ToolbarCenterTitleSample

wprowadź opis zdjęcia tutaj

Mam nadzieję, że pomogę komuś innemu;)

Gueorgui Obregon
źródło
5
jeśli ustawię setDisplayHomeAsUpEnabled (true) i setDisplayShowHomeEnabled (true); enalbe strzałka wstecz. Zatem tytuł nie będzie centrum. Próbowałem ustawić akcję actionBar.setTitle („”); i setDisplayShowTitleEnabled (false). Ale nadal nie jest w stanie rozwiązać problemu
Prashanth Debbadwar
Czy przetestowałeś to dla Scrolling Activity?
AN
to prawda, że ​​w przypadku tylnej strzałki tytuł nie jest wyśrodkowany (jest przesunięty w prawo o połowę szerokości strzałki w tył). Podejrzewam, że gdybym był naprawdę zdeterminowany, programowo dodam wystarczający margines z prawej strony pola tekstowego, jeśli to konieczne, aby wyśrodkować tekst.
Ktoś gdzieś
52

nie mamy bezpośredniego dostępu do tytułu paska narzędzi TextView, więc używamy refleksji, aby uzyskać do niego dostęp.

  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;
}
BugsBunnyBR
źródło
3
Chociaż jest to hacking, to rozwiązanie działa dla mnie po próbie znalezienia sposobu na uzyskanie dostępu do widoku tekstu paska narzędzi. Dziękuję Ci.
falc0nit3
1
Ładnie działało na tytuł. Ale gdy próbowano uzyskać mSubtitleTextView w ten sposób, spowodowało to wyjątek. Przyczyna: java.lang.NullPointerException: Próba wywołania metody wirtualnej „void android.widget.TextView.setTypeface (android.graphics.Typeface)” w odwołaniu do obiektu o wartości null
Vinod
5
Uwaga: Dostęp do pola „mTitleTextView” można uzyskać tylko po ustawieniu tytułu paska narzędzi! Pole jest leniwe inicjowane przy pierwszym użyciu.
funcoder
2
Co się stanie, jeśli zaciemnisz swój kod za pomocą ProGuard i stanie mTitleTextViewsię abcde12345?
voghDev
1
@voghDev getDeclaredField wygeneruje wyjątek NoSuchFieldException, co spowoduje, że kod nie będzie działał.
Jeremy,
30

Oto podejście zależne od tekstu tytułu do znalezienia TextViewinstancji 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;
}
Nikola Despotoski
źródło
28

Zdefiniuj następującą klasę:

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

... a następnie użyj go zamiast zwykłego w Toolbarten sposób:

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

Nadal potrzebujesz tych 2 linii kodu Activity(jak w standardzie 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);

Otóż ​​to! Nie musisz ukrywać standardowego wyrównanego do lewej tytułu tytułu, nie musisz powtarzać tego samego kodu XML w kółko itp., Po prostu użyj go CenteredToolbartak, jakby był domyślny Toolbar. Możesz także programowo ustawić własną czcionkę, ponieważ masz teraz bezpośredni dostęp do TextView. Mam nadzieję że to pomoże.

fraggjkee
źródło
1
Dzięki! Najlepsze rozwiązanie, ale nie zapomnij zaimportować do paska narzędzi „v7.widget”
David
Wiem, że to jest dość stare, ale ... jak mogę zmienić kolor tekstu? Próbowałem w XML z app: titleTextColor i w kodzie z centereredTitleTextView.setColor. Wszelkie pomysły, @fraggjkee?
Genaro Alberto Cancino Herrera
centeredTitleTextView.setTextColor(...)powinien działać
fraggjkee
Nie powinno tak być LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)?
liminal
16

Nikt o tym nie wspominał, ale istnieją pewne atrybuty Toolbar:

app:titleTextColor do ustawiania koloru tekstu tytułowego

app:titleTextAppearance do ustawiania wyglądu tekstu tytułowego

app:titleMargin do ustalenia marginesu

Są też inne marginesy po stronie konkretnej, takie jak marginStartitp.

Ab ِ
źródło
1
Idealne rozwiązanie ... jeśli znasz FontOverride , po prostu stwórz styl w styles.xml <style name="customFontTextAppearanceStyle"> <item name="android:textSize">18sp</item> <item name="android:typeface">monospace</item> i zastosuj go na pasku narzędzi app:titleTextAppearance="@styles/customFontTextAppearanceStyle"
Chinmay Thoriya
2
Użyłem tej metody, ale na pasku narzędzi nic się nie stało! utworzyłem nowy „<style>” i ustawiłem go app:titleTextAppearanc="style name" na android.support.v7.widget.ToolbarTAG
AN
12

Korzystam z tego rozwiązania:

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);
    }
}
ultraon
źródło
1
Działa bardzo dobrze, ale z jakiegoś powodu nie wyśrodkowuje prawidłowo pasków narzędzi, które nie mają przycisku pozycji.
Munib
1
Dodatek: jeśli na pasku narzędzi znajduje się ikona kreślarki lub ikona cofania, tytuł nie pozostaje dokładnie w środku. Dodaję pustą ikonę menu ustawień dla tej sytuacji. Moja pusta pozycja menu to: <pozycja android: id = "@ + id / empty" android: orderInCategory = "100" android: icon = "@ android: color / transparent" aplikacja: showAsAction = "always" tools: ignore = " MenuTitle "/>
Mete
10

Bez paska narzędzi TextView możemy dostosować czcionkę za pomocą poniższego kodu

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);
}
Ajit Kumar Dubey
źródło
1
Jeśli potrzebujesz tylko zmienić czcionkę, wydaje się to najbardziej czystym rozwiązaniem. UWAGA: TypefaceSpanString jest właśnie taki: stackoverflow.com/a/17961854
Mohib Irshad
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);
    }
}
Shatazone
źródło
1
rozwiązanie działa świetnie, gdy wypuścisz ostatnie dwa wiersze kodu, nie powinno ono znajdować się w pętli for: // Przywróć tytuł i napisy toolbar.setTitle (originalTitle); toolbar.setSubtitle (originalSubtitle);
Ivan Stojkovic
5

Układ:

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

Kod:

    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);
maros136
źródło
1
Myślę, że „int width = maxWidth - titleWidth * 2;” powinno być „int width = maxWidth - iconWidth * 2;”, myśli!
oldfeel
4

Rozwiązałem to rozwiązanie, a są to następujące kody:

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

I możesz zmienić tytuł / etykietę, w Activity, napisz poniższe kody:

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

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

Hai Rom
źródło
4

Możesz użyć w następujący sposób

 <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>
Sharma
źródło
jeśli ustawię setDisplayHomeAsUpEnabled (true) i setDisplayShowHomeEnabled (true); enalbe strzałka wstecz. Zatem tytuł nie będzie centrum. Próbowałem ustawić akcję actionBar.setTitle („”); i setDisplayShowTitleEnabled (false). Ale nadal nie jest w stanie rozwiązać problemu
Prashanth Debbadwar
4

Bardzo szybkim i łatwym sposobem ustawienia niestandardowej czcionki jest użycie niestandardowej titleTextAppearancez fontFamily:

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

W folderze res utwórz folder czcionek (np .: varela_round_regular.ttf )

Przeczytaj oficjalny przewodnik, aby dowiedzieć się więcej https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

vovahost
źródło
3

Nie wiem, czy coś się zmieniło w bibliotece appcompat, ale jest to dość trywialne, nie wymaga refleksji.

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

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

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

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

    // assuming that the title is the first instance of TextView
    // you can also check if the title string matches
    if (child instanceof TextView) {
        toolbarTitle = (TextView)child;
        break;
    }
}
headsvk
źródło
3

Rozwiązanie zastosowane w przypadku tego problemu:

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

Myślę, że dla grawitacji środkowej konieczna byłaby zmiana parametrów układu na match_parent w poziomie, a następnie:

tv.setGravity(Gravity.CENTER);
Monet_z_Polski
źródło
3

Aktualizacja z odpowiedzi @ MrEngineer13: aby wyrównać centrum tytułu w każdym przypadku, w tym ikonę Hamburger, menu opcji, możesz dodać FrameLayoutpasek narzędzi w następujący sposób:

   <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>
R4j
źródło
3

W XML spróbuj tego:

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

W kodzie:

Toolbar myToolbar= (Toolbar) findViewById(R.id.toolbar);
TextView mTitle = (TextView) mytoolbar.findViewById(R.id.toolbar_title);
mohamad sheikhi
źródło
2

Chociaż dodanie widoku tekstu do paska narzędzi może rozwiązać problem ograniczenia stylu tytułowego, jest z tym problem. Ponieważ nie dodajemy go do układu, nie mamy zbyt dużej kontroli nad jego szerokością. Możemy użyć wrap_content lub match_parent.

Rozważmy teraz scenariusz, w którym mamy searchView jako przycisk na prawej krawędzi paska narzędzi. Jeśli zawartość tytułu jest większa, zostanie zasłonięty przycisk na górze. Nie ma sposobu na kontrolowanie tego braku ustawiania szerokości etykiety i jest to coś, czego nie chcesz robić, jeśli chcesz mieć responsywny projekt.

Oto rozwiązanie, które działało dla mnie i różni się nieco od dodania widoku tekstu do paska narzędzi. Zamiast tego dodaj pasek narzędzi i widok tekstu do względnego układu i upewnij się, że widok tekstu znajduje się na górze paska narzędzi. Następnie możemy użyć odpowiednich marginesów i upewnić się, że widok tekstu pokazuje się tam, gdzie chcemy.

Upewnij się, że ustawiłeś pasek narzędzi tak, aby nie wyświetlał tytułu.

Oto kod XML tego rozwiązania:

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

Rozwiązuje problem @ ankur-chaudhary wspomniany powyżej.

Deepak GM
źródło
2

Ponieważ android.support.v7.appcompat 24.2 Toolbarma metodę setTitleTextAppearancei możesz ustawić jej czcionkę bez zewnętrznego textview.

stwórz nowy styl w styles.xml

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

i użyj go

mToolbar.setTitleTextAppearance(this, R.style.RobotoBoldTextAppearance);
Zaklinacz deszczu
źródło
2

Kilka dni spędziłem na poszukiwaniu uniwersalnego rozwiązania. Mój pasek narzędzi działa z menu Androida i ikoną nawigacji.

Najpierw musisz utworzyć niestandardową klasę paska narzędzi. Ta klasa musi obliczać pozycje wyśrodkowane (wypełnienia):

    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)

}

Po drugie, musisz utworzyć pasek narzędzi układu:

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

To wszystko

Valery Boretsky
źródło
2

Spróbuj wziąć pasek narzędzi i tittle w osobnym widoku. Zobacz prawy koniec i nadaj im wagę równą ciężarowi paska narzędzi. W ten sposób twój tytuł znajdzie się na środku.

<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>
Diya Bhat
źródło
2

Możesz wstawić ten kod do pliku 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>
Uzair Ahmed
źródło
Cześć Uzair. Który plik XML? Korzystam z projektu Android Studio 3.6.3 utworzonego z szablonu pustej aktywności. Dzięki.
Miłość i pokój - Joe Codeswell
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();
                }
            });
        }
    }
}
wklbeta
źródło
1

Otoczenie android:gravity="center"działało dla mnie

Bez stylizacji. Pasek narzędzi to w zasadzie ViewGroupwszystko, co musisz zrobić, to ustawić w nim grawitację elementów.

        <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" />
Hitesh Sahu
źródło
8
Nie działa zandroidx.appcompat.widget.Toolbar
tmm1
1

dla niestandardowej czcionki na pasku narzędzi można przesłonić tekst Zobacz stylowo czcionkę, a następnie każdy tekst Zobacz w aplikacji również czcionka tytułu paska narzędzi zmieniana automatycznie Testowałem to w Android Studio 3.1.3

zrób to w stylu:

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

a następnie użyj w swoim motywie tego:

<item name="android:textViewStyle">@style/defaultTextViewStyle</item>
Ali Khaki
źródło
1

Znalazłem inny sposób na dodanie niestandardowego paska narzędzi bez dodatkowego kodu Java / Kotlin.

  • Po pierwsze: utwórz kod XML z niestandardowym układem paska narzędzi, używając AppBarLayout jako elementu nadrzędnego:

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

  • Po drugie: dołącz pasek narzędzi do swojego układu:

    <?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>
Ângelo Polotto
źródło
1

Widzę, że masz dwie opcje:

1) Edytuj XML paska narzędzi. Po dodaniu paska narzędzi do pliku XML zwykle wygląda to tak:

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

jeśli chcesz go dostosować, po prostu usuń „/” na końcu i ustaw go w ten sposób:

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

w ten sposób możesz mieć pasek narzędzi i dostosować widok tekstu i logo.

2) Programowo zmień natywny widok tekstu i ikonę:

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

upewnij się, że pasek narzędzi nie ma wartości zerowej, zanim cokolwiek w nim ustawisz.

Idan Damri
źródło
1

Możesz mieć niestandardowy TextViewna pasku narzędzi, taki jak ten:

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

To wyśrodkuje tekst. Jeśli chcesz dodać niestandardową czcionkę do normalnej Toolbar, wykonaj <style>:

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

I dodaj go do paska narzędzi:

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

Dla widoku tekstu na pasku narzędzi możesz go zdefiniować za pomocą fontFamilyatrybutu:

<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>
Gourav
źródło
1

Napotkałem ten sam problem, naprawiony przez wykonanie tego w MainActivity

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

I we fragmencie

@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);
}
VINAY DANARADDI
źródło