Cách triển khai DrawerArrowToggle từ thư viện appcompat v7 21 của Android


97

Vì vậy, bây giờ Android 5.0 đã được phát hành, tôi đã tự hỏi làm thế nào để triển khai các biểu tượng thanh hành động hoạt hình.

Thư viện này ở đây thực hiện nó tốt cho tôi nhưng vì thư viện appcompat v7 có nó, làm thế nào nó có thể được triển khai?

Thư viện tham chiếu nó trong themes.xml

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

Theo phong cách này

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

CẬP NHẬT

Tôi đã thực hiện điều này bằng cách sử dụng DrawerToggle v7. Tuy nhiên tôi không thể tạo kiểu cho nó. Xin vui lòng giúp đỡ

Tôi đã tìm thấy kiểu dáng cho nó trong 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>

Tôi đã thêm điều này vào phong cách của mình và không hoạt động. Cũng được thêm vào attr.xml của tôi

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

Nhưng bị treo và báo lỗi loại màu khi làm như vậy. Tôi đang thiếu cái gì?

Câu trả lời:


243

Đầu tiên, bạn nên biết bây giờ android.support.v4.app.ActionBarDrawerTogglekhông dùng nữa.

Bạn phải thay thế bằng android.support.v7.app.ActionBarDrawerToggle.

Đây là ví dụ của tôi và tôi sử dụng cái mới Toolbarđể thay thế 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>

Bạn có thể đọc tài liệu trên AndroidDocument # DrawerArrowToggle_spinBars

Thuộc tính này là chìa khóa để triển khai hoạt ảnh từ menu sang mũi tên.

public static int DrawerArrowToggle_spinBars Các

thanh có nên xoay hay không trong quá trình chuyển đổi
Phải là giá trị boolean, "true" hoặc "false".

Vì vậy, bạn thiết lập này: <item name="spinBars">true</item>.

Sau đó, hình ảnh động có thể được trình bày.

Hy vọng điều này có thể giúp bạn.


12
Tôi đã gặp sự cố khi hiển thị biểu tượng bánh hamburger. gọi đã mDrawerToggle.syncState();sửa nó.
aheuermann

1
đối với tôi getSupportActionBar () trả về null .. lý do có thể là gì?
Ramesh_D

2
Android Studio nói Cannot resolve method setSupportActionBar(android.widget.Toolbar). Tôi cũng đã thử với android.support.v7.toolbar. Có ai biết tại sao điều này xảy ra?
pez

1
Tôi đã sử dụng setSupportActionBar(mToolbar);và cũng đã xác định <item name="spinBars">true</item>nhưng hoạt ảnh không hoạt động
SweetWisher ツ

2
Nên sử dụng ActionBarDrawerToggle (Activity, DrawerLayout, int, int) nếu bạn đang đặt Thanh công cụ làm ActionBar cho hoạt động của mình.
Peter Zhao

24

Nếu bạn đang sử dụng Thư viện hỗ trợ được cung cấp DrawerLayout như được đề xuất trong khóa đào tạo Tạo ngăn điều hướng , bạn có thể sử dụng android.support mới được thêm vào . v7 .app.ActionBarDrawerToggle (lưu ý: khác với android.support hiện không dùng nữa . v4 .app.ActionBarDrawerToggle ):

hiển thị biểu tượng Hamburger khi ngăn kéo được đóng và một mũi tên khi ngăn kéo đang mở. Nó hoạt động giữa hai trạng thái này khi ngăn kéo mở ra.

Trong khi khóa đào tạo chưa được cập nhật để tính đến lớp không dùng nữa / lớp mới, bạn sẽ có thể sử dụng nó gần như chính xác cùng một mã - điểm khác biệt duy nhất trong việc triển khai nó là hàm tạo.


Tôi đang sử dụng v4 trong ứng dụng của mình bc tôi không cần phải hỗ trợ các thiết bị trước api 15. Vì vậy, nếu tôi muốn điều này hoạt động, tôi sẽ phải sử dụng chuyển đổi ngăn kéo thanh tác vụ v7? Nếu tôi làm điều đó, tôi sẽ không phải chuyển đổi tất cả các kiểu của mình sang AppCompat và phân mảnh các hoạt động thành các hoạt động trên thanh hành động, v.v.? Hoặc tôi có thể thực hiện chỉ chuyển đổi Ngăn kéo từ v7. Ngay bây giờ tôi sử dụng v7 để xem thẻ. Tôi thậm chí có nên sử dụng v4 nếu tôi không hỗ trợ api dưới 15? Và tôi đoán tôi cần v7 cho lượt xem thẻ.
Bignadad

Tất cả khả năng tương thích của Thư viện hỗ trợ cho thiết kế Material design đều được triển khai trong v7-appcompat và được khuyến nghị nếu bạn muốn hỗ trợ kiểu đó trên các thiết bị <5.0. AppCompat được xây dựng dựa trên và yêu cầu phiên bản 4, vì vậy bạn có muốn sử dụng AppCompat hay không. Nếu bạn đã sử dụng FragmentActivity, thì bạn đã khá gần rồi - sự khác biệt về kiểu dáng bây giờ là khá nhỏ (chủ yếu chỉ là thay thế các thuộc tính android: bằng các thuộc tính không có vùng chứa tên).
ianhanniballake

Đã cập nhật câu hỏi nếu bạn không phiền hãy xem
Bignadad

Đó thực sự là một câu hỏi hoàn toàn riêng biệt về kiểu dáng. Tôi khuyên bạn nên gửi phần đó dưới dạng toàn bộ câu hỏi khác (vui lòng thêm nhận xét với liên kết đến phần đó).
ianhanniballake

1
@mraviator - yep: thay đổi XML, sau đó tạo và đính kèm v7 ActionBarDrawerToggle. Các câu trả lời kinh điển từ nhà sản xuất của AppCompat có một ví dụ đầy đủ như thế nào XML của bạn nên được cấu trúc.
ianhanniballake

17

Tôi đã tạo một ứng dụng nhỏ có chức năng tương tự

Hoạt động chủ yêu

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 của tôi về Hoạt động đó

<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 của Thanh công cụ Tùy chỉnh của tôi

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

Phong cách chủ đề của tôi

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

Kiểu của tôi trong giá trị-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>

1
Điều này hoạt động hoàn hảo nhưng tôi không muốn sử dụng Title, vậy làm cách nào để xử lý việc này? Bởi vì nếu tôi sử dụng Theme.AppCompat.Light.NoActionBar , nó chắc chắn sẽ cho tôi NULL tại getSupportActionBar
SweetWisher ツ

Tôi đã sử dụng mã trên. Tôi có Ngoại lệ: Hoạt động này đã có một thanh tác vụ được cung cấp bởi trang trí cửa sổ trong dòng setsupportactionbar (thanh công cụ). Tôi đã sử dụng getSupportActionBar (). Hide (); Trước setContentView (R.layout.activity_main); Bây giờ nó đang hoạt động.
Thirumalvalavan

setSupportActionBar (thanh công cụ); cũng đã nhận xét.
Thirumalvalavan

9

Để trả lời phần cập nhật của câu hỏi của bạn: để tạo kiểu cho biểu tượng / mũi tên ngăn kéo, bạn có hai tùy chọn:

Tạo kiểu cho chính mũi tên

Để làm điều này, hãy ghi đè drawerArrowStylechủ đề của bạn như sau:

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

Đây có thể không phải là những gì bạn muốn , vì bản thân ActionBar phải có kiểu dáng nhất quán với mũi tên, vì vậy, hầu hết có thể, bạn muốn tùy chọn hai:

Tạo chủ đề cho ActionBar / Thanh công cụ

Ghi đè thuộc tính android:actionBarTheme( actionBarThemefor appcompat) của chủ đề ứng dụng toàn cầu bằng chủ đề của riêng bạn (mà bạn có thể nên lấy từ đó ThemeOverlay.Material.ActionBar/ThemeOverlay.AppCompat.ActionBar) như sau:

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

Một lưu ý quan trọng ở đây là khi sử dụng một cách bố trí tùy chỉnh với một Toolbarthay vì chứng khoán ActionBar thực hiện (ví dụ: nếu bạn đang sử dụng DrawerLayout- NavigationView- Toolbarcombo để đạt được hiệu quả Vật liệu kiểu ngăn kéo nơi nó có thể nhìn thấy dưới mờ statusbar), các actionBarThemethuộc tính là obviosly không được chọn tự động (vì nó có nghĩa là được chăm sóc bởi AppCompatActivitymặc định ActionBar), vì vậy đối với tùy chỉnh của bạn, Toolbarđừng quên áp dụng chủ đề của bạn theo cách thủ công:

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

- điều này sẽ giải quyết thành mặc định của AppCompat ThemeOverlay.AppCompat.ActionBarhoặc ghi đè của bạn nếu bạn đặt thuộc tính trong chủ đề bắt nguồn của mình.

Tái bút một chút nhận xét về drawerArrowStyleghi đè và spinBarsthuộc tính - mà nhiều nguồn gợi ý nên được đặt thành trueđể có được hoạt ảnh ngăn kéo / mũi tên. Có điều là, spinBarsnó là true theo mặc định trong AppCompat (xem phần Base.Widget.AppCompat.DrawerArrowToggle.Commonphong cách), bạn không cần phải ghi đè lên actionBarThemeở tất cả để có được những lao động hoạt hình. Bạn nhận được hoạt ảnh ngay cả khi bạn ghi đè nó và đặt thuộc tính thành false, nó chỉ là một hoạt ảnh khác, ít xoay vòng hơn. Điều quan trọng ở đây là sử dụng ActionBarDrawerToggle, đó là những gì kéo hoạt hình lạ mắt có thể vẽ được.


2

Tôi muốn sửa một chút đoạn mã trên

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

và tất cả những thứ khác sẽ vẫn như cũ ...

Đối với những người đang gặp sự cố Drawerlayoutthanh công cụ lớp phủ

thêm android:layout_marginTop="?attr/actionBarSize"vào bố cục gốc của nội dung ngăn kéo


làm thế nào bạn sử dụng getSupportActionBar()khi bạn chỉ cần mở rộng Activity?
wzieba

chỉ đơn giản là bạn có thể không, bạn phải mở rộng từActionBarActivity
Nitin Misra
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.