OK。多くの調査の結果、上記の受け入れられた回答と組み合わせて、アクションバーに他のもの(バック/ホームボタン、メニューボタン)がある場合にも機能する解決策を考え出しました。したがって、基本的にはオーバーライドメソッドを基本的なアクティビティ(他のすべてのアクティビティが拡張する)に配置し、そこにコードを配置しました。このコードは、AndroidManifest.xmlで提供される各アクティビティのタイトルを設定し、他のカスタム機能(アクションバーボタンにカスタムティントを設定したり、タイトルにカスタムフォントを設定するなど)も行います。action_bar.xmlで重力を省略し、代わりにパディングを使用する必要があるだけです。actionBar != null
すべてのアクティビティに1つあるわけではないため、チェックが使用されます。
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>
編集:アクティビティがロードされた後(onCreateOptionsMenuが既に呼び出されている場合)にタイトルを別の名前に変更する必要がある場合は、別のTextViewをaction_bar.xmlに配置し、次のコードを使用してこの新しい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);
}
}
編集( 2016年8月25日):アクティビティに「戻るボタン」がある場合、これはappcompat 24.2.0リビジョン(2016年8月)では機能しません。バグレポート(問題220899)を提出しましたが、それが役に立っているかどうかはわかりません(間違いはすぐに修正される予定です)。一方、解決策は、子のクラスがAppCompatImageButton.classと等しいかどうかを確認し、同じことを行うことです。幅を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;
}
}