編輯:關於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等,這樣才能逐步實現效果。
Android——線程+最簡單計數器
1.第一種方法package com.example.jer824;import android.os.Handler;import android.os.Message
android獲取控件寬高和屏幕寬高
一、獲取屏幕寬高1、android界面簡單介紹要獲取屏幕寬高,我們可以先從android的界面構成了解 android的界面主要由三部分構成:1、狀態欄 2、標
360浏覽器文本框獲得焦點後被android軟鍵盤遮罩該怎麼辦
場景是這樣的,站點上篩選按鈕點擊後彈出層(fixed),當輸入框獲取焦點以後彈出系統自帶的軟鍵盤,在android上十款浏覽器挨個測試比對,發現在360浏覽器彈出鍵盤以後
如何使用字體管家為qq換字體
字體管家是最好的字體下載工具,提供字體下載、字體備份、字體預覽、字體修復功能,永久免費的好軟件,為您提供最好用的字體下載字體備份字體安裝軟件。我們來看看如何