¿Cómo centrar el título de ActionBar en Android?

Estoy tratando de usar el siguiente código para centrar el texto en la ActionBar , pero se alinea a la izquierda.

¿Cómo lo haces aparecer en el centro?

 ActionBar actionBar = getActionBar(); actionBar.setDisplayShowTitleEnabled(true); actionBar.setTitle("Canteen Home"); actionBar.setHomeButtonEnabled(true); actionBar.setIcon(R.drawable.back); 

Tener un título centrado en ABS (si desea tener esto en la ActionBar predeterminada, simplemente elimine el “soporte” en los nombres de los métodos), puede hacer esto:

En tu actividad, en tu método onCreate() :

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

abs_layout :

     

Ahora debería tener una Actionbar con solo un título. Si desea establecer un fondo personalizado, android:layout_height="match_parent" en el Diseño anterior (pero no olvide configurar android:layout_height="match_parent" ).

o con:

 getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.yourimage)); 

No he tenido mucho éxito con las otras respuestas … a continuación es exactamente lo que funcionó para mí en Android 4.4.3 usando ActionBar en la biblioteca de soporte v7. Lo tengo configurado para mostrar el ícono del cajón de navegación (“botón del menú de hamburguesas”)

XML

      

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

Defina su propia vista personalizada con el texto del título, luego pase LayoutParams a setCustomView (), como dice Sergii.

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

EDITADO : al menos para el ancho, debe usar WRAP_CONTENT o su cajón de navegación, icono de la aplicación, etc. NO SE MOSTRARÁN (la vista personalizada se muestra en la parte superior de otras vistas en la barra de acciones). Esto ocurrirá especialmente cuando no se muestra ningún botón de acción.

EDITADO : Equivalente en el diseño xml:

  

Esto no requiere que se especifique LayoutParams.

 actionBar.setCustomView(getLayoutInflater().inflate(R.layout.action_bar_home, null); 

Solo una rápida adición a la respuesta de Ahmad. Ya no puede usar getSupportActionBar (). SetTitle cuando usa una vista personalizada con un TextView. Por lo tanto, para establecer el título cuando tiene varias actividades con esta barra de acciones personalizada (utilizando este xml), en su método onCreate () después de asignar una vista personalizada:

 TextView textViewTitle = (TextView) findViewById(R.id.mytext); textViewTitle.setText(R.string.title_for_this_activity); 

DE ACUERDO. Después de una gran cantidad de investigación, combinada con la respuesta aceptada anteriormente, he encontrado una solución que también funciona si tienes otras cosas en tu barra de acción (botón de inicio / inicio, botón de menú). Básicamente, puse los métodos de anulación en una actividad básica (que todas las otras actividades se extienden) y coloqué el código allí. Este código establece el título de cada actividad tal como se proporciona en AndroidManifest.xml, y también hace otras cosas personalizadas (como establecer un tinte personalizado en los botones de la barra de acciones y una fuente personalizada en el título). Solo necesitas dejar de lado la gravedad en action_bar.xml, y usar el relleno en su lugar. actionBar != null se utiliza la verificación actionBar != null , ya que no todas mis actividades tienen una.

Probado en 4.4.2 y 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); } ... 

Y mi action_bar.xml es así (si alguien está interesado):

     

EDITAR : Si necesita cambiar el título a algo más DESPUÉS de que se cargue la actividad (ya se ha llamado a onCreateOptionsMenu), coloque otro TextView en su action_bar.xml y use el siguiente código para "rellenar" este nuevo TextView, establecer texto y mostrar eso:

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

EDITAR (25.08.2016) : Esto no funciona con la revisión appcompat 24.2.0 (agosto de 2016), si su actividad tiene un "botón Atrás". Archivé un informe de error ( Número 220899 ), pero no sé si es útil (duda que se solucionará pronto). Mientras tanto, la solución es comprobar si la clase del niño es igual a AppCompatImageButton.class y hacer lo mismo, solo boost el ancho en un 30% (por ejemplo, appCompatImageButton.getWidth () * 1.3 antes de restar este valor del relleno original):

 padding -= appCompatImageButton.getWidth()*1.3; 

Mientras tanto, lancé algunos controles de relleno / margen allí:

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

sin vista personalizada es capaz de centrar el título de la barra de acciones. también funciona perfectamente para el cajón de navegación

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

Feliz encoding. gracias.

Funciona bien

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

Abajo el diseño de la barra de ejecución personalizada:

     

Después de mucha investigación: Esto realmente funciona:

  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; 

Debe definir el diseño custom_actionbar.xml, que es según su requisito, por ejemplo:

     

ActionBar.LayoutParams.WRAP_CONTENT establecer ActionBar.LayoutParams.WRAP_CONTENT y 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 ); 

Los otros tutoriales que he visto anulan todo el diseño de la barra de acciones que oculta los elementos del menú. Lo hice funcionar solo siguiendo los siguientes pasos:

Crea un archivo xml de la siguiente manera:

     

Y en el classe hazlo:

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

Este código no ocultará el botón Atrás, Mismo tiempo alineará el título en el centro.

llama a este método en 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); } } 

Para los usuarios de Kotlin:

Usa el siguiente código en tu actividad:

 // Set custom action bar supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM supportActionBar?.setCustomView(R.layout.action_bar) // Set title for action bar val title = findViewById(R.id.titleTextView) title.setText(resources.getText(R.string.app_name)) 

Y el diseño de XML / recursos:

     

La mejor y más fácil manera, específicamente para aquellos que solo quieren ver texto con el centro de gravedad sin ningún diseño 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);