如何从 Android appcompat v7 21 库实现 DrawerArrowToggle
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26434504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement DrawerArrowToggle from Android appcompat v7 21 library
提问by Bignadad
So now that Android 5.0 was released i was wondering how to implement the animated actionbar icons.
所以现在 Android 5.0 发布了,我想知道如何实现动画操作栏图标。
This library hereimplements it fine for me but since the appcompat v7 library has it how can it be implemented?
这里的这个库对我来说很好,但是既然 appcompat v7 库有它,它如何实现?
The library references it in themes.xml
库在 themes.xml 中引用它
<item name="drawerArrowStyle">@style/Widget.AppCompat.DrawerArrowToggle</item>
Under this style
在这种风格下
<style name="Base.V7.Theme.AppCompat" parent="Platform.AppCompat">
UPDATE
更新
I got this implemented using the v7 DrawerToggle. However I cannot style it. Please Help
我使用 v7 DrawerToggle 实现了这个。但是我不能设计它。请帮忙
I found the styling for it in the v7 styles_base.xml
我在 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>
I added this to my styles and did not work. Also added to my attr.xml
我将此添加到我的样式中,但不起作用。也添加到我的 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>
But crashes and says color type error when doing so. What am i missing?
但是这样做时会崩溃并说颜色类型错误。我错过了什么?
回答by Yong
First, you should know now the android.support.v4.app.ActionBarDrawerToggle
is deprecated.
首先,您现在应该知道 已android.support.v4.app.ActionBarDrawerToggle
弃用。
You must replace that with android.support.v7.app.ActionBarDrawerToggle
.
您必须将其替换为android.support.v7.app.ActionBarDrawerToggle
.
Here is my example and I use the new Toolbar
to replace the ActionBar
.
这是我的示例,我使用 newToolbar
替换ActionBar
.
MainActivity.java
主活动.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>
You can read the documents on AndroidDocument#DrawerArrowToggle_spinBars
您可以阅读AndroidDocument#DrawerArrowToggle_spinBars上的文档
This attribute is the key to implement the menu-to-arrow animation.
该属性是实现菜单到箭头动画的关键。
public static int DrawerArrowToggle_spinBars
Whether bars should rotate or not during transition
Must be a boolean value, either "true" or "false".
public static int DrawerArrowToggle_spinBars
条在过渡期间是否应该旋转
必须是布尔值,“true”或“false”。
So, you set this: <item name="spinBars">true</item>
.
所以,你设置这样的:<item name="spinBars">true</item>
。
Then the animation can be presented.
然后可以呈现动画。
Hope this can help you.
希望这可以帮到你。
回答by ianhanniballake
If you are using the Support Library provided DrawerLayoutas suggested in the Creating a navigation drawer training, you can use the newly added android.support.v7.app.ActionBarDrawerToggle(note: different from the now deprecated android.support.v4.app.ActionBarDrawerToggle):
如果您按照创建导航抽屉培训中的建议使用支持库提供的DrawerLayout,则可以使用新添加的android.support。V7.app.ActionBarDrawerToggle(注:从现在反对的不同。android.support V4.app.ActionBarDrawerToggle):
shows a Hamburger icon when drawer is closed and an arrow when drawer is open. It animates between these two states as the drawer opens.
抽屉关闭时显示汉堡图标,抽屉打开时显示箭头。当抽屉打开时,它会在这两种状态之间进行动画处理。
While the training hasn't been updated to take the deprecation/new class into account, you should be able to use it almost exactly the same code - the only difference in implementing it is the constructor.
虽然培训尚未更新以考虑弃用/新类,但您应该能够使用几乎完全相同的代码 - 实现它的唯一区别是构造函数。
回答by tim
I created a small application which had similar functionality
我创建了一个具有类似功能的小应用程序
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();
}
}
My XML of that Activity
我的那个活动的 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>
My Custom Toolbar XML
我的自定义工具栏 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>
My Theme Style
我的主题风格
<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>
My Styles in values-v21
我在 values-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>
回答by Ivan Bartsov
To answer the updated part of your question: to style the drawer icon/arrow, you have two options:
要回答问题的更新部分:要设置抽屉图标/箭头的样式,您有两个选择:
Style the arrow itself
设计箭头本身
To do this, override drawerArrowStyle
in your theme like so:
为此,请覆盖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>
This is probably not what you want, because the ActionBar itself should have consistent styling with the arrow, so, most probably, you want the option two:
这可能不是您想要的,因为 ActionBar 本身应该具有与箭头一致的样式,因此,很可能您需要选项二:
Theme the ActionBar/Toolbar
主题操作栏/工具栏
Override the android:actionBarTheme
(actionBarTheme
for appcompat) attribute of the global application theme with your own theme (which you probably should derive from ThemeOverlay.Material.ActionBar/ThemeOverlay.AppCompat.ActionBar
) like so:
使用您自己的主题(您可能应该从中派生)覆盖全局应用程序主题的android:actionBarTheme
( actionBarTheme
for 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>
An important note here is that when using a custom layout with a Toolbar
instead of stock ActionBar implementation (e.g. if you're using the DrawerLayout
-NavigationView
-Toolbar
combo to achieve the Material-style drawer effect where it's visible under translucent statusbar), the actionBarTheme
attribute is obviosly not picked up automatically (because it's meant to be taken care of by the AppCompatActivity
for the default ActionBar
), so for your custom Toolbar
don't forget to apply your theme manually:
一个重要的注意这里是当使用带有自定义布局Toolbar
,而不是股票的动作条的实施(例如,如果您使用的是DrawerLayout
- NavigationView
-Toolbar
组合来实现材料式抽屉效果,即它在半透明的状态栏是可见的),该actionBarTheme
属性是obviosly不自动拾取(因为它是由AppCompatActivity
默认值处理的ActionBar
),因此对于您的自定义,Toolbar
请不要忘记手动应用您的主题:
<!--inside your custom layout with DrawerLayout
and NavigationView or whatever -->
<android.support.v7.widget.Toolbar
...
app:theme="?actionBarTheme">
-- this will resolve to either AppCompat's default ThemeOverlay.AppCompat.ActionBar
or your override if you set the attribute in your derived theme.
--ThemeOverlay.AppCompat.ActionBar
如果您在派生主题中设置属性,这将解析为 AppCompat 的默认值或您的覆盖。
PSa little comment about the drawerArrowStyle
override and the spinBars
attribute -- which a lot of sources suggest should be set to true
to get the drawer/arrow animation. Thing is, spinBars
it is true
by defaultin AppCompat (check out the Base.Widget.AppCompat.DrawerArrowToggle.Common
style), you don't have to override actionBarTheme
at all to get the animation working. You get the animation even if you do override it and set the attribute to false
, it's just a different, less twirly animation. The important thing here is to use ActionBarDrawerToggle
, it's what pulls in the fancy animated drawable.
PS关于drawerArrowStyle
覆盖和spinBars
属性的一些评论- 许多来源建议应该设置true
为获取抽屉/箭头动画。spinBars
事实是,它true
默认在 AppCompat 中(查看Base.Widget.AppCompat.DrawerArrowToggle.Common
样式),您根本不必覆盖actionBarTheme
即可使动画正常工作。即使您确实覆盖了动画并将属性设置为false
,您也会获得动画,这只是一个不同的、不那么扭曲的动画。这里重要的是使用ActionBarDrawerToggle
,它是吸引精美动画可绘制对象的原因。
回答by Nitin Misra
I want to correct little bit the above code
我想更正一下上面的代码
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);
}
and all the other things will remain same...
所有其他的事情都将保持不变......
For those who are having problem Drawerlayout
overlaying toolbar
对于那些在Drawerlayout
覆盖工具栏时遇到问题的人
add android:layout_marginTop="?attr/actionBarSize"
to root layout of drawer content
添加android:layout_marginTop="?attr/actionBarSize"
到抽屉内容的根布局