編輯:關於Android編程
實現思路
利用自定義的HorizontalScrollView實現。 HorizontalScrollView中管理兩個視圖,一個視圖為“菜單”,另一個為“正文”。初始時“菜單”部分在屏幕可視區域以外。當利用HorizontalScrollView的滑動機制進行水平滑動時,將隱藏在屏幕外的“菜單”部分“拖入”屏幕可視區域。 效果增強實現步驟
初步示意圖MySlidingMenu extends HorizontalScrollView
然後利用自定義的MySlidingMenu構建MainActivity中的布局
其中left_menu_layout就是一個簡單的LinearLayout,羅列了幾個TextView形式的菜單項,正文區域是一幅圖片
方法重寫@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { wrapper = (LinearLayout) this.getChildAt(0); menu = wrapper.getChildAt(0); content = wrapper.getChildAt(1); menuWidth = screenWidth - menuRightPadding; menu.getLayoutParams().width = menuWidth; content.getLayoutParams().width = screenWidth; super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { this.scrollTo(menuWidth, 0); } }
在onMeasure方法中screenWidth是屏幕的寬度:
DisplayMetrics outMetrics = new DisplayMetrics(); ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(outMetrics); screenWidth = outMetrics.widthPixels;
menuRightPadding是“菜單”打開後,菜單距離屏幕右側的距離。該值可以被當做一個自定義屬性在布局文件中由使用者傳入。默認值為80dp
TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.MySlidingMenu); menuRightPadding = t.getDimensionPixelSize(R.styleable.MySlidingMenu_menu_padding, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics())); t.recycle();
在確定了“菜單”部分的寬度後,在onLayout方法中調用scrollTo方法,該方法就是將MySlidingMenu的“內容區域”的左邊緣移動到MySlidingMenu左邊緣的左側,距離恰好是“菜單”的寬度。這樣就保證了“菜單”恰好位於屏幕可視區域之外。
此時就可以運行代碼,實現“菜單”的側滑了。
@Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); if (action == MotionEvent.ACTION_UP) { int sx = getScrollX(); if (sx >= menuWidth / 2) { smoothScrollTo(menuWidth, 0); isOpen = false; } else { smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); }
這裡在完成滑動時直接調用了HorizontalScrollView的smoothScrollTo方法,這樣可以實現一個平滑的滑動過程,而不會像scrollTo那樣瞬間完成滑動。
在上面的實現中,“菜單”是從左側被“拖”出來的,接下來實現一種正文好像覆蓋在“菜單”上面的感覺,先看示意圖,對比一下兩者的差異:
可以明顯看出兩者的效果差異吧。
要從“拖出”效果轉為“覆蓋”效果,僅僅需要一行代碼:
重寫一下父類的onScrollChanged方法即可:
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { ViewHelper.setTranslationX(menu, l); super.onScrollChanged(l, t, oldl, oldt); }
其中ViewHelper是nineoldandroids.jar中的一個類,nineoldandroids不用過多介紹了,它是一個兼容3.0以下版本實現屬性動畫的一個安卓類庫。setTranslationX的意思就是設定“菜單”這個視圖的translationX的值。方法中將menu視圖的translationX的值設定為了onScrollChanged方法的第一個參數值。這是因為:
當MySlidingMenu的scrollTo方法被調用的時候(scrollBy和smoothScrollTo方法內部也是在調用scrollTo方法),scrollTo方法內部做的事情就是設定好滑動終止時的目標scrollX和scrollY的值以及滑動開始時的scrollX與scrollY的值,然後調用onScrollChanged方法,將這四個值作為onScrollChanged方法的四個參數,因此l參數的意思實際就是當滑動結束時“菜單”視圖的scrollX的值。
MySlidingMenu的本身的視圖寬度為屏幕的寬度,而MySlidingMenu中管理的內容是“菜單”視圖+“正文”視圖,內容的寬度是大於MySlidingMenu本身的寬度的,scrollX代表的就是MySlidingMenu現實的內容左邊緣與MySlidingMenu本身左邊緣的距離。
如果此時不做任何額外的操作,那麼“菜單”視圖停留在MySlidingMenu左側邊緣的左側,距離MySlidingMenu左側邊緣scrollX個像素。現在希望它能夠出現在可視區域中,也就是讓“菜單”視圖的左邊緣恰好出現在MySlidingMenu的左邊緣,那就需要讓“菜單”視圖從當前自己的左邊緣開始再多滑動scrollX個像素的距離。如何滑動呢,就設定“菜單”視圖的translationX屬性值即可,translationX屬性值代表讓視圖產生移動,視圖移動後左側邊緣與視圖left屬性之間的距離(這部分內容的詳情可以參考我的另一篇blogView的坐標系)。所以只要設定“菜單”視圖的translationX屬性值為滑動結束後的scrollX的值即可,這樣每次滑動結束後,利用translationX再讓“菜單”視圖多滑動scrollX個像素值。這樣就實現了每次滑動時,“菜單”視圖始終都是左側與MySlidingMenu的左側保持一致的效果。
接下來再增加一些滑動中的效果。比如隨著滑動,讓“內容”區域產生一個由大到小的變化,讓“菜單”區域產生一個由小到大的變化,並伴隨一個透明度的變化:
這一切的發生都是隨著滑動而發生的,因此這裡需要找到一個隨著滑動而不斷變化的比例值:
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { float scale = l*1.0f/menuWidth; ViewHelper.setTranslationX(menu, l); super.onScrollChanged(l, t, oldl, oldt); }
隨著滑動l的值會不斷發生變化,但是“菜單”的寬度是在onMeasure方法中設定好的,並不會變化,而滑動的整體變化過程或者說l的取值范圍就是從0到menuWidth。有了這個scale後,就可以利用它實現各種滑動過程中的變化了:
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { //隨著滑動,l的值不斷變化(從menuWidth到0)。將絕對值值轉化為一個比值 //scale的變化區間是1--->0 float scale = l*1.0f/menuWidth; ViewHelper.setTranslationX(menu, l); //隨著拖動,content區域由大到小從100%--->70%左右 ViewHelper.setScaleX(content,0.7f+0.3f*scale); ViewHelper.setScaleY(content,0.7f+0.3f*scale); ViewHelper.setPivotX(content,0); ViewHelper.setPivotY(content,content.getHeight()/2); //隨著拖動,菜單區域的透明度在變化,變化區間大概是0.7--->1 ViewHelper.setAlpha(menu,0.5f+0.5f*(1-scale)); //隨著拖動,菜單區域的大小在變化變化區間大概是0.7--->1 ViewHelper.setScaleX(menu,0.7f+0.3f*(1-scale)); ViewHelper.setScaleY(menu,0.7f+0.3f*(1-scale)); super.onScrollChanged(l, t, oldl, oldt); }
代碼運行後的效果如圖所示:
還可以再增加一點效果。此時的效果是隨著拖動“菜單”視圖恰好每次都是出現在MySlidingMenu的左邊緣。如果每次不讓“菜單”視圖都移動scrollX的距離,而是移動的少一點,這樣在MySlidingMenu的滑動過程除了上述已經有的效果外,還可以再帶著一點“菜單”平滑拖出的效果。
只需要修改setTranslationX部分即可,原先移動l,現在讓l乘以一個比例值,就可以不移動scrollX了:
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { //隨著滑動,l的值不斷變化(從menuWidth到0)。將絕對值值轉化為一個比值 //scale的變化區間是1--->0 float scale = l*1.0f/menuWidth; //ViewHelper.setTranslationX(menu, l); ViewHelper.setTranslationX(menu, l*0.7f); //隨著拖動,content區域由大到小 //但是並不是到0,大概是從100%--->70%左右 ViewHelper.setScaleX(content,0.7f+0.3f*scale); ViewHelper.setScaleY(content,0.7f+0.3f*scale); ViewHelper.setPivotX(content,0); ViewHelper.setPivotY(content,content.getHeight()/2); //隨著拖動,菜單區域的透明度在變化 //變化區間大概是0.7--->1 ViewHelper.setAlpha(menu,0.5f+0.5f*(1-scale)); //隨著拖動,菜單區域的大小在變化 //變化區間大概是0.7--->1 ViewHelper.setScaleX(menu,0.7f+0.3f*(1-scale)); ViewHelper.setScaleY(menu,0.7f+0.3f*(1-scale)); super.onScrollChanged(l, t, oldl, oldt); }
看一下這次的運行效果:
可以看到“菜單”區域除了透明度、大小變化之外,還有了側拉效果。
該策滑菜單的基本實現需要掌握自定義View的基本知識,以及scrollTo的用法。在效果增強部分,需要先理解View中的幾個坐標點的差異包括left,scrollX,translationX等,這樣才能逐步實現效果。
1.第一種方法package com.example.jer824;import android.os.Handler;import android.os.Message
一、獲取屏幕寬高1、android界面簡單介紹要獲取屏幕寬高,我們可以先從android的界面構成了解 android的界面主要由三部分構成:1、狀態欄 2、標
場景是這樣的,站點上篩選按鈕點擊後彈出層(fixed),當輸入框獲取焦點以後彈出系統自帶的軟鍵盤,在android上十款浏覽器挨個測試比對,發現在360浏覽器彈出鍵盤以後
字體管家是最好的字體下載工具,提供字體下載、字體備份、字體預覽、字體修復功能,永久免費的好軟件,為您提供最好用的字體下載字體備份字體安裝軟件。我們來看看如何