Làm thế nào để có được chiều cao ActionBar?


190

Tôi đang cố gắng lấy chiều cao của ActionBar(sử dụng Sherlock) mỗi khi một hoạt động được tạo (đặc biệt để xử lý các thay đổi cấu hình khi xoay trong đó chiều cao ActionBar có thể thay đổi).

Đối với điều này, tôi sử dụng phương thức ActionBar.getHeight()chỉ hoạt động khi ActionBarđược hiển thị.

Khi hoạt động đầu tiên được tạo lần đầu tiên, tôi có thể gọi lại getHeight()trong cuộc onCreateOptionsMenugọi lại. Nhưng phương pháp này không được gọi sau.

Vì vậy, câu hỏi của tôi là khi nào tôi có thể gọi getHeight () và yên tâm rằng nó không trả về 0? Hoặc nếu không thể, làm cách nào tôi có thể đặt chiều cao của ActionBar?

Câu trả lời:


417

Mặc dù câu trả lời của @ birdy là một tùy chọn nếu bạn muốn kiểm soát rõ ràng kích thước ActionBar, có một cách để kéo nó lên mà không khóa kích thước mà tôi tìm thấy trong tài liệu hỗ trợ. Hơi khó xử một chút nhưng nó hiệu quả với tôi. Bạn sẽ cần một bối cảnh, ví dụ này sẽ hợp lệ trong một Hoạt động.

// 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
giúp đỡ nhiều !! nhưng từ nơi bạn tìm thấy tất cả những thứ như vậy !!
vikky

5
Nói chung từ Googling đầy đủ hoặc vất vả thông qua sổ tay nhà phát triển. Tôi nghĩ rằng sau này trong trường hợp này, nhưng nó đã được một thời gian.
Anthony

1
Chúng ta có thể thay đổi kích thước thanh hành động chỉ cho một hoạt động cụ thể không?
Sudarshan Bhat

Điều này làm việc cho tôi trong cả hai trường hợp: (i) onCreateView và (ii) onConfigurationChanged. Cảm ơn!
Marcelo Noguti

5
"Android.R.attr.actionBarSize" không hoạt động trong phiên bản Android 2.3, nhưng "R.attr.actionBarSize" đang hoạt động trên Android tất cả các phiên bản. chỉ sử dụng "R.attr.actionBarSize" thay vì "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" và v.v.
Nathaniel Jobs

147

Trong XML, bạn nên sử dụng thuộc tính này:

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

20
trong trường hợp bạn đang sử dụng ActionBarCompat "@ dimen / abc_action_bar_default_height"
Ali AlNoaimi

10
Cảm ơn Ali AlNoaimi! Với AppCompat v21, tên đã được đổi thành: "@ dimen / abc_action_bar_default_height_m vật liệu"
Tony Ceralva

5
Như @muzikant đã đề cập dưới đây, đối với appcompat, nếu bạn muốn sử dụng nó trong mã, thuộc tính chính xác là android.support.v7.appcompat.R.attr.actionBarSize. Nếu bạn muốn sử dụng nó trong layout xml , android:paddingTop="?attr/actionBarSize". Hoạt động tốt ở mọi nơi.
rpattabi

1
Giải pháp này thật tuyệt vời khi bạn đang sử dụng một framelayout XML tùy chỉnh.
thử 18/03/2016

2
Nếu tôi muốn sử dụng attr này nhưng phủ định để sử dụng nó với phần đệm âm. Làm thế nào tôi có thể làm điều đó?
phát triển Tiger

17

Ok tôi đã đi vòng quanh và nhận được bài đăng này nhiều lần vì vậy tôi nghĩ sẽ rất tốt khi được mô tả không chỉ cho Sherlock mà còn cho cả appcompat:

Chiều cao thanh hành động bằng appCompat

Khá giống với mô tả @Anthony bạn có thể tìm thấy nó với đoạn mã sau (Tôi vừa thay đổi id tài nguyên):

TypedValue tv = new TypedValue();

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

Vấn đề trước Sandwitch

Tôi cần chiều cao của thanh hành động vì trên các thiết bị ICE_CREAM_SANDWITCH trước, chế độ xem của tôi nằm trên thanh hành động. Tôi đã thử cài đặt android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize", thiết lập chồng chéo để xem / thanh hành động và thậm chí cố định chiều cao của thanh hành động với chủ đề tùy chỉnh nhưng không có gì hiệu quả. Đó là cách nó trông:

vấn đề chồng chéo

Thật không may, tôi phát hiện ra rằng với phương pháp được mô tả ở trên, tôi chỉ nhận được một nửa chiều cao (tôi cho rằng thanh tùy chọn không được đặt đúng chỗ) vì vậy để khắc phục hoàn toàn vấn đề tôi cần tăng gấp đôi chiều cao của thanh hành động và mọi thứ có vẻ ổn:

cố định chồng chéo

Nếu ai đó biết giải pháp tốt hơn (hơn là nhân đôi hành độngBarHeight) tôi sẽ vui mừng cho tôi biết khi tôi đến từ sự phát triển của iOS và tôi thấy hầu hết các công cụ của chế độ xem Android khá khó hiểu :)

Trân trọng,

hris.to


Tôi đã trải nghiệm điều tương tự khi sử dụng các tab. Vấn đề là đôi khi rất khó để phát hiện các tab so với không có tab, vì một số thiết bị trực quan thu gọn các tab vào ActionBar cơ bản trong một số trường hợp. Vì vậy, những gì làm việc cho tôi chỉ là ActionBar.getHeight(). Tùy thuộc vào tình huống, điều đó có thể làm việc cho bạn quá.
TalkLittle

Tôi đã phải đối mặt với vấn đề vì tôi chỉ đang xem xét chiều cao của thanh hành động, sau đó tôi cũng đã thêm chiều cao của 'thanh thông báo'. Nó làm việc tốt cho tôi.
Darpan

Bạn có sử dụng FrameLayout và có layout_gravity="center_vertical"? Thay đổi nó thành "bottom". Android 2.3 xử lý lề trong FrameLaoyut khác với Android mới hơn.
Oliv

16

Câu trả lời @Anthony hoạt động cho các thiết bị hỗ trợ ActionBarvà cho các thiết bị chỉ hỗ trợ Sherlock Action Barphương pháp sau phải được sử dụng

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

Bạn có thể gói đầu tiên nếu bằng "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" để tránh lỗi thời gian chạy trên các phiên bản Android cũ hơn.
Bến du thuyền.Eariel 18/03/13

Đối với tôi com.actionbarsherlock.R.attr.actionBarSizeđã làm việc cho cả Android 2.3 và 4.0, vì vậy có vẻ như bạn có thể sử dụng ứng dụng này bất kể phiên bản Android.
Felix

13

tôi nghĩ cách an toàn nhất sẽ là:

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
trong trường hợp bạn đang sử dụng appcompat, hãy thêm vào như sau: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 =="? Tôi nghĩ bạn có thể xóa "true" ... :)
nhà phát triển Android

Vâng, bạn đã đúng ... điều đó chỉ được thêm vào cho rõ ràng
Muzikant

Từ mã của bạn, có vẻ như không có vấn đề gì nếu tôi sử dụng ABS, trong tất cả các phiên bản trên HONEYCOMB, nó sẽ lấy chiều cao của thanh hành động từ android.R.attr.actionBarSize. Điều này có đúng không?
AsafK

Có phải dù sao cũng chỉ định một nửa thanh hành động để ẩn đầu màn hình? stackoverflow.com/questions/27163374/ trộm
Steve

6

Để thiết lập chiều cao của ActionBarbạn, bạn có thể tạo mới Themenhư thế này:

<?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>

và đặt cái này Themethành của bạn Activity:

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

1
Lưu ý rằng chiều cao của thanh hành động nhỏ hơn ở chế độ ngang.
Đánh dấu Buikema

Tôi không khuyến nghị điều này vì actionBarSherlock tính đến rất nhiều khi quyết định chiều cao của thanh hành động. Nếu bạn làm điều này, chiều cao ActionBar sẽ không dựa trên thông số kỹ thuật của thiết bị và do đó sẽ không giống chiều cao tiêu chuẩn cho một số thiết bị nhất định.
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

Nếu bạn đang sử dụng Thanh công cụ làm ActionBar,

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

sau đó chỉ cần sử dụng layout_height của thanh công cụ.

int actionBarHeight = toolbar.getLayoutParams().height;

3

bạn có thể sử dụng chức năng này để có được chiều cao của thanh hành động.

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

Phương pháp trợ giúp này sẽ có ích cho một ai đó. Thí dụ: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

bạn chỉ cần thêm cái này

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

Tôi tìm thấy một cách chung hơn để khám phá nó:

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

trong đó ' mainView ' là chế độ xem gốc của bố cục của bạn.

Ý tưởng về cơ bản là lấy vị trí Y của mainView vì nó được đặt ngay bên dưới ActionBar (hoặc Thanh công cụ).


2

Chiều cao thanh hành động khác nhau theo chủ đề được áp dụng. Nếu bạn đang sử dụng AppCompatActivity , chiều cao sẽ khác trong hầu hết các trường hợp so với Hoạt động bình thường.

Nếu bạn đang sử dụng AppCompatActivity, bạn nên sử dụng R.attr.actionBarSize thay vì 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

Trong xml, bạn có thể sử dụng? Attr / actionBarSize, nhưng nếu bạn cần truy cập vào giá trị đó trong Java, bạn cần sử dụng mã bên dưới:

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

Một phương pháp sẵn sàng để thực hiện câu trả lời phổ biến nhất:

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

Đây là phiên bản cập nhật với Kotlin mà tôi đã sử dụng giả sử điện thoại cao hơn Honeycomb:

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

1

Nếu bạn đang sử dụng Xamarin / C #, đây là mã bạn đang tìm kiếm:

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

Một cách đơn giản để tìm chiều cao thanh hành động là từ onPrepareOptionMenuphương thức Activity .

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

0

Trong javafx (sử dụng Glamon), chiều cao được đặt khi chạy hoặc một cái gì đó tương tự. Trong khi có thể có được chiều rộng như bình thường ...

double width = appBar.getWidth();

Bạn phải tạo một người nghe:

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

... Và lấy giá trị gần đây nhất mà nó đổi thành. Để có được chiều cao.


0

Sau khi thử mọi thứ ngoài kia mà không thành công, tôi tình cờ phát hiện ra, một cách dễ dàng và hiệu quả để có được chiều cao mặc định của thanh hành động.

Chỉ được thử nghiệm trong API 25 và 24

C #

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

Java

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.