前言
提前下班了!!!
综述
先来看一下最终的效果图
功能点
1、CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout、Toolbar、TabLayout、ViewPager联动使用
2、联动过程中保持沉浸式状态栏效果
3、ToolBar的基本使用,如自定义居中的title, Toolbar和Menu的结合使用,自定义溢出菜单样式
期间会涉及控件各种属性的设置,这个比较细碎
中间遇到一个问题,就是给menu,navigation等设置图片时,图片被拉伸(原因:把基于1280*720的切图放在了drawable文件夹下了,应该放在drawable-xhdpi)
4、解决应用启动白屏的问题
各个突破
设置ToolBar
private void setupToolbar() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int statusBarHeight = getStatusBarHeight(this);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
layoutParams.topMargin = statusBarHeight;
}
appbar = (AppBarLayout) findViewById(R.id.appbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); //使用系统自带的返回按钮
getSupportActionBar().setHomeAsUpIndicator(R.drawable.icon_back_normal);//替换系统自带的返回图标
toolbar.setOnMenuItemClickListener(onMenuItemClick);
}
private Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_share:
Toast.makeText(MainActivity.this, "收藏", Toast.LENGTH_SHORT).show();
//其余的省略
break;
}
return true;
}
};
private void setupCollapsingToolbar() {
collapseToolbar = (CollapsingToolbarLayout) findViewById(
R.id.collapse_toolbar);
collapseToolbar.setTitleEnabled(false);
}
OnOffsetChangedListener联动显示
实现AppBarLayout的OnOffsetChangedListener
@Override
protected void onResume() {
super.onResume();
appbar.addOnOffsetChangedListener(this);
}
@Override
protected void onPause() {
super.onPause();
appbar.removeOnOffsetChangedListener(this);
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (lastPosition == verticalOffset) {
return;
}
lastPosition = verticalOffset;
if (verticalOffset == 0) {
getSupportActionBar().setTitle("");
btnRight.setVisibility(View.GONE);
viewTitle.setPadding(0, 6, 0, 0);
toolbarTitle.setText("");
return;
} else if (verticalOffset < -dip2px(this, 110)) {
viewTitle.setPadding(0, 0, 0, 0);
getSupportActionBar().setTitle("");
btnRight.setVisibility(View.GONE);
toolbarTitle.setText("");
} else {
viewTitle.setPadding(0, 6, 0, 0);
getSupportActionBar().setTitle("");
toolbarTitle.setText("军团再临");
btnRight.setVisibility(View.VISIBLE);
}
}
自定义溢出菜单样式
定义样式
<!--溢出菜单样式 -->
<style name="OverflowMenuStyle" parent="@style/Widget.AppCompat.Light.PopupMenu.Overflow">
<item name="overlapAnchor">false</item>
<item name="android:dropDownWidth">wrap_content</item>
<item name="android:paddingRight">5dp</item>
<item name="android:popupBackground">@color/dcdcdc</item>
<item name="android:dropDownVerticalOffset">4dip</item>
<item name="android:dropDownHorizontalOffset">-4dip</item>
</style>
添加到application theme中(前两个属性是为了解决启动白屏的问题)
<style name="Theme.AppStartLoadTranslucent" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<!--<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>-->
</style>
AndroidManifest.xml
设置theme为Theme.AppStartLoadTranslucent
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.soulrelay.coordinatorlayoutdemo">
<!-- To access Google+ APIs: -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppStartLoadTranslucent">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
其实,之前实现类似菜单功能采用popupwindow居多
Toolbar中Menu中图标不显示的问题
在menu中,图标不会显示。
有的人是采用 onMenuOpened() 来写,可是仍然会有问题,对于AppCompactActivity你可以把onPrepareOptionsPanel(View v,Menu menu)代替 onMenuOpened() 。
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
if (menu != null) {
if (menu.getClass() == MenuBuilder.class) {
try {
Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return super.onPrepareOptionsPanel(view, menu);
}
toolbar menu中app:showAsAction各个属性值作用
android:showAsAction。这个属性可接受的值有:
- always:使菜单项一直显示在ToolBar上。
- ifRoom:如果有足够的空间,这个值会使菜单项显示在ToolBar上。
- never:使菜单项永远都不出现在ToolBar上,在…的子项中显示。
- withText:使菜单项和它的图标,菜单文本一起显示。
源码下载
参考链接
Android布局属性android:clipToPadding的UI设计妙用
Android开发:最详细的 Toolbar 开发实践总结
fitsSystemWindows