Android ToolBar 使用完全解析
http://www.jianshu.com/p/ae0013a4f71a
style.xml
<font color="#4590a3" size = "6px">
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
</font>
我们需要ToolBar来代替ActionBar,因此要指定一个不带ActionBar的主题。通常有Theme.AppCompat.NoActionBar 和 Theme.AppCompat.Light.NoActionBar这两种主题可选。Theme.AppCompat.NoActionBar表示深色主题,它将界面的主题颜色设成深色,陪衬颜色设为淡色。Theme.AppCompat.Light.NoActionBar表示淡色主题,它会将界面的主题颜色设成淡色,陪衬颜色设成深色。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.class
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
}
1.Theme.AppCompat.Light.NoActionBar淡色主题陪衬颜色会自动设成深色
2.我们把style.xml 的主题改为Theme.AppCompat.NoActionBar深色主题陪衬颜色会自动设成淡色
如果使用了淡色主题,而Toolbar上面的各元素就会自动使用深色主题,如果使用了深色主题,Toolbar上面的各元素就会自动使用淡色主题,这是为了和主题颜色区分开。
我们这里使用淡色主题
3.但是这个效果看起来很差,之前使用的ActionBar文字都是白色的,现在变为黑色会很难看。所以要把Toolbar单独使用深色主题,我们这里使用android:theme属性,将Toolbar的主题指定成@style/ThemeOverlay.AppCompat.Dark.ActionBar。
这个应用的主题是淡色主题,但是Toolbar是深色主题,所以Toolbar的陪衬颜色会自动设成淡色。
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
4.这里发现了一个问题,Toolbar的菜单按钮弹出的菜单项会变成深色主题,所以这里再使用app:popupTheme单独将弹出菜单项指定为淡色主题
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
5.指定Toolbar的背景为蓝色
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:background="@color/colorPrimary"/>
然后
代码
app/build.gradle
compile 'com.android.support:design:26.+'
compile 'de.hdodenhof:circleimageview:2.1.0'
这里添加了两行依赖关系,第一行是Design Support库,第二行是开源项目circleimageview,它可以实现图片圆化功能。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--滑动菜单-->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--第一个子控件是主屏幕显示的内容-->
<!--加强版的FrameLayout -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--标题栏-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<!--悬浮按钮-->
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_done"
app:elevation="8dp"/>
</android.support.design.widget.CoordinatorLayout>
<!--第二个子控件是滑动菜单中显示的内容-->
<!--滑动菜单布局-->
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header"/>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
DrawerLayout它是一个布局,在布局中允许放两个直接子控件,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容。
NavigationView是Design Support库中提供的一个控件,它按照Material Design的要求来进行设计,将滑动菜单页面的实现变得很简单,它其实就是滑动菜单的布局。menu用来在NavigationView显示菜单项,headerLayout用来显示NavigationView的头部布局。
FloatingActionButton是Design Support库中提供的一个控件,这个控件可以帮助我们比较轻松地实现悬浮按钮的效果,它其实就是悬浮按钮。elevation:设置阴影,高度值越大阴影投影范围越大,投影效果越淡。
CoordinatorLayout可以说是加强版的FrameLayout,这个布局是由Design Support库提供的。它可以监听所有子控件的各种事件,然后帮我们作出响应。比如弹出的Snackbar提示将悬浮按钮遮挡住了,而如果我们能让CoordinatorLayout监听到Snackbar的弹出事件,那么它会自动将内部的FloatingActionButton向上偏移,从而保证不会被Snackbar遮挡到。
menu/toolbar.xml
标题栏上面的内容
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/backup"
android:icon="@drawable/ic_backup"
android:title="Backup"
app:showAsAction="always"/>
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete"
android:title="Delete"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="never"/>
</menu>
always:表示永远显示在Toolbar中,如果屏幕空间不够则不显示,不会显示在菜单当中
ifRoom:表示在屏幕空间足够的情况下显示在Toolbar中,不够的话显示在菜单当中
never: 永远显示在菜单中
layout/nav_header.xml
NavigationView的头部布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:padding="10dp"
android:background="@drawable/timg">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/icon_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/nav_icon"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[email protected]"
android:textColor="#FFF"
android:textSize="14sp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="可爱女人"
android:layout_below="@+id/icon_image"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:textColor="#FFF"
android:textSize="14sp"/>
</RelativeLayout>
menu/nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_call"
android:icon="@drawable/nav_call"
android:title="Call"/>
<item
android:id="@+id/nav_friends"
android:icon="@drawable/nav_friends"
android:title="Friends"/>
<item
android:id="@+id/nav_location"
android:icon="@drawable/nav_location"
android:title="Loaction"/>
<item
android:id="@+id/nav_mail"
android:icon="@drawable/nav_mail"
android:title="Mail"/>
<item
android:id="@+id/nav_task"
android:icon="@drawable/nav_task"
android:title="Tasks"/>
</group>
</menu>
checkableBehavior指定为single表示菜单项只能单选
layout/snackbar_icon.xml
snackbar的图标
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
MainActivity.xml
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;//标题
private DrawerLayout mDrawerLayout;//滑动菜单布局
private NavigationView navView;//滑动菜单界面
private FloatingActionButton fab;//悬浮按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navView = (NavigationView) findViewById(R.id.nav_view);
fab = (FloatingActionButton) findViewById(R.id.fab);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);//导航按钮显示出来
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);//设置导航图标
}
navView.setCheckedItem(R.id.nav_call);//默认选中
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
//关闭滑动菜单
mDrawerLayout.closeDrawers();
return true;
}
});
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"悬浮按钮",Toast.LENGTH_SHORT).show();
Snackbar snackbar = Snackbar.make(view," " +
"Snackbar",Snackbar.LENGTH_LONG);
snackbar.setAction("Undo", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"这是Snackbar",Toast.LENGTH_SHORT).show();
}
}).show();
View snackbarview = snackbar.getView();
//设置snackbar的颜色
snackbarview.setBackgroundColor(Color.parseColor("#3F51B5"));
//设置snackbar的图标
//将获取的View转换成SnackbarLayout
Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) snackbarview;
//加载布局文件新建View
View snackbarIcon = LayoutInflater.from(snackbarview.getContext()).
inflate(R.layout.snackbar_icon,null);
//设置新建布局参数
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
//设置新建布局在Snackbar内垂直居中显示
p.gravity = Gravity.CENTER_VERTICAL;
snackbarLayout.addView(snackbarIcon,0,p);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home://HomeAsUp的id永远都是android.R.id.home
mDrawerLayout.openDrawer(GravityCompat.START);//把滑动菜单显示出
break;
case R.id.backup:
Toast.makeText(this, "You click Backup",Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this,"You click Delete",Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this,"You click Settings",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
Snackbar的make方法来创建一个Snackbar对象,make()方法的第一个参数传入一个view,只要是当前界面布局任意一个View都可以,Snackbar会使用这个View来自动查找最外层布局,用于展示Snackbar。第二个参数就是Snackbar中显示的内容。第三个参数就是Snackbar中显示的时长。settAction方法来设置一个动作,从而让Snackbar不仅仅是一个提示,而是可以和用户一起交互。但是当Snackbar弹出时会把悬浮按钮挡住怎么办呢?使用CoordinatorLayout轻松解决。