1. 程式人生 > >SlideMenu實現沉浸式效果

SlideMenu實現沉浸式效果

SlideMenu是一個在Android上被廣泛使用的開源庫,它是一個仿照IOS左滑選單開發的類似效果。 
SlideMenu開源庫GuiHub地址如下: 
SlideMenu GitHub

在專案中匯入SlideMenu有兩種方式,一種是將SlideMenu作為Library庫,然後在自己的專案中右鍵點選Properties–>android–>在右下方Library選項將開源庫新增進來,點選apply即可;第二種方式是將SlideMenu專案中的lib包直接複製到我們的專案中(這裡存在第三種方式,可以自己打Jar,略過不談),之後如何開始利用SlideMenu新增選單呢? 
第一步,我們一般可以寫個自定義控制元件繼承SlideMenu,其主要程式碼如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Activity activity;
    SlidingMenu localSlidingMenu;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">MySlideMenu</span>(Activity activity) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.activity = activity;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> SlidingMenu <span class="hljs-title" style="box-sizing: border-box;">initSlidingMenu</span>() {
        localSlidingMenu = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SlidingMenu(activity);
        localSlidingMenu.setMode(SlidingMenu.LEFT);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定左右滑選單</span>
        localSlidingMenu.setTouchModeAbove(SlidingMenu.SLIDING_WINDOW);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定要使選單滑動,觸碰螢幕的範圍</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//localSlidingMenu.setTouchModeBehind(SlidingMenu.SLIDING_CONTENT);</span>
        localSlidingMenu.setShadowWidthRes(R.dimen.shadow_width);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定陰影圖片的寬度</span>
        localSlidingMenu.setShadowDrawable(R.drawable.shadow);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定陰影圖片</span>
        localSlidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//SlidingMenu劃出時主頁面顯示的剩餘寬度</span>
        localSlidingMenu.setFadeDegree(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.35</span>F);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//SlidingMenu滑動時的漸變程度</span>
        localSlidingMenu.attachToActivity(activity, SlidingMenu.SLIDING_WINDOW);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使SlidingMenu附加在Activity右邊</span>
        localSlidingMenu.setMenu(R.layout.left_drawer_fragment);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定menu的佈局檔案</span>
        localSlidingMenu.setOnOpenedListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SlidingMenu.OnOpenedListener() {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onOpened</span>() {

                    }
                });
        localSlidingMenu.setOnClosedListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> OnClosedListener() {

            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClosed</span>() {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated method stub</span>

            }
        });
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> localSlidingMenu;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li></ul>

其中選單的佈局檔案大家可以自己設定,之後在我們的Activity的OnCreate中新增如下程式碼:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    MySlideMenu slide=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> MySlideMenu(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
    slide.initSlidingMenu();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

這樣左滑選單即可成功匯入,效果如下(來自仿今日頭條原始碼):

這裡寫圖片描述

那麼,實現沉浸式選單欄該怎麼做呢: 
在Activity設定了佈局檔案之後加入如下程式碼:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">if (Environment<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getInstance</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getOSVersionCode</span>() >= VERSION_CODES<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.KITKAT</span>) {
            getWindow()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addFlags</span>(   WindowManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.LayoutParams</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FLAG</span>_TRANSLUCENT_STATUS)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            getWindow()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addFlags</span>(           WindowManager<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.LayoutParams</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.FLAG</span>_TRANSLUCENT_NAVIGATION)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

因為沉浸式狀態列是在Android4.4才被Google引用的,所以需要先判斷SDK的版本是否超過了KITKAT。在佈局檔案的程式碼中加入如下兩句:

<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> android:clipToPadding=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"true"</span>
 android:fitsSystemWindows=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"true"</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

這裡是使得控制元件佈局頂到狀態列去。 
那麼在SlideMenu中加入沉浸式會是什麼效果呢?請看下圖: 
這裡寫圖片描述 
圖中顯示,控制元件無法實現沉浸式效果。可真的是如此麼?仔細觀察可以發現,狀態列的顏色確實是改變了,而且變成了白色,那麼說明狀態列是沉浸了的,只是下面的控制元件無法“頂”上去而已,那麼該如何解決呢? 
通過扒SlideMenu的原始碼可知,SlideMenu是利用ViewGroup來作為ViewAbove和ViewBehind的容器,而這裡的ViewAbove和ViewBehind就是分別代表我們的主介面佈局檔案和選單佈局檔案。而通過查閱資料我們發現,沉浸式狀態列是僅僅支援Layout和TextView等幾種控制元件的沉浸效果的,而且如果Layout裡面的第一個控制元件為ImageView,沉浸效果也是無法實現的,所以,筆者這裡提供兩個解決方案: 
方案一:修改SlideMenu原始碼 (最簡單實現)

方案二:參考http://blog.csdn.net/zf19921020/article/details/46840383