Cara mengimplementasikan DrawerArrowToggle dari pustaka Android appcompat v7 21

97

Jadi sekarang Android 5.0 dirilis saya bertanya-tanya bagaimana menerapkan ikon actionbar animasi.

Pustaka ini di sini mengimplementasikannya dengan baik bagi saya, tetapi karena pustaka appcompat v7 memilikinya, bagaimana cara mengimplementasikannya?

Pustaka mereferensikannya di themes.xml

 <item name="drawerArrowStyle">@style/Widget.AppCompat.DrawerArrowToggle</item>

Di bawah gaya ini

 <style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat">

MEMPERBARUI

Saya menerapkan ini menggunakan v7 DrawerToggle. Namun saya tidak bisa menatanya. Tolong bantu

Saya menemukan gaya untuk itu di v7 styles_base.xml

<style name="Base.Widget.AppCompat.DrawerArrowToggle" parent="">
    <item name="color">?android:attr/textColorSecondary</item>
    <item name="thickness">2dp</item>
    <item name="barSize">18dp</item>
    <item name="gapBetweenBars">3dp</item>
    <item name="topBottomBarArrowSize">11.31dp</item>
    <item name="middleBarArrowSize">16dp</item>
    <item name="drawableSize">24dp</item>
    <item name="spinBars">true</item>
</style>

Saya menambahkan ini ke gaya saya dan tidak berhasil. Juga ditambahkan ke attr.xml saya

<declare-styleable name="DrawerArrowToggle">
    <!-- The drawing color for the bars -->
    <attr name="color" format="color"/>
    <!-- Whether bars should rotate or not during transition -->
    <attr name="spinBars" format="boolean"/>
    <!-- The total size of the drawable -->
    <attr name="drawableSize" format="dimension"/>
    <!-- The max gap between the bars when they are parallel to each other -->
    <attr name="gapBetweenBars" format="dimension"/>
    <!-- The size of the top and bottom bars when they merge to the middle bar to form an arrow -->
    <attr name="topBottomBarArrowSize" format="dimension"/>
    <!-- The size of the middle bar when top and bottom bars merge into middle bar to form an arrow -->
    <attr name="middleBarArrowSize" format="dimension"/>
    <!-- The size of the bars when they are parallel to each other -->
    <attr name="barSize" format="dimension"/>
    <!-- The thickness (stroke size) for the bar paint -->
    <attr name="thickness" format="dimension"/>
</declare-styleable>

Tetapi macet dan mengatakan kesalahan jenis warna saat melakukannya. Apa yang saya lewatkan?

Bignadad
sumber

Jawaban:

243

Pertama, Anda harus tahu sekarang bahwa android.support.v4.app.ActionBarDrawerToggleini sudah usang.

Anda harus menggantinya dengan android.support.v7.app.ActionBarDrawerToggle.

Berikut adalah contoh saya dan saya menggunakan yang baru Toolbaruntuk menggantikan ActionBar.

MainActivity.java

public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);
    DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
        this,  mDrawerLayout, mToolbar,
        R.string.navigation_drawer_open, R.string.navigation_drawer_close
    );
    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);
    mDrawerToggle.syncState();
}

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@android:color/white</item>
</style>

Anda dapat membaca dokumen di AndroidDocument # DrawerArrowToggle_spinBars

Atribut ini adalah kunci untuk mengimplementasikan animasi menu-ke-panah.

public static int DrawerArrowToggle_spinBars

Apakah bar harus berputar atau tidak selama transisi
Harus berupa nilai boolean, baik "true" atau "false".

Jadi, Anda mengatur ini: <item name="spinBars">true</item>.

Kemudian animasi dapat disajikan.

Semoga ini bisa membantu Anda.

Yong
sumber
12
Saya mengalami masalah saat menampilkan ikon hamburger. menelepon mDrawerToggle.syncState();memperbaikinya.
aheuermann
1
bagi saya getSupportActionBar () mengembalikan null .. apa alasannya?
Ramesh_D
2
Kata Android Studio Cannot resolve method setSupportActionBar(android.widget.Toolbar). Saya juga sudah mencoba dengan android.support.v7.toolbar. Apakah ada yang tahu mengapa hal ini terjadi?
pez
1
Saya menggunakan setSupportActionBar(mToolbar);dan juga mendefinisikan <item name="spinBars">true</item>tetapi animasi tidak berfungsi
SweetWisher ツ
2
Harus menggunakan ActionBarDrawerToggle (Activity, DrawerLayout, int, int) jika Anda menyetel Toolbar sebagai ActionBar aktivitas Anda.
Peter Zhao
24

Jika Anda menggunakan Library Dukungan yang disediakan DrawerLayout seperti yang disarankan dalam pelatihan Membuat panel navigasi , Anda bisa menggunakan android.support yang baru ditambahkan . v7 .app.ActionBarDrawerToggle (catatan: berbeda dari android.support. v4 .app.ActionBarDrawerToggle yang sekarang tidak digunakan lagi ):

menunjukkan ikon Hamburger saat laci ditutup dan panah saat laci terbuka. Ini menjiwai antara dua keadaan ini saat laci terbuka.

Meskipun pelatihan belum diperbarui untuk memperhitungkan deprecation / new class, Anda harus dapat menggunakannya dengan kode yang hampir persis sama - satu-satunya perbedaan dalam mengimplementasikannya adalah konstruktornya.

ianhanniballake
sumber
Saya menggunakan v4 di aplikasi saya bc saya tidak perlu mendukung perangkat sebelum api 15. Jadi jika saya ingin ini berfungsi, saya harus menggunakan toggle laci actionbar v7? Jika saya melakukannya, bukankah saya harus mengonversi semua gaya saya ke AppCompat dan aktivitas fragmen ke aktivitas bilah tindakan dan seterusnya? Atau dapatkah saya menerapkan hanya sakelar Drawer dari v7. Sekarang saya menggunakan v7 untuk tampilan kartu. Haruskah saya menggunakan v4 jika saya tidak mendukung api di bawah 15? Dan saya rasa saya perlu v7 untuk tampilan kartu.
Bignadad
Semua kompatibilitas Library Dukungan untuk desain Material diimplementasikan di v7-appcompat dan direkomendasikan jika Anda ingin mendukung gaya tersebut pada perangkat <5.0. AppCompat dibuat dan membutuhkan v4 sehingga benar-benar terserah apakah Anda ingin menggunakan AppCompat sama sekali. Jika Anda sudah menggunakan FragmentActivity, Anda sudah cukup dekat - perbedaan gaya cukup kecil sekarang (kebanyakan hanya mengganti atribut android: dengan atribut non-namespace).
ianhanniballake
Memperbarui pertanyaan jika Anda tidak keberatan untuk melihatnya
Bignadad
Itu benar-benar pertanyaan terpisah tentang gaya. Saya sarankan untuk mengirimkan bagian itu sebagai pertanyaan lain (jangan ragu untuk menambahkan komentar dengan link ke sana).
ianhanniballake
1
@mraviator - yep: ubah XML, lalu buat dan pasang v7 ActionBarDrawerToggle. The jawaban kanonik dari pembuat appcompat memiliki contoh lengkap bagaimana XML Anda harus terstruktur.
ianhanniballake
17

Saya membuat aplikasi kecil yang memiliki fungsi serupa

Aktifitas utama

public class MyActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(
                this,
                drawerLayout,
                toolbar,
                R.string.open,
                R.string.close
        )

        {
            public void onDrawerClosed(View view)
            {
                super.onDrawerClosed(view);
                invalidateOptionsMenu();
                syncState();
            }

            public void onDrawerOpened(View drawerView)
            {
                super.onDrawerOpened(drawerView);
                invalidateOptionsMenu();
                syncState();
            }
        };
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        //Set the custom toolbar
        if (toolbar != null){
            setSupportActionBar(toolbar);
        }

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        actionBarDrawerToggle.syncState();
    }
}

XML saya tentang Aktivitas itu

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity"
    android:id="@+id/drawer"
    >

    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <include layout="@layout/toolbar_custom"/>
    </FrameLayout>
    <!-- The navigation drawer -->
    <ListView
        android:layout_marginTop="?attr/actionBarSize"
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#457C50"/>


</android.support.v4.widget.DrawerLayout>

XML Toolbar Kustom saya

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/toolbar"
    android:background="?attr/colorPrimaryDark">
    <TextView android:text="U titel"
        android:textAppearance="@android:style/TextAppearance.Theme"
        android:textColor="@android:color/white"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</android.support.v7.widget.Toolbar>

Gaya Tema Saya

<resources>
    <style name="AppTheme" parent="Base.Theme.AppCompat"/>

    <style name="AppTheme.Base" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDarker</item>
        <item name="android:windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    </style>

    <style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
        <item name="spinBars">true</item>
        <item name="color">@android:color/white</item>
    </style>

    <color name="primary">#457C50</color>
    <color name="primaryDarker">#580C0C</color>
</resources>

Gaya saya di values-v21

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
    </style>
</resources>
tim
sumber
1
Ini berfungsi sempurna tetapi saya tidak ingin menggunakan Judul jadi bagaimana saya bisa menangani ini? Karena jika saya menggunakan Theme.AppCompat.Light.NoActionBar , itu pasti akan memberi saya NULL di getSupportActionBar
SweetWisher ツ
Saya menggunakan kode di atas. Saya mendapat Pengecualian: Aktivitas ini sudah memiliki bilah tindakan yang disediakan oleh dekorasi jendela di baris set supportactionbar (toolbar). Saya menggunakan getSupportActionBar (). Hide (); Sebelum setContentView (R.layout.activity_main); Sekarang ini berhasil.
Thirumalvalavan
setSupportActionBar (toolbar); juga berkomentar.
Thirumalvalavan
9

Untuk menjawab bagian terbaru dari pertanyaan Anda: untuk mengatur gaya ikon / panah laci, Anda memiliki dua opsi:

Style pada panah itu sendiri

Untuk melakukan ini, ganti drawerArrowStyletema Anda seperti ini:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    <item name="drawerArrowStyle">@style/MyTheme.DrawerArrowToggle</item>
</style>
<style name="MyTheme.DrawerArrowToggle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="color">@android:color/holo_purple</item>
    <!-- ^ this will make the icon purple -->
</style>

Ini mungkin bukan yang Anda inginkan , karena ActionBar itu sendiri harus memiliki gaya yang konsisten dengan panah, jadi, kemungkinan besar, Anda menginginkan opsi dua:

Buat tema ActionBar / Toolbar

Ganti atribut android:actionBarTheme( actionBarThemeuntuk appcompat) dari tema aplikasi global dengan tema Anda sendiri (yang mungkin harus Anda peroleh ThemeOverlay.Material.ActionBar/ThemeOverlay.AppCompat.ActionBar) seperti ini:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    <item name="actionBarTheme">@style/MyTheme.ActionBar</item>
</style>
<style name="MyTheme.ActionBar" parent="ThemeOverlay.AppCompat.ActionBar">
    <item name="android:textColorPrimary">@android:color/white</item>
    <!-- ^ this will make text and arrow white -->
    <!-- you can also override drawerArrowStyle here -->
</style>

Catatan penting di sini adalah bahwa saat menggunakan tata letak khusus dengan Toolbaralih - alih penerapan ActionBar stok (misalnya jika Anda menggunakan DrawerLayout- NavigationView- Toolbarcombo untuk mencapai efek laci bergaya Material yang terlihat di bawah statusbar tembus), actionBarThemeatributnya jelas tidak diambil secara otomatis (karena itu dimaksudkan untuk diurus oleh AppCompatActivitydefault ActionBar), jadi untuk kebiasaan Anda Toolbarjangan lupa untuk menerapkan tema Anda secara manual:

<!--inside your custom layout with DrawerLayout
and NavigationView or whatever -->
<android.support.v7.widget.Toolbar
        ...
        app:theme="?actionBarTheme">

- ini akan menyelesaikan baik default AppCompat ThemeOverlay.AppCompat.ActionBaratau penggantian Anda jika Anda menyetel atribut dalam tema turunan Anda.

PS sedikit komentar tentang drawerArrowStyleoverride dan spinBarsatribut - yang disarankan oleh banyak sumber harus diatur trueuntuk mendapatkan animasi laci / panah. Masalahnya, spinBarsini true secara default di AppCompat (lihat Base.Widget.AppCompat.DrawerArrowToggle.Commongayanya), Anda tidak perlu menimpa actionBarThemesama sekali agar animasi berfungsi. Anda mendapatkan animasi bahkan jika Anda menimpanya dan menyetel atributnya ke false, itu hanya animasi yang berbeda, kurang berputar-putar. Hal yang penting di sini adalah menggunakannya ActionBarDrawerToggle, itulah yang menarik drawable animasi yang mewah.

Ivan Bartsov
sumber
2

Saya ingin mengoreksi sedikit kode di atas

    public class MainActivity extends ActionBarActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
            this,  mDrawerLayout, mToolbar,
            R.string.navigation_drawer_open, R.string.navigation_drawer_close
        );
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
    }

dan semua hal lainnya akan tetap sama ...

Bagi mereka yang mengalami masalah Drawerlayout overlay toolbar

tambahkan android:layout_marginTop="?attr/actionBarSize"ke tata letak root konten laci

Nitin Misra
sumber
bagaimana Anda menggunakan getSupportActionBar()saat Anda hanya memperpanjang Activity?
wzieba
Anda tidak bisa, Anda harus memperpanjang dari ActionBarActivity
Nitin Misra