Как реализовать DrawerArrowToggle из Android appcompat v7 21 library
Итак, теперь, когда был выпущен Android 5.0, мне было интересно, как реализовать анимированные значки в действии.
Эта библиотека здесь реализует для меня это хорошо, но поскольку библиотека appcompat v7 имеет ее, как ее можно реализовать?
Библиотека ссылается на него в topic.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>
Но при этом происходит сбой и при ошибке указывается ошибка типа цвета. Что мне не хватает?
Ответы
Ответ 1
Сначала вы должны знать, что 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>
.
Затем можно представить анимацию.
Надеюсь, это поможет вам.
Ответ 2
Если вы используете библиотеку поддержки, предоставленную DrawerLayout, как предложено в Создание учебного курса для навигации,, вы можете использовать добавленный android.support. v7.app.ActionBarDrawerToggle (примечание: отличается от устаревших android.support v4.app.ActionBarDrawerToggle).
показывает значок гамбургера, когда ящик закрыт, и стрелка, когда выдвижной ящик открыт. Он оживляет между этими двумя состояниями при открытии ящика.
В то время как обучение не обновлялось, чтобы учитывать устаревший/новый класс, вы должны использовать его почти точно в том же коде - единственная разница в его реализации - это конструктор.
Ответ 3
Я создал небольшое приложение, имеющее аналогичную функциональность
MainActivity
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>
Ответ 4
Чтобы ответить на обновленную часть вашего вопроса: чтобы стилизовать значок ящика/стрелку, у вас есть два варианта:
Стиль самой стрелки
Чтобы сделать это, переопределите 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 должен иметь последовательный стиль со стрелкой, поэтому, скорее всего, вам нужна опция two:
Тема 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">
- это разрешит либо AppCompat по умолчанию ThemeOverlay.AppCompat.ActionBar
, либо ваш переопределить, если вы установите атрибут в своей производной теме.
PS немного комментариев об переопределении drawerArrowStyle
и атрибуте spinBars
, которые, как полагают многие источники, должны быть установлены на true
, чтобы получить анимацию ящика/стрелки. Thing is, spinBars
по умолчанию true
в AppCompat (проверьте стиль Base.Widget.AppCompat.DrawerArrowToggle.Common
), вам не нужно переопределять actionBarTheme
вообще, чтобы заставить анимацию работать. Вы получаете анимацию, даже если вы ее переопределите и установите атрибут false
, это просто другая, менее крутая анимация. Важно здесь использовать ActionBarDrawerToggle
, это то, что тянет в воображаемую анимацию.
Ответ 5
Я хочу немного исправить код выше
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"
в корневую компоновку содержимого ящика