Как центрировать выравнивание заголовка ActionBar в Android?
Я пытаюсь использовать следующий код, чтобы центрировать текст в ActionBar
, но он выравнивается влево.
Как вы делаете это в центре?
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle("Canteen Home");
actionBar.setHomeButtonEnabled(true);
actionBar.setIcon(R.drawable.back);
13 ответов:
чтобы иметь центрированный заголовок В ABS (если вы хотите иметь это по умолчанию
ActionBar
, просто удалите "поддержку" в именах методов), вы можете просто сделать это:в вашей деятельности, в вашей
onCreate()
способ:getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getSupportActionBar().setCustomView(R.layout.abs_layout);
abs_layout
:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v7.widget.AppCompatTextView android:id="@+id/tvTitle" style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:textColor="#FFFFFF" /> </LinearLayout>
теперь вы должны иметь
Actionbar
только название. Если вы хотите установить пользовательский фон, установите его в макете выше (но тогда не забудьте указатьandroid:layout_height="match_parent"
).или:
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.yourimage));
у меня не было большого успеха с другими ответами... ниже именно то, что работал для меня на Android 4.4.3 с помощью ActionBar в библиотеке поддержки v7. Я настроил его, чтобы показать значок навигационного ящика ("кнопка меню гамбургера")
XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/actionbar_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:maxLines="1" android:clickable="false" android:focusable="false" android:longClickable="false" android:textStyle="bold" android:textSize="18sp" android:textColor="#FFFFFF" /> </LinearLayout>
Java
//Customize the ActionBar final ActionBar abar = getSupportActionBar(); abar.setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_background));//line under the action bar View viewActionBar = getLayoutInflater().inflate(R.layout.actionbar_titletext_layout, null); ActionBar.LayoutParams params = new ActionBar.LayoutParams(//Center the textview in the ActionBar ! ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER); TextView textviewTitle = (TextView) viewActionBar.findViewById(R.id.actionbar_textview); textviewTitle.setText("Test"); abar.setCustomView(viewActionBar, params); abar.setDisplayShowCustomEnabled(true); abar.setDisplayShowTitleEnabled(false); abar.setDisplayHomeAsUpEnabled(true); abar.setIcon(R.color.transparent); abar.setHomeButtonEnabled(true);
определите свой собственный пользовательский вид с текстом заголовка, а затем передайте LayoutParams в setCustomView (), как говорит Сергей.
ActionBar actionBar = getSupportActionBar() actionBar.setDisplayShowCustomEnabled(true); actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); actionBar.setCustomView(getLayoutInflater().inflate(R.layout.action_bar_home, null), new ActionBar.LayoutParams( ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER ) );
редактировать: по крайней мере, для ширины, вы должны использовать wrap_content в качестве параметров или навигации ящик значок приложения и т. д. Не будет отображаться (пользовательский вид отображается поверх других представлений на панели действий). Это произойдет, особенно если кнопка действия не отображается.
редактировать: эквивалент в макете XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:orientation="vertical">
Это не требуют ни быть указано.
actionBar.setCustomView(getLayoutInflater().inflate(R.layout.action_bar_home, null);
просто быстрое дополнение к ответу Ахмада. Вы не можете использовать getSupportActionBar().setTitle больше при использовании пользовательского представления с TextView. Поэтому, чтобы установить заголовок, когда у вас есть несколько действий с этой пользовательской панелью действий (используя этот xml), в вашем методе onCreate ()после вы назначаете пользовательский вид:
TextView textViewTitle = (TextView) findViewById(R.id.mytext); textViewTitle.setText(R.string.title_for_this_activity);
ОК. После многих исследований, в сочетании с принятым ответом выше, я придумал решение, которое также работает, если у вас есть другие вещи в панели действий (кнопка "Назад/Домой", кнопка меню). Поэтому в основном я поместил методы переопределения в базовое действие (которое распространяется на все другие действия) и разместил там код. Этот код устанавливает название каждого действия, как это предусмотрено в AndroidManifest.xml, а также делает некоторые другие пользовательские вещи (например, установка пользовательского оттенка на панели действий кнопки и шрифт на заголовке). Вам нужно только оставить гравитацию в action_bar.xml, и вместо этого используйте заполнение.
actionBar != null
используется проверка, так как не все мои действия имеют один.проверено на 4.4.2 и 5.0.1
public class BaseActivity extends AppCompatActivity { private ActionBar actionBar; private TextView actionBarTitle; private Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); super.onCreate(savedInstanceState); ... getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setElevation(0); actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); actionBar.setCustomView(R.layout.action_bar); LinearLayout layout = (LinearLayout) actionBar.getCustomView(); actionBarTitle = (TextView) layout.getChildAt(0); actionBarTitle.setText(this.getTitle()); actionBarTitle.setTypeface(Utility.getSecondaryFont(this)); toolbar = (Toolbar) layout.getParent(); toolbar.setContentInsetsAbsolute(0, 0); if (this.getClass() == BackButtonActivity.class || this.getClass() == AnotherBackButtonActivity.class) { actionBar.setHomeButtonEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); Drawable wrapDrawable = DrawableCompat.wrap(getResources().getDrawable(R.drawable.ic_back)); DrawableCompat.setTint(wrapDrawable, getResources().getColor(android.R.color.white)); actionBar.setHomeAsUpIndicator(wrapDrawable); actionBar.setIcon(null); } else { actionBar.setHomeButtonEnabled(false); actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setDisplayShowHomeEnabled(false); actionBar.setHomeAsUpIndicator(null); actionBar.setIcon(null); } } try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if(menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } } catch (Exception ex) { // Ignore } } @Override public boolean onCreateOptionsMenu(Menu menu) { if (actionBar != null) { int padding = (getDisplayWidth() - actionBarTitle.getWidth())/2; MenuInflater inflater = getMenuInflater(); if (this.getClass() == MenuActivity.class) { inflater.inflate(R.menu.activity_close_menu, menu); } else { inflater.inflate(R.menu.activity_open_menu, menu); } MenuItem item = menu.findItem(R.id.main_menu); Drawable icon = item.getIcon(); icon.mutate().mutate().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN); item.setIcon(icon); ImageButton imageButton; for (int i =0; i < toolbar.getChildCount(); i++) { if (toolbar.getChildAt(i).getClass() == ImageButton.class) { imageButton = (ImageButton) toolbar.getChildAt(i); padding -= imageButton.getWidth(); break; } } actionBarTitle.setPadding(padding, 0, 0, 0); } return super.onCreateOptionsMenu(menu); } ...
и мой action_bar.xml выглядит так (если кому интересно):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/actionbar_text_color" android:textAllCaps="true" android:textSize="9pt" /> </LinearLayout>
EDIT: Если вам нужно изменить название на что-то другое после загрузки действия (onCreateOptionsMenu уже был вызван), поместите еще один элемент TextView, в action_bar.xml и использовать следующий код, чтобы "pad" этот новый TextView, установить текст и показать его:
protected void setSubTitle(CharSequence title) { if (!initActionBarTitle()) return; if (actionBarSubTitle != null) { if (title != null || title.length() > 0) { actionBarSubTitle.setText(title); setActionBarSubTitlePadding(); } } } private void setActionBarSubTitlePadding() { if (actionBarSubTitlePaddingSet) return; ViewTreeObserver vto = layout.getViewTreeObserver(); if(vto.isAlive()){ vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int padding = (getDisplayWidth() - actionBarSubTitle.getWidth())/2; ImageButton imageButton; for (int i = 0; i < toolbar.getChildCount(); i++) { if (toolbar.getChildAt(i).getClass() == ImageButton.class) { imageButton = (ImageButton) toolbar.getChildAt(i); padding -= imageButton.getWidth(); break; } } actionBarSubTitle.setPadding(padding, 0, 0, 0); actionBarSubTitlePaddingSet = true; ViewTreeObserver obs = layout.getViewTreeObserver(); obs.removeOnGlobalLayoutListener(this); } }); } } protected void hideActionBarTitle() { if (!initActionBarTitle()) return; actionBarTitle.setVisibility(View.GONE); if (actionBarSubTitle != null) { actionBarSubTitle.setVisibility(View.VISIBLE); } } protected void showActionBarTitle() { if (!initActionBarTitle()) return; actionBarTitle.setVisibility(View.VISIBLE); if (actionBarSubTitle != null) { actionBarSubTitle.setVisibility(View.GONE); } }
EDIT (25.08.2016): это не работает с редакцией appcompat 24.2.0 (август 2016), Если ваша активность имеет кнопку "Назад". Я подал сообщение об ошибке (выпуск 220899), но я не знаю, если это какая-нибудь польза (сомневаюсь, что это будет исправлено в ближайшее время). Между тем решение состоит в том, чтобы проверить, равен ли класс ребенка AppCompatImageButton.класс и сделать то же самое, только увеличить ширину на 30% (например, appCompatImageButton.getWidth () * 1.3 перед вычитанием этого значения из исходного заполнения):
padding -= appCompatImageButton.getWidth()*1.3;
в то же время я бросил туда некоторые проверки заполнения/маржи:
Class<?> c; ImageButton imageButton; AppCompatImageButton appCompatImageButton; for (int i = 0; i < toolbar.getChildCount(); i++) { c = toolbar.getChildAt(i).getClass(); if (c == AppCompatImageButton.class) { appCompatImageButton = (AppCompatImageButton) toolbar.getChildAt(i); padding -= appCompatImageButton.getWidth()*1.3; padding -= appCompatImageButton.getPaddingLeft(); padding -= appCompatImageButton.getPaddingRight(); if (appCompatImageButton.getLayoutParams().getClass() == LinearLayout.LayoutParams.class) { padding -= ((LinearLayout.LayoutParams) appCompatImageButton.getLayoutParams()).getMarginEnd(); padding -= ((LinearLayout.LayoutParams) appCompatImageButton.getLayoutParams()).getMarginStart(); } break; } else if (c == ImageButton.class) { imageButton = (ImageButton) toolbar.getChildAt(i); padding -= imageButton.getWidth(); padding -= imageButton.getPaddingLeft(); padding -= imageButton.getPaddingRight(); if (imageButton.getLayoutParams().getClass() == LinearLayout.LayoutParams.class) { padding -= ((LinearLayout.LayoutParams) imageButton.getLayoutParams()).getMarginEnd(); padding -= ((LinearLayout.LayoutParams) imageButton.getLayoutParams()).getMarginStart(); } break; } }
без customview его возможность центрировать заголовок панели действий. его прекрасно работает для навигации, а также
int titleId = getResources().getIdentifier("action_bar_title", "id", "android"); TextView abTitle = (TextView) findViewById(titleId); abTitle.setTextColor(getResources().getColor(R.color.white)); DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); abTitle.setGravity(Gravity.CENTER); abTitle.setWidth(metrics.widthPixels); getActionBar().setTitle("I am center now");
удачи в кодировании. спасибо.
Он прекрасно работает.
activity = (AppCompatActivity) getActivity(); activity.getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflater.inflate(R.layout.custom_actionbar, null); ActionBar.LayoutParams p = new ActionBar.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER); ((TextView) v.findViewById(R.id.title)).setText(FRAGMENT_TITLE); activity.getSupportActionBar().setCustomView(v, p); activity.getSupportActionBar().setDisplayShowTitleEnabled(true); activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ниже макет custom_actionbar:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:text="Example" android:layout_height="wrap_content" android:layout_centerInParent="true" android:ellipsize="end" android:maxLines="1" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/colorBlack" /> </RelativeLayout>
после многих исследований: Это действительно работает:
getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getActionBar().setCustomView(R.layout.custom_actionbar); ActionBar.LayoutParams p = new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); p.gravity = Gravity.CENTER;
вы должны определить custom_actionbar.XML-макет, который соответствует вашим требованиям, например:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:background="#2e2e2e" android:orientation="vertical" android:gravity="center" android:layout_gravity="center"> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/top_banner" android:layout_gravity="center" /> </LinearLayout>
необходимо указать
ActionBar.LayoutParams.WRAP_CONTENT
иActionBar.DISPLAY_HOME_AS_UP
View customView = LayoutInflater.from(this).inflate(R.layout.actionbar_title, null); ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER); getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP );
лучший и самый простой способ, специально для тех, кто просто хочет текстовый вид с центром тяжести без каких-либо XML-макета.
AppCompatTextView mTitleTextView = new AppCompatTextView(getApplicationContext()); mTitleTextView.setSingleLine(); ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT); layoutParams.gravity = Gravity.CENTER; actionBar.setCustomView(mTitleTextView, layoutParams); actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP); mTitleTextView.setText(text); mTitleTextView.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Medium);
другие учебники, которые я видел, переопределяют весь макет панели действий, скрывающий элементы меню. Я получил его работал, просто делая следующие шаги:
создайте xml-файл следующим образом:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:ellipsize="end" android:maxLines="1" android:text="@string/app_name" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@android:color/white" /> </RelativeLayout>
и в классе сделать это:
LayoutInflater inflator = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflator.inflate(R.layout.action_bar_title, null); ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER); TextView titleTV = (TextView) v.findViewById(R.id.title); titleTV.setText("Test");
этот код не будет скрывать кнопку Назад, в то же время выровняет заголовок по центру.
вызовите этот метод в oncreate
centerActionBarTitle(); getSupportActionBar().setDisplayHomeAsUpEnabled(true); myActionBar.setIcon(new ColorDrawable(Color.TRANSPARENT)); private void centerActionBarTitle() { int titleId = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { titleId = getResources().getIdentifier("action_bar_title", "id", "android"); } else { // This is the id is from your app's generated R class when // ActionBarActivity is used for SupportActionBar titleId = R.id.action_bar_title; } // Final check for non-zero invalid id if (titleId > 0) { TextView titleTextView = (TextView) findViewById(titleId); DisplayMetrics metrics = getResources().getDisplayMetrics(); // Fetch layout parameters of titleTextView // (LinearLayout.LayoutParams : Info from HierarchyViewer) LinearLayout.LayoutParams txvPars = (LayoutParams) titleTextView.getLayoutParams(); txvPars.gravity = Gravity.CENTER_HORIZONTAL; txvPars.width = metrics.widthPixels; titleTextView.setLayoutParams(txvPars); titleTextView.setGravity(Gravity.CENTER); } }
для пользователей Kotlin:
используйте в своей деятельности следующий код:
// Set custom action bar supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM supportActionBar?.setCustomView(R.layout.action_bar) // Set title for action bar val title = findViewById<TextView>(R.id.titleTextView) title.setText(resources.getText(R.string.app_name))
и макет XML/ resource:
<?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"> <TextView android:id="@+id/titleTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Title" android:textColor="@color/black" android:textSize="18sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>