zoukankan      html  css  js  c++  java
  • 文章标题

    通过重写FrameLayout 中boolean fitSystemWindows(Rect insets)方法来实现ActionBar的Overlay模式不遮盖顶部的设计

    应用场景:

    在一个ListView显示图片的界面中,当ListView向下滑动的时候,actionbar是是浮动在GridView上面一层的。可是当ListView滚动到顶部,顶部的内容是全然显示出来的,当然这种情况一般ActionBar我们会做成透明效果。

    主要代码:

    1.对应的FrameLayout

    ...
    @Override
        protected boolean fitSystemWindows(Rect insets) {
            mInsets = new Rect(insets);
            setWillNotDraw(mInsetBackground == null);
            postInvalidateOnAnimation();
            if (mOnInsetsCallback != null) {
                mOnInsetsCallback.onInsetsChanged(insets);
            }
            return true; // consume insets
        }
    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            int width = getWidth();
            int height = getHeight();
            if (mInsets != null && mInsetBackground != null) {
                // Top
                mTempRect.set(0, 0, width, mInsets.top);
                mInsetBackground.setBounds(mTempRect);
                mInsetBackground.draw(canvas);
                // Bottom
                mTempRect.set(0, height - mInsets.bottom, width, height);
                mInsetBackground.setBounds(mTempRect);
                mInsetBackground.draw(canvas);
                // Left
                mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
                mInsetBackground.setBounds(mTempRect);
                mInsetBackground.draw(canvas);
                // Right
                mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
                mInsetBackground.setBounds(mTempRect);
                mInsetBackground.draw(canvas);
            }
        }
        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            if (mInsetBackground != null) {
                mInsetBackground.setCallback(this);
            }
        }
        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            if (mInsetBackground != null) {
                mInsetBackground.setCallback(null);
            }
        }
        /**
         * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
         * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
         * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
         * clipToPadding to false.
         */
        public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
            mOnInsetsCallback = onInsetsCallback;
        }
        public static interface OnInsetsCallback {
            public void onInsetsChanged(Rect insets);
        }
        ...

    2.对应的activity

    xxxlayout.setOnInsetsCallback(new DrawInsetsFrameLayout.OnInsetsCallback() {
                @Override
                public void onInsetsChanged(Rect insets) {
                    // Update the map padding (inset the compass, zoom buttons, attribution, etc.)
                    Log.i("", "insets.top = " + insets.top);
                    View headerView = new View(MainActivity.this);
                    AbsListView.LayoutParams params = new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, insets.top);
    
                    headerView.setLayoutParams(params);
                    headerView.setBackgroundColor(0x33000000); 
                    listView.addHeaderView(headerView);
                }
            });

    3.actionbar风格的xml文件:

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:actionBarStyle">@style/TranslucentActionBar</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    <style name="TranslucentActionBar" parent="android:Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@null</item>
    </style>

    当中TranslucentActionBar是为自己定义的FrameLayout自己定义的一个属性,而activity的actionbar和statusbar在这里我们都是设置成了浮动模式的,注意<item name="android:windowTranslucentStatus">true</item>

    4.最后是布局内容

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:yourapp="http://schemas.android.com/apk/res-auto"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />
        <xxxFrameLayout
            android:id="@+id/my_draw_insets_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            yourapp:insetBackground="#9000" />
    </FrameLayout>

    5.当然效果图是这种

    这个是没处理的效果。图片来自网络

    这个是处理后的效果,图片来来自网络

    最后鸣谢:
    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0930/1720.html

  • 相关阅读:
    shiro什么时候会进入doGetAuthorizationInfo(PrincipalCollection principals)
    Kali2安装完成后的设置
    Springboot打包war
    2017总结及2018计划
    gitlab数据库
    Entity Framework学习
    从零开始编写操作系统——bochs
    Docker基本操作
    Jenkins打包安卓时提示没同意constraintLayout的license的解决方法
    env:bash 解决
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7100015.html
Copyright © 2011-2022 走看看