Как реализовать DrawerArrowToggle из библиотеки Android appcompat v7 21

Так что теперь, когда вышла Android 5.0, мне стало интересно, как реализовать анимированные иконки панели действий.

Эта библиотека здесь реализует это хорошо для меня, но так как библиотека appcompat v7 имеет это, как это может быть реализовано?

Библиотека ссылается на это в themes.xml

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

Под этот стиль

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

ОБНОВИТЬ

Я получил это реализовано с помощью v7 DrawerToggle. Однако я не могу это стилизовать. Пожалуйста помоги

Я нашел стиль для него в 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>

Я добавил это к своим стилям и не работал. Также добавлен в мой attr.xml

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

Но вылетает и говорит об ошибке типа цвета при этом. Что мне не хватает?

5 ответов

Решение

Во-первых, вы должны знать сейчас android.support.v4.app.ActionBarDrawerToggle устарела.

Вы должны заменить это на android.support.v7.app.ActionBarDrawerToggle,

Вот мой пример, и я использую новый Toolbar заменить 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>

Вы можете прочитать документы на AndroidDocument#DrawerArrowToggle_spinBars

Этот атрибут является ключом для реализации анимации меню-стрелка.

public static int DrawerArrowToggle_spinBars

Должны ли бары вращаться или нет во время перехода
Должно быть логическим значением, "истина" или "ложь".

Итак, вы установите это: <item name="spinBars">true</item>,

Затем анимация может быть представлена.

Надеюсь, это поможет вам.

Если вы используете библиотеку поддержки, предоставляемую DrawerLayout в соответствии с рекомендациями, приведенными в разделе " Создание ящика навигации", вы можете использовать только что добавленный android.support. v7.app.ActionBarDrawerToggle (примечание: отличается от ныне устаревшего android.support. v4.app.ActionBarDrawerToggle):

показывает значок гамбургера, когда ящик закрыт, и стрелку, когда ящик открыт. Он оживляет между этими двумя состояниями, как ящик открывается.

Хотя обучение не было обновлено для учета устаревшего / нового класса, вы должны иметь возможность использовать его практически в том же коде - единственное отличие в его реализации - это конструктор.

Я создал небольшое приложение с похожей функциональностью

Основная деятельность

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 этой активности

<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

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

Мой стиль темы

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

Мои стили в значениях-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>

Чтобы ответить на обновленную часть вашего вопроса: для стилизации значка / стрелки ящика у вас есть два варианта:

Стиль самой стрелки

Для этого переопределить drawerArrowStyle в твоей теме вот так:

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

Вероятно, это не то, что вам нужно, потому что сам ActionBar должен иметь согласованный стиль со стрелкой, поэтому, скорее всего, вам нужен второй вариант:

Тема ActionBar / Панель инструментов

Переопределить android:actionBarTheme (actionBarTheme для appcompat) атрибут глобальной темы приложения с вашей собственной темой (которую вы, вероятно, должны извлечь из ThemeOverlay.Material.ActionBar/ThemeOverlay.AppCompat.ActionBar) вот так:

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

Важным примечанием здесь является то, что при использовании пользовательского макета с Toolbar вместо стандартной реализации ActionBar (например, если вы используете DrawerLayout-NavigationView-Toolbar комбо для достижения эффекта ящика в стиле материала, когда он виден под полупрозрачной строкой состояния), actionBarTheme атрибут, очевидно, не выбирается автоматически (потому что он должен быть AppCompatActivity по умолчанию ActionBar), так что для вашего обычая Toolbar не забудьте применить свою тему вручную:

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

- это разрешит любой AppCompat по умолчанию ThemeOverlay.AppCompat.ActionBar или переопределение, если вы установите атрибут в вашей производной теме.

PS небольшой комментарий о drawerArrowStyle переопределить и spinBars атрибут - который многие источники предлагают установить true чтобы получить анимацию ящика / стрелки. Дело в том, spinBars это true по умолчанию в AppCompat (проверить Base.Widget.AppCompat.DrawerArrowToggle.Common стиль), вам не нужно переопределять actionBarTheme чтобы анимация работала. Вы получаете анимацию, даже если переопределите ее и установите для атрибута значение falseЭто просто другая, менее крутая анимация. Здесь важно использовать ActionBarDrawerToggleЭто то, что тянет в модных анимационных рисунках.

Я хочу немного исправить вышеприведенный код

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

и все остальное останется таким же...

Для тех, у кого проблемы Drawerlayout наложенная панель инструментов

добавлять android:layout_marginTop="?attr/actionBarSize" в корневой макет содержимого ящика

Другие вопросы по тегам