ĐỒNG Ý. Sau rất nhiều nghiên cứu, kết hợp với câu trả lời được chấp nhận ở trên, tôi đã đưa ra một giải pháp cũng hoạt động nếu bạn có những thứ khác trong thanh tác vụ của mình (nút quay lại / trang chủ, nút menu). Vì vậy, về cơ bản tôi đã đặt các phương thức ghi đè trong một hoạt động cơ bản (mà tất cả các hoạt động khác đều mở rộng) và đặt mã ở đó. Mã này đặt tiêu đề của mỗi hoạt động vì nó được cung cấp trong AndroidManifest.xml và cũng thực hiện các nội dung tùy chỉnh khác (như đặt màu tùy chỉnh trên các nút trên thanh tác vụ và phông chữ tùy chỉnh trên tiêu đề). Bạn chỉ cần loại bỏ lực hấp dẫn trong action_bar.xml và thay vào đó sử dụng padding. actionBar != null
séc được sử dụng, vì không phải tất cả các hoạt động của tôi đều có.
Đã thử nghiệm trên 4.4.2 và 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);
} ...
Và action_bar.xml của tôi là như thế này (nếu có ai quan tâm):
<?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>
CHỈNH SỬA : Nếu bạn cần thay đổi tiêu đề thành một cái gì đó khác SAU KHI hoạt động được tải (onCreateOptionsMenu đã được gọi), hãy đặt một TextView khác vào action_bar.xml của bạn và sử dụng mã sau để "đệm" TextView mới này, đặt văn bản và hiển thị nó:
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) : Điều này không hoạt động với bản sửa đổi appcompat 24.2.0 (tháng 8 năm 2016), nếu hoạt động của bạn có "nút quay lại". Tôi đã gửi một báo cáo lỗi ( Sự cố 220899 ), nhưng tôi không biết liệu nó có được sử dụng hay không (nghi ngờ rằng nó sẽ sớm được sửa). Trong khi đó, giải pháp là kiểm tra xem lớp của đứa trẻ có bằng AppCompatImageButton.class hay không và làm tương tự, chỉ tăng chiều rộng thêm 30% (ví dụ: appCompatImageButton.getWidth () * 1.3 trước khi trừ giá trị này khỏi phần đệm ban đầu):
padding -= appCompatImageButton.getWidth()*1.3;
Trong thời gian đó, tôi đã ném một số kiểm tra đệm / ký quỹ vào đó:
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;
}
}