基于ToolBar等MD相关控件实现的沉浸式联动效果

前言


Drawing

提前下班了!!!

综述

先来看一下最终的效果图


这里写图片描述

功能点

1、CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout、Toolbar、TabLayout、ViewPager联动使用 2、联动过程中保持沉浸式状态栏效果 3、ToolBar的基本使用,如自定义居中的title, Toolbar和Menu的结合使用,自定义溢出菜单样式
期间会涉及控件各种属性的设置,这个比较细碎

中间遇到一个问题,就是给menu,navigation等设置图片时,图片被拉伸(原因:把基于1280*720的切图放在了drawable文件夹下了,应该放在drawable-xhdpi)

4、解决应用启动白屏的问题

各个突破

设置ToolBar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@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);
}
}

自定义溢出菜单样式

定义样式

1
2
3
4
5
6
7
8
9
<!--溢出菜单样式 -->
<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中(前两个属性是为了解决启动白屏的问题)

Android 启动白屏或者黑屏闪现解决

1
2
3
4
5
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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() 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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。这个属性可接受的值有:

SuS wechat
欢迎您扫一扫上面的微信公众号,订阅我的最新信息!
坚持原创技术分享,您的支持将鼓励我继续创作!