2019-12-27 20:44:40 WideMouth
DrawerLayout布局结合HomeAsUp箭头动画效果最小系统
2019年12月27日,现在,终于解决了写下这篇博客的所有事情,之前一直纠结博客园无法上传视频,找了很多种方法,尝试上传B网站视频测试,查看博客时却无法显示,原来是园主设置了JS权限,申请了才能支持HTML代码,几个小时申请完后,发现上传的视频无法自动播放(尝试了网上的办法,还是没能解决,头疼),一小时前找到了完美的解决办法(GIF)哈哈,多么简单的办法,还真是难倒人的总是一些简单到恶心的细节。终于开启我的博客之路啦!!!这是我的第一篇博客哦!
说了这么多废话,现在开始啦!!!
先上效果图:
随便下了一个GIF软件(Screen To GIF),鼠标特效挺不错的,看到ToolBar最左侧的箭头按钮了吗,效果很炫酷吧,没玩过的你一定觉得很难做吧,嘻嘻,放心啦,AndroidStudio都为你封装好啦,只需几段代码量就能解决呢,有没有很激动,那就跟我一起来吧!!!
首先我们需要准备一个ToolBar布局,为了以后更好的扩展,就不直接在activity_main.xml里添加啦,我要将他独立出来,那让我们在layout文件夹New一个layout XML file吧,就命名为toolbar.xml吧!
代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:id="@ id/Toolbar" 5 android:layout_width="match_parent" 6 android:layout_height="?attr/actionBarSize" 7 android:background="?attr/colorPrimary" 8 app:title="WideMouth" 9 app:titleTextColor="@android:color/holo_blue_dark" />
这里将ToolBar的高度设置成ActionBar的高度,将背景颜色设置为colorPrimary(标题栏)颜色,标题为WideMouth并设置颜色为暗蓝色,一个简单的自定义ToolBar就做好啦!
下面是DrawerLayout布局:
drawerlayout.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:id="@ id/DrawerLayout" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent"> 7 <!-- 主界面--> 8 <FrameLayout 9 android:layout_width="match_parent" 10 android:layout_height="match_parent"> 11 <TextView 12 android:id="@ id/textView" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:layout_gravity="center" 16 android:gravity="center" 17 android:text="This is main_layout" 18 android:textColor="@android:color/holo_blue_dark" 19 android:textSize="24sp" /> 20 </FrameLayout> 21 <!--滑动菜单--> 22 <LinearLayout 23 android:layout_width="match_parent" 24 android:layout_height="match_parent" 25 android:layout_gravity="start" 26 android:orientation="vertical" 27 android:background="@android:color/darker_gray" > 28 <TextView 29 android:id="@ id/textView2" 30 android:layout_width="wrap_content" 31 android:layout_height="wrap_content" 32 android:layout_gravity="center" 33 android:gravity="center" 34 android:text="This is menu" 35 android:textSize="24sp" 36 android:textColor="@android:color/holo_blue_dark" 37 /> 38 </LinearLayout> 39 </androidx.drawerlayout.widget.DrawerLayout>
虽然代码有点长,但都是常用的布局控件,并不复杂,最外层的是我们自定义的DrawerLayout布局,DrawerLayout下放置了两个直接子布局(FrameLayout和LinearLayout),第一个子布局默认为主界面,也就是主屏幕中显示的内容,第二个子布局为滑动菜单,在LinearLayout标签属性中,最核心的代码是android:layout_gravity="start",这个属性是必须指定的,告知DrawerLayout滑动菜单是从哪边滑出,这里指定为start,意思是根据系统语言顺序习惯进行判断,系统语言为英语或汉语,则滑动菜单就从左边滑出,如果是阿拉伯语,则是从右边滑出。
注意:DrawerLayout布局可以有多个子布局,这里放置了两个,其实也可以两个以上,但除了第一个子布局外,后面的子布局都需指定android:layout_gravity属性,可以是start、end(右边)、bottom(底部)。子布局也可以是其他控件,DrawerLayout并没有限制只能使用固定的控件。
准备好这两个主要的自定义布局后,下面我们将他写进activity_main.xml吧。
activity_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8 tools:context=".MainActivity"> 9 10 <include layout="@layout/toolbar"/> 11 <include layout="@layout/drawerlayout"/> 12 </LinearLayout>
主布局是不是很简单,这主要得益于我们将两个主布局都做好啦,这里我们只需要通过include标签将他们添加进来即可。现在我们运行一下。
这时,我们发现屏幕上方多出一条白条,这是因为我们的MainActivity继承自AppCompatActivity,系统自动给我们配置了一个ActionBar(标题栏),这是我们需要将他删除,打开res/values/styles.xml文件,添加<item name="windowNoTitle">true</item>,去掉默认的ActionBar。
styles.xml:
1 <resources> 2 3 <!-- Base application theme. --> 4 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 5 <!-- Customize your theme here. --> 6 7 <item name="windowNoTitle">true</item> 8 9 <item name="colorPrimary">@color/colorPrimary</item> 10 <item name="colorPrimaryDark">@color/colorPrimaryDark</item> 11 <item name="colorAccent">@color/colorAccent</item> 12 </style> 13 </resources>
再次运行:
这里我们已经实现了滑动菜单功能,但还不具有滑动箭头特效,这就需要我们的代码了。我们继续来优化。
MainActivity:
1 package com.widemouth.drawerlayout; 2 3 import androidx.annotation.NonNull; 4 import androidx.appcompat.app.ActionBar; 5 import androidx.appcompat.app.ActionBarDrawerToggle; 6 import androidx.appcompat.app.AppCompatActivity; 7 import androidx.appcompat.widget.Toolbar; 8 import androidx.core.view.GravityCompat; 9 import androidx.drawerlayout.widget.DrawerLayout; 10 11 import android.os.Bundle; 12 import android.view.MenuItem; 13 import android.view.View; 14 15 public class MainActivity extends AppCompatActivity { 16 private DrawerLayout drawerLayout; 17 private ActionBarDrawerToggle drawerToggle; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 //设置状态栏黑色字体 23 getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); 24 25 Toolbar toolbar = (Toolbar) findViewById(R.id.Toolbar); 26 //将ToolBar实例传入,使ToolBar的外观与功能都和ActionBar保持一致 27 setSupportActionBar(toolbar); 28 29 ActionBar actionBar = getSupportActionBar();//得到当前ActionBar实例 30 if (actionBar != null) { 31 actionBar.setDisplayHomeAsUpEnabled(true);//显示箭头导航按钮 32 actionBar.setHomeButtonEnabled(true);//设置按钮可点击 33 // actionBar.setHomeAsUpIndicator(R.drawable.location);//更改导航按钮图标 34 } 35 drawerLayout = findViewById(R.id.DrawerLayout);//得到DrawerLayout实例 36 //new一个 ActionBarDrawerToggle,特殊类型的抽屉监听器 37 drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.app_name, R.string.app_name); 38 drawerLayout.setDrawerListener(drawerToggle);//设置监听器 39 } 40 41 //菜单按钮监听器,这里只有导航键按钮 42 @Override 43 public boolean onOptionsItemSelected(@NonNull MenuItem item) { 44 switch (item.getItemId()) { 45 case android.R.id.home: //HomeAsUp导航按钮id为android.R.id.home. 46 if (drawerLayout.isDrawerOpen(GravityCompat.START)) {//如果滑动菜单已显示 47 drawerLayout.closeDrawer(GravityCompat.START);//隐藏左边滑动菜单 48 //drawerLayout.closeDrawers();//隐藏所有滑动菜单 49 } else { 50 drawerLayout.openDrawer(GravityCompat.START);//显示滑动菜单 51 } 52 return true; 53 } 54 return super.onOptionsItemSelected(item); 55 } 56 57 //屏幕翻转变化监测,监测DrawerLayout布局状态 58 @Override 59 protected void onPostCreate(Bundle savedInstanceState) { 60 super.onPostCreate(savedInstanceState); 61 drawerToggle.syncState();//syncState方法更新导航图标和DrawerLayout布局状态保持一致 62 //实现动画效果 63 } 64 }
首先将状态栏字体和图标设置为暗色,因为这里将状态栏背景设置为浅色(文章底部附屏幕主题颜色设置指南),如果字体和图标默认也为浅色,会引起视觉上的模糊(见第二个效果图)。然后需要得到ToolBar和DrawerLayout控件实例,这样才能进行逻辑操作。这里重新两个类方法,一个是onOptionsItemSelected,用来监听ActionBar上的菜单按钮,类似于Button的setOnClickListener()方法,这里只监听了导航按钮;另一个是onPostCreate,用来监测屏幕的翻转情况,当DrawerLayout滑动时,会调用此方法,方法内更新了导航按钮状态,从而实现了文章开头的动画效果。代码部分我注释的很详细,大家应该容易上手。
效果图:
注意:如果大家运行时出现闪退,可能是大家没有按文章上述要求修改styles.xml,因为MainActivity继承自AppCompatActivity,Activity会自带一个ActionBar,当执行setSupportActionBar(toolbar);时,出现了两个ActionBar导致程序闪退。返回上一步,在styles.xml文件中添加<item name="windowNoTitle">true</item>即可。
这样,我们就完成了DrawerLayout的动画效果,不过,大家应该也发现了一个问题,导航按钮颜色是灰色的,这与ToolBar主题格格不入,我们需要进行主题修改。打开values文件夹的styles.xml,这里包含了所有的主题设置,在这里面系统在配置时默认给添加了一个AppTheme主题,其中写了colorPrimary、colorPrimaryDark和colorAccent这3个属性的颜色,相关属性的对应位置如图:
最后的优化,修改导航按钮颜色需要我们为其设置主题,顺便我们设置了其他属性颜色。
附最终styles.xml:
1 <resources> 2 <!-- Base application theme. --> 3 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 4 <!-- Customize your theme here. --> 5 <item name="windowNoTitle">true</item> 6 <item name="colorPrimary">@android:color/white</item> 7 <item name="colorPrimaryDark">#FFF0EFEF</item> 8 <item name="colorAccent">@color/colorAccent</item> 9 <item name="android:navigationBarColor">@android:color/holo_blue_dark</item> 10 <item name="drawerArrowStyle">@style/DrawerArrowStyle</item> 11 </style> 12 <style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle"> 13 <item name="spinBars">true</item> 14 <item name="color">@android:color/holo_blue_dark</item> 15 </style> 16 </resources>
大功告成!!! @WideMouth
最终效果图: