[AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统

时间:2022-05-15 05:15:01

2019-12-27  20:44:40  WideMouth

DrawerLayout布局结合HomeAsUp箭头动画效果最小系统

 

   2019年12月27日,现在,终于解决了写下这篇博客的所有事情,之前一直纠结博客园无法上传视频,找了很多种方法,尝试上传B网站视频测试,查看博客时却无法显示,原来是园主设置了JS权限,申请了才能支持HTML代码,几个小时申请完后,发现上传的视频无法自动播放(尝试了网上的办法,还是没能解决,头疼),一小时前找到了完美的解决办法(GIF)哈哈,多么简单的办法,还真是难倒人的总是一些简单到恶心的细节。终于开启我的博客之路啦!!!这是我的第一篇博客哦!

  说了这么多废话,现在开始啦!!!

  先上效果图:

                             [AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统

  随便下了一个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标签将他们添加进来即可。现在我们运行一下。

        [AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统

  这时,我们发现屏幕上方多出一条白条,这是因为我们的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>

  再次运行: 

       [AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统 

  这里我们已经实现了滑动菜单功能,但还不具有滑动箭头特效,这就需要我们的代码了。我们继续来优化。

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滑动时,会调用此方法,方法内更新了导航按钮状态,从而实现了文章开头的动画效果。代码部分我注释的很详细,大家应该容易上手。

  效果图:

      [AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统

  注意:如果大家运行时出现闪退,可能是大家没有按文章上述要求修改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个属性的颜色,相关属性的对应位置如图:

            [AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统

  最后的优化,修改导航按钮颜色需要我们为其设置主题,顺便我们设置了其他属性颜色。

  附最终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

  最终效果图:

           [AndroidStudio]DrawerLayout布局结合HomeAsUp箭头动画效果最小系统