基于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

  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中(前两个属性是为了解决启动白屏的问题)

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

  <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

发布了97 篇原创文章 · 获赞 87 · 访问量 32万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览