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