ตกลง. หลังจากการวิจัยจำนวนมากรวมกับคำตอบที่ยอมรับข้างต้นฉันได้พบวิธีแก้ปัญหาที่ใช้ได้ผลเช่นกันหากคุณมีสิ่งอื่นในแถบการทำงาน (ปุ่มย้อนกลับ / ปุ่มโฮมปุ่มเมนู) โดยพื้นฐานแล้วฉันได้ใส่วิธีการแทนที่ในกิจกรรมพื้นฐาน (ซึ่งกิจกรรมอื่น ๆ ทั้งหมดขยายออกไป) และวางโค้ดไว้ที่นั่น รหัสนี้ตั้งชื่อของแต่ละกิจกรรมตามที่ระบุไว้ใน 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) {
}
}
@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 ของคุณและใช้รหัสต่อไปนี้เพื่อ "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);
}
}
แก้ไข (25.08.2016) : สิ่งนี้ใช้ไม่ได้กับการแก้ไข appcompat 24.2.0 (สิงหาคม 2016) หากกิจกรรมของคุณมี "ปุ่มย้อนกลับ" ฉันยื่นรายงานข้อผิดพลาด ( ฉบับ 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;
}
}