จะรับความสูงของ ActionBar ได้อย่างไร


190

ฉันพยายามรับความสูงของActionBar(โดยใช้ Sherlock) ทุกครั้งที่มีการสร้างกิจกรรม (โดยเฉพาะเพื่อจัดการกับการเปลี่ยนแปลงการกำหนดค่าในการหมุนซึ่งความสูงของ ActionBar อาจเปลี่ยนแปลง)

สำหรับเรื่องนี้ฉันใช้วิธีการActionBar.getHeight()ที่ใช้งานได้เฉพาะเมื่อActionBarมีการแสดง

เมื่อกิจกรรมแรกที่ถูกสร้างขึ้นเป็นครั้งแรกที่ฉันสามารถโทรgetHeight()ในonCreateOptionsMenuการติดต่อกลับ แต่วิธีนี้ไม่ได้ถูกเรียกหลังจาก

ดังนั้นคำถามของฉันคือเมื่อใดที่ฉันสามารถโทรหา getHeight () และมั่นใจได้ว่าจะไม่ส่งคืน 0 หรือถ้าเป็นไปไม่ได้ฉันจะตั้งความสูงของ ActionBar ได้อย่างไร?

คำตอบ:


419

ในขณะที่คำตอบ @ birdy เป็นตัวเลือกหากคุณต้องการควบคุมขนาด ActionBar อย่างชัดเจนมีวิธีดึงขึ้นมาโดยไม่ต้องล็อกขนาดที่ฉันพบในเอกสารสนับสนุน มันค่อนข้างงุ่มง่าม แต่มันก็ใช้ได้กับฉัน คุณจะต้องมีบริบทตัวอย่างนี้จะถูกต้องในกิจกรรม

// Calculate ActionBar height
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
    Int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

Kotlin :

val tv = TypedValue()
if (requireActivity().theme.resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
    val actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, resources.displayMetrics)
}

13
ความช่วยเหลือที่ดี !! แต่จากที่คุณพบสิ่งต่าง ๆ ทั้งหมด !!
vikky

5
โดยทั่วไปแล้วจาก Googling ที่ครบถ้วนสมบูรณ์หรือผ่านคู่มือนักพัฒนาซอฟต์แวร์ ฉันคิดว่าอันหลังในกรณีนี้ แต่มันก็ไม่นาน
แอนโธนี

1
เราสามารถเปลี่ยนขนาดของแถบการกระทำสำหรับกิจกรรมเฉพาะได้หรือไม่
Sudarshan Bhat

สิ่งนี้ใช้ได้ผลกับฉันในทั้งสองกรณี: (i) onCreateView และ (ii) onConfigurationChanged ขอบคุณ!
Marcelo Noguti

5
"android.R.attr.actionBarSize" ไม่ทำงานใน android เวอร์ชั่น 2.3 แต่ "R.attr.actionBarSize" ทำงานได้กับ android ทุกรุ่น เพียงแค่ใช้ "R.attr.actionBarSize" แทน "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" และอื่น ๆ
งานนาธาเนียล

148

ใน XML คุณควรใช้คุณลักษณะนี้:

android:paddingTop="?android:attr/actionBarSize"

20
ในกรณีที่คุณใช้ ActionBarCompat "@ dimen / abc_action_bar_default_height"
Ali AlNoaimi

10
ขอบคุณอาลี AlNoaimi! ด้วย AppCompat v21 ชื่อได้เปลี่ยนเป็น: "@ dimen / abc_action_bar_default_height_material"
Tony Ceralva

5
ในฐานะที่เป็น @muzikant ระบุไว้ด้านล่างสำหรับ AppCompat android.support.v7.appcompat.R.attr.actionBarSizeถ้าคุณต้องการที่จะใช้ในรหัสแอตทริบิวต์ที่ถูกต้องคือ หากคุณต้องการที่จะใช้ในรูปแบบ android:paddingTop="?attr/actionBarSize"XML, ทำงานได้ดีทุกที่
rpattabi

1
โซลูชันนี้ยอดเยี่ยมเมื่อคุณใช้ XML แบบกำหนดเอง
ลอง

2
ถ้าฉันต้องการใช้ attr นี้ แต่ติดลบเพื่อใช้กับ padding เชิงลบ ฉันจะทำสิ่งนั้นได้อย่างไร
นักพัฒนาเสือ

17

โอเคฉันกำลังไปรอบ ๆ และไปที่โพสต์นี้หลายครั้งดังนั้นฉันคิดว่ามันจะดีที่จะอธิบายไม่เพียง แต่สำหรับ Sherlock แต่สำหรับ appcompat ด้วย:

ความสูงของแถบการกระทำโดยใช้ appCompat

ค่อนข้างคล้ายกับคำอธิบาย @Anthony คุณสามารถค้นหาได้ด้วยรหัสต่อไปนี้ (ฉันเพิ่งเปลี่ยนรหัสทรัพยากร):

TypedValue tv = new TypedValue();

if (getActivity().getTheme().resolveAttribute(R.attr.actionBarSize, tv, true))
{
    int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

ปัญหาพื้นฐานของแซนด์วิช

ฉันต้องการความสูงของแถบการกระทำเนื่องจากอุปกรณ์ ICE_CREAM_SANDWITCH ก่อนหน้านี้มุมมองของฉันซ้อนทับแถบแอ็คชัน ฉันลองตั้งค่า android: layout_marginTop = "? android: attr / actionBarSize", android: layout_marginTop = "? attr / actionBarSize", การตั้งค่าเหลื่อมกันเพื่อดู / actionbar และแม้แต่ความสูงของ actionbar คงที่ด้วยธีมที่กำหนดเอง แต่ไม่มีอะไรทำงาน นั่นคือวิธีที่มันดู:

ปัญหาที่ทับซ้อนกัน

น่าเสียดายที่ฉันพบว่าด้วยวิธีการที่อธิบายไว้ข้างต้นฉันได้ครึ่งหนึ่งของความสูง (ฉันคิดว่าแถบตัวเลือกไม่ได้อยู่ในสถานที่) เพื่อแก้ไข isue อย่างสมบูรณ์ฉันต้องเพิ่มความสูงสองเท่าของแถบแอ็คชั่น

แก้ไขเหลื่อมกัน

หากมีคนรู้วิธีแก้ปัญหาที่ดีกว่า (มากกว่าการกระทำสองเท่า BarHeight) ฉันยินดีที่จะแจ้งให้ฉันทราบเมื่อฉันมาจากการพัฒนา iOS และฉันพบว่าสิ่งต่าง ๆ ในมุมมอง Android ดูค่อนข้างสับสน :)

ความนับถือ,

hris.to


ฉันพบสิ่งเดียวกันเมื่อใช้แท็บ ปัญหาคือบางครั้งยากที่จะตรวจจับแท็บเทียบกับไม่มีแท็บเนื่องจากอุปกรณ์บางอย่างมองเห็นแท็บลงใน ActionBar พื้นฐานในบางสถานการณ์ ActionBar.getHeight()ดังนั้นสิ่งที่ทำงานให้ฉันเป็นเพียง ขึ้นอยู่กับสถานการณ์ซึ่งอาจใช้ได้ผลกับคุณเช่นกัน
TalkLittle

ฉันกำลังเผชิญกับปัญหาเพราะฉันเพิ่งพิจารณาความสูงของแอ็คชั่นบาร์จากนั้นฉันก็เพิ่มความสูงของ 'แถบการแจ้งเตือน' เช่นกัน มันทำงานได้ดีสำหรับฉัน
Darpan

คุณใช้ FrameLayout และมีlayout_gravity="center_vertical"ไหม "bottom"เปลี่ยนไป Android 2.3 จัดการส่วนต่างใน FrameLaoyut แตกต่างจาก androids รุ่นใหม่
Oliv

16

@Anthony คำตอบสามารถใช้ได้กับอุปกรณ์ที่รองรับActionBarและสำหรับอุปกรณ์ที่รองรับเฉพาะSherlock Action Barวิธีต่อไปนี้เท่านั้น

    TypedValue tv = new TypedValue();
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());

    if(actionBarHeight ==0 && getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true)){
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
    }

   //OR as stated by @Marina.Eariel
   TypedValue tv = new TypedValue();
   if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
      if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
   }else if(getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true){
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
   }

คุณสามารถตัดคำแรกถ้ามี "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" เพื่อหลีกเลี่ยงข้อผิดพลาดรันไทม์บน Android รุ่นเก่า
Marina.Eariel

สำหรับฉันcom.actionbarsherlock.R.attr.actionBarSizeทำงานทั้ง Android 2.3 และ 4.0 ดังนั้นดูเหมือนว่าคุณจะสามารถใช้สิ่งนี้ได้โดยไม่คำนึงถึงรุ่น Android
เฟลิกซ์

13

ฉันคิดว่าวิธีที่ปลอดภัยที่สุดจะเป็น:

private int getActionBarHeight() {
    int actionBarHeight = getSupportActionBar().getHeight();
    if (actionBarHeight != 0)
        return actionBarHeight;
    final TypedValue tv = new TypedValue();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
    } else if (getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
    return actionBarHeight;
}

9
ในกรณีที่คุณใช้ appcompat ให้เพิ่มรายการต่อไปนี้:else if (true == getTheme().resolveAttribute( android.support.v7.appcompat.R.attr.actionBarSize, tv, true)) { actionBarHeight = TypedValue.complexToDimensionPixelSize( tv.data,getResources().getDisplayMetrics()); }
Muzikant

3
"if (true ==" ฉันคิดว่าคุณสามารถลบ "true" ... :)
นักพัฒนา Android

ใช่คุณพูดถูก ... เพิ่งเข้ามาเพื่อความกระจ่าง
Muzikant

จากรหัสของคุณดูเหมือนว่าไม่สำคัญว่าถ้าฉันใช้ ABS ในทุกรุ่นเหนือ HONEYCOMB มันจะใช้ความสูงของ actionbar จาก android.R.attr.actionBarSize ถูกต้องหรือไม่
AsafK

จะเป็นการระบุแถบการกระทำครึ่งตัวเพื่อซ่อนด้านบนของหน้าจอหรือไม่? stackoverflow.com/questions/27163374/…
Steve

6

หากต้องการตั้งค่าความสูงของActionBarคุณสามารถสร้างสิ่งใหม่Themeเช่นนี้:

<?xml version="1.0" encoding="utf-8"?>
<resources>   
    <style name="Theme.FixedSize" parent="Theme.Sherlock.Light.DarkActionBar">
        <item name="actionBarSize">48dip</item>
        <item name="android:actionBarSize">48dip</item> 
    </style> 
 </resources>

และตั้งThemeเป็นActivity:

android:theme="@style/Theme.FixedSize"

1
โปรดสังเกตว่าความสูงของแถบการกระทำนั้นเล็กกว่าในโหมดแนวนอน
Mark Buikema

ฉันไม่แนะนำสิ่งนี้เนื่องจาก actionBarSherlock คำนึงถึงเรื่องนี้เป็นอย่างมากเมื่อตัดสินใจเลือกความสูงของ actionbar หากคุณทำเช่นนี้ความสูง actionBar จะไม่ขึ้นอยู่กับข้อมูลจำเพาะของอุปกรณ์และจะไม่ดูเหมือนความสูงมาตรฐานสำหรับอุปกรณ์บางอย่าง
Chris Sprague

5

Java:

    int actionBarHeight;
    int[] abSzAttr;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        abSzAttr = new int[] { android.R.attr.actionBarSize };
    } else {
        abSzAttr = new int[] { R.attr.actionBarSize };
    }
    TypedArray a = obtainStyledAttributes(abSzAttr);
    actionBarHeight = a.getDimensionPixelSize(0, -1);

XML:

    ?attr/actionBarSize

5

หากคุณใช้ Toolbar เป็น ActionBar

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

จากนั้นเพียงใช้ layout_height ของแถบเครื่องมือ

int actionBarHeight = toolbar.getLayoutParams().height;

3

คุณสามารถใช้ฟังก์ชั่นนี้เพื่อรับความสูงของ actionbar

public int getActionBarHeight() {
    final TypedArray ta = getContext().getTheme().obtainStyledAttributes(
            new int[] {android.R.attr.actionBarSize});
    int actionBarHeight = (int) ta.getDimension(0, 0);
    return actionBarHeight;
}

2

วิธีการช่วยเหลือนี้ควรมีประโยชน์สำหรับใครบางคน ตัวอย่าง:int actionBarSize = getThemeAttributeDimensionSize(this, android.R.attr.actionBarSize);

public static int getThemeAttributeDimensionSize(Context context, int attr)
{
    TypedArray a = null;
    try{
        a = context.getTheme().obtainStyledAttributes(new int[] { attr });
        return a.getDimensionPixelSize(0, 0);
    }finally{
        if(a != null){
            a.recycle();
        }
    }
}

2

คุณเพียงแค่ต้องเพิ่มสิ่งนี้

public int getActionBarHeight() {
        int height;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            height = getActivity().getActionBar().getHeight();
        } else {
            height = ((ActionBarActivity) getActivity()).getSupportActionBar().getHeight();

        }
        return height;
    }

2

ฉันพบวิธีที่ธรรมดากว่าที่จะค้นพบมัน:

  int[] location = new int[2];
  mainView.getLocationOnScreen(location);
  int toolbarHeight = location[1];

ที่ ' mainView ' คือมุมมองรูทของโครงร่างของคุณ

โดยทั่วไปแล้วความคิดจะรับตำแหน่ง Y ของmainViewเนื่องจากตั้งอยู่ด้านล่างของแถบเครื่องมือ (หรือแถบเครื่องมือ)


2

ความสูงของแถบการกระทำแตกต่างกันไปตามชุดรูปแบบที่ใช้ หากคุณใช้AppCompatActivityความสูงจะแตกต่างกันในกรณีส่วนใหญ่จากกิจกรรมปกติ

หากคุณใช้AppCompatActivityคุณควรใช้ R.attr.actionBarSize แทน android.R.attr.actionBarSize

public static int getActionBarHeight(Activity activity) {
        TypedValue typedValue = new TypedValue();

        int attributeResourceId = android.R.attr.actionBarSize;
        if (activity instanceof AppCompatActivity) {
            attributeResourceId = R.attr.actionBarSize;
        }

        if (activity.getTheme().resolveAttribute(attributeResourceId, typedValue, true)) {
            return TypedValue.complexToDimensionPixelSize(typedValue.data, activity.getResources().getDisplayMetrics());
        }

        return (int) Math.floor(activity.getResources()
                .getDimension(R.dimen.my_default_value));
    }

2

ใน xml คุณสามารถใช้? attr / actionBarSize แต่ถ้าคุณต้องการเข้าถึงค่านั้นใน Java คุณต้องใช้รหัสด้านล่าง:

public int getActionBarHeight() {
        int actionBarHeight = 0;
        TypedValue tv = new TypedValue();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv,
                    true))
                actionBarHeight = TypedValue.complexToDimensionPixelSize(
                        tv.data, getResources().getDisplayMetrics());
        } else {
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,
                    getResources().getDisplayMetrics());
        }
        return actionBarHeight;
    }

2

วิธีการที่พร้อมในการตอบสนองคำตอบยอดนิยม:

public static int getActionBarHeight(
  Activity activity) {

  int actionBarHeight = 0;
  TypedValue typedValue = new TypedValue();

  try {

    if (activity
      .getTheme()
      .resolveAttribute(
        android.R.attr.actionBarSize,
        typedValue,
        true)) {

      actionBarHeight =
        TypedValue.complexToDimensionPixelSize(
          typedValue.data,
          activity
            .getResources()
            .getDisplayMetrics());
    }

  } catch (Exception ignore) {
  }

  return actionBarHeight;
}

2

นี่คือรุ่นที่อัปเดตกับ Kotlin ฉันใช้สมมติว่าโทรศัพท์สูงกว่า Honeycomb:

val actionBarHeight = with(TypedValue().also {context.theme.resolveAttribute(android.R.attr.actionBarSize, it, true)}) {
            TypedValue.complexToDimensionPixelSize(this.data, resources.displayMetrics)
        }

1

หากคุณใช้ Xamarin / C # นี่คือรหัสที่คุณกำลังมองหา:

var styledAttributes = Context.Theme.ObtainStyledAttributes(new[] { Android.Resource.Attribute.ActionBarSize });
var actionBarSize = (int)styledAttributes.GetDimension(0, 0);
styledAttributes.Recycle();

1
The action bar now enhanced to app bar.So you have to add conditional check for getting height of action bar.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   height = getActivity().getActionBar().getHeight();
 } else {
  height = ((ActionBarActivity) getActivity()).getSupportActionBar().getHeight();
}

0

วิธีง่ายๆในการค้นหาความสูงของ actionbar นั้นมาจากonPrepareOptionMenuวิธีกิจกรรม

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
           ....
           int actionBarHeight = getActionBar().getHeight());
           .....
    }

0

ใน javafx (โดยใช้ Gluon) ความสูงถูกตั้งค่าไว้ที่รันไทม์หรืออะไรทำนองนั้น ในขณะที่สามารถรับความกว้างได้เหมือนปกติ ...

double width = appBar.getWidth();

คุณต้องสร้างผู้ฟัง:

GluonApplication application = this;

application.getAppBar().heightProperty().addListener(new ChangeListener(){
    @Override
    public void changed(ObservableValue observable, Object oldValue, Object newValue) {
        // Take most recent value given here
        application.getAppBar.heightProperty.get()
    }
});

... และนำค่าล่าสุดมาเปลี่ยนเป็น เพื่อให้ได้ความสูง


0

หลังจากลองทุกอย่างที่อยู่ข้างนอกโดยไม่ประสบความสำเร็จฉันค้นพบโดยบังเอิญวิธีการทำงานและวิธีที่ง่ายมากในการรับความสูงเริ่มต้นของแถบแอ็คชัน

ทดสอบใน API 25 และ 24 เท่านั้น

ค#

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

ชวา

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.