it-swarm.com.ru

Как реализовать 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>

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

96
Bignadad

Во-первых, вы должны знать, что 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

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

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

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

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

242
Yong

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

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

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

24
ianhanniballake

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

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

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

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

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

Для этого переопределите 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 для достижения эффекта ящика в стиле Material, где он виден под полупрозрачной строкой состояния), Атрибут actionBarTheme, очевидно, не подбирается автоматически (потому что он должен быть обработан AppCompatActivity для ActionBar по умолчанию), поэтому для своего пользовательского Toolbar не забудьте применить свою тему вручную:

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

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

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

9
Ivan Bartsov

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

    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" в корневой макет содержимого ящика

2
Nitin Misra