Bagaimana cara mendapatkan tinggi ActionBar?

190

Saya mencoba untuk mendapatkan ketinggian ActionBar(menggunakan Sherlock) setiap kali aktivitas dibuat (khusus untuk menangani perubahan konfigurasi pada rotasi di mana ketinggian ActionBar mungkin berubah).

Untuk ini saya menggunakan metode ActionBar.getHeight()yang hanya berfungsi ketika ActionBarditampilkan.

Ketika aktivitas pertama kali dibuat untuk pertama kalinya, saya dapat menelepon getHeight()kembali onCreateOptionsMenu. Tetapi metode ini tidak dipanggil setelah.

Jadi pertanyaan saya adalah kapan saya bisa memanggil getHeight () dan yakin bahwa itu tidak mengembalikan 0? Atau jika tidak memungkinkan, bagaimana saya bisa mengatur ketinggian ActionBar?

znat
sumber

Jawaban:

419

Sementara jawaban @ birdy adalah opsi jika Anda ingin secara eksplisit mengontrol ukuran ActionBar, ada cara untuk menariknya tanpa mengunci ukuran yang saya temukan di dokumentasi dukungan. Agak canggung tapi berhasil bagi saya. Anda akan memerlukan konteks, contoh ini akan valid dalam suatu Aktivitas.

// 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)
}
Anthony
sumber
13
sangat membantu !! tetapi dari tempat Anda menemukan semua hal seperti itu !!
vikky
5
Umumnya dari Googling lengkap atau membanting tulang melalui buku pegangan pengembang. Saya pikir yang terakhir dalam kasus ini, tapi sudah lama.
Anthony
1
Bisakah kita mengubah ukuran bilah tindakan hanya untuk aktivitas tertentu?
Sudarshan Bhat
Ini bekerja untuk saya dalam kedua kasus: (i) onCreateView dan (ii) onConfigurationChanged. Terima kasih!
Marcelo Noguti
5
"android.R.attr.actionBarSize" tidak berfungsi di android versi 2.3, tetapi "R.attr.actionBarSize" bekerja android semua versi. cukup gunakan "R.attr.actionBarSize" alih-alih "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" dan lain
Nathaniel Jobs
148

Dalam XML, Anda harus menggunakan atribut ini:

android:paddingTop="?android:attr/actionBarSize"
cesards
sumber
20
jika Anda menggunakan ActionBarCompat "@ dimen / abc_action_bar_default_height"
Ali AlNoaimi
10
Terima kasih Ali AlNoaimi! Dengan AppCompat v21, namanya telah berubah menjadi: "@ dimen / abc_action_bar_default_height_material"
Tony Ceralva
5
Seperti @muzikant disebutkan di bawah ini, untuk appcompat, jika Anda ingin menggunakannya dalam kode, atribut yang benar adalah android.support.v7.appcompat.R.attr.actionBarSize. Jika Anda ingin menggunakannya di tata letak xml android:paddingTop="?attr/actionBarSize",. Bekerja dengan baik di mana-mana.
rpattabi
1
Solusi ini luar biasa ketika Anda menggunakan framelayout XML kustom.
tryp
2
Jika saya ingin menggunakan attr ini tetapi negatif untuk menggunakannya dengan padding negatif. Bagaimana saya bisa melakukan itu?
Pengembang harimau
17

Ok saya sudah googling dan mendapatkan ke posting ini beberapa kali jadi saya pikir itu akan baik untuk dijelaskan tidak hanya untuk Sherlock tetapi untuk appcompat juga:

Tinggi Action Bar menggunakan appCompat

Mirip dengan deskripsi @Anthony, Anda dapat menemukannya dengan kode berikut (Saya baru saja mengubah id sumber daya):

TypedValue tv = new TypedValue();

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

Pre Sandwitch Problem

Saya membutuhkan ketinggian bilah tindakan karena pada perangkat ICE_CREAM_SANDWITCH pra, pandangan saya tumpang tindih dengan bilah tindakan. Saya mencoba mengatur android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize", pengaturan tumpang tindih untuk melihat / actionbar dan bahkan memperbaiki tinggi actionbar dengan tema khusus tetapi tidak ada yang berhasil. Seperti itulah tampilannya:

masalah tumpang tindih

Sayangnya saya menemukan bahwa dengan metode yang dijelaskan di atas saya hanya mendapatkan setengah dari tinggi (saya berasumsi bahwa bar opsi tidak diambil di tempat) sehingga untuk benar-benar memperbaiki isue saya perlu menggandakan aksi bar tinggi dan semuanya tampak ok:

tumpang tindih diperbaiki

Jika seseorang tahu solusi yang lebih baik (daripada menggandakan actionBarHeight) Saya akan senang memberi tahu saya karena saya berasal dari pengembangan iOS dan saya menemukan sebagian besar hal tampilan Android cukup membingungkan :)

Salam,

hris.to

hris.to
sumber
Saya mengalami hal yang sama ketika menggunakan tab. Masalahnya adalah terkadang sulit untuk mendeteksi tab vs tanpa tab, karena beberapa perangkat secara visual menciutkan tab ke dalam ActionBar dasar dalam beberapa situasi. Jadi apa yang berhasil untuk saya adalah adil ActionBar.getHeight(). Bergantung pada situasinya, itu mungkin cocok untuk Anda juga.
TalkLittle
Saya menghadapi masalah karena saya hanya mempertimbangkan ketinggian actionbar, lalu saya menambahkan tinggi 'bilah pemberitahuan' juga. Itu bekerja dengan baik untuk saya.
Darpan
Apakah Anda menggunakan FrameLayout dan miliki layout_gravity="center_vertical"? Ubah ke "bottom". Android 2.3 menangani margin di FrameLaoyut secara berbeda dari Android yang lebih baru.
Oliv
16

@Anthony answer berfungsi untuk perangkat yang mendukung ActionBardan untuk perangkat yang hanya mendukung Sherlock Action Barmetode berikut ini harus digunakan

    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());
   }
laaptu
sumber
Anda dapat membungkus yang pertama jika dengan "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" untuk menghindari kesalahan runtime pada versi Android yang lebih lama.
Marina.Eariel
Bagi saya com.actionbarsherlock.R.attr.actionBarSizebekerja untuk Android 2.3 dan 4.0, jadi sepertinya Anda dapat menggunakan ini terlepas dari versi Android.
Felix
13

Saya pikir cara teraman adalah:

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;
}
pengembang android
sumber
9
jika Anda menggunakan appcompat, tambahkan yang berikut: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 =="? Saya pikir Anda dapat menghapus "true" ... :)
pengembang android
Ya, Anda benar ... itu baru ditambahkan untuk kejelasan
Muzikant
Dari kode Anda sepertinya tidak masalah jika saya menggunakan ABS, di semua versi di atas HONEYCOMB akan mengambil tinggi actionbar dari android.R.attr.actionBarSize. Apakah ini benar ?
AsafK
apakah itu untuk menentukan bar setengah tindakan untuk menyembunyikan bagian atas layar? stackoverflow.com/questions/27163374/…
Steve
6

Untuk mengatur ketinggian ActionBarAnda dapat membuat yang baru Themeseperti ini:

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

dan atur ini Themeuntuk Anda Activity:

android:theme="@style/Theme.FixedSize"
birdy
sumber
1
Perhatikan bahwa ketinggian bilah tindakan lebih kecil dalam mode lansekap.
Mark Buikema
Saya tidak merekomendasikan ini karena actionBarSherlock mempertimbangkan banyak hal ketika menentukan tinggi actionbar. Jika Anda melakukan ini, ketinggian actionBar tidak akan didasarkan pada spesifikasi perangkat dan karenanya tidak akan terlihat seperti ketinggian standar untuk perangkat tertentu.
Chris Sprague
5

Jawa:

    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
TeeTracker
sumber
5

Jika Anda menggunakan Bilah Alat sebagai ActionBar,

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

kemudian gunakan saja layout_height pada bilah alat.

int actionBarHeight = toolbar.getLayoutParams().height;
jk7
sumber
3

Anda dapat menggunakan fungsi ini untuk mendapatkan ketinggian 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;
}
Wangzhengyi
sumber
2

Metode penolong ini harus berguna bagi seseorang. Contoh: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();
        }
    }
}
Simon
sumber
2

Anda hanya perlu menambahkan ini.

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;
    }
JCDecary
sumber
2

Saya menemukan cara yang lebih umum untuk menemukannya:

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

di mana ' mainView ' adalah tampilan root tata letak Anda.

Idenya pada dasarnya adalah mendapatkan posisi Y dari mainView karena diatur tepat di bawah ActionBar (atau Toolbar).

Alécio Carvalho
sumber
2

Tinggi bilah tindakan berbeda sesuai dengan tema yang diterapkan. Jika Anda menggunakan AppCompatActivity ketinggian akan berbeda di sebagian besar kasus dari Aktivitas normal.

Jika Anda menggunakan AppCompatActivity, Anda harus menggunakan R.attr.actionBarSize alih-alih 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));
    }
Mahmoud
sumber
2

Di xml, Anda bisa menggunakan? Attr / actionBarSize, tetapi jika Anda membutuhkan akses ke nilai itu di Java, Anda perlu menggunakan kode di bawah ini:

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;
    }
Faxriddin Abdullayev
sumber
2

Metode yang siap untuk memenuhi jawaban paling populer:

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;
}
Zon
sumber
2

Berikut ini adalah versi yang diperbarui dengan Kotlin yang saya gunakan dengan asumsi ponsel lebih tinggi dari Honeycomb:

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

Jika Anda menggunakan Xamarin / C #, ini adalah kode yang Anda cari:

var styledAttributes = Context.Theme.ObtainStyledAttributes(new[] { Android.Resource.Attribute.ActionBarSize });
var actionBarSize = (int)styledAttributes.GetDimension(0, 0);
styledAttributes.Recycle();
Fred
sumber
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();
}
Devraj Singh
sumber
0

Cara sederhana untuk menemukan ketinggian bilah tindakan adalah dari onPrepareOptionMenumetode Aktivitas .

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

Di javafx (menggunakan Gluon), tingginya diatur pada saat runtime atau semacamnya. Sementara bisa mendapatkan lebar seperti biasa ...

double width = appBar.getWidth();

Anda harus membuat pendengar:

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

... Dan ambil nilai terakhir yang diubahnya. Untuk mendapatkan ketinggian.

Leo
sumber
0

Setelah mencoba semua yang ada di luar sana tanpa hasil, saya menemukan, secara tidak sengaja, cara yang fungsional dan sangat mudah untuk mendapatkan tinggi standar action bar.

Hanya diuji dalam API 25 dan 24

C #

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

Jawa

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
Rafael Pereira
sumber