1. 程式人生 > >自定義slideview(轉)

自定義slideview(轉)

Android控制元件View打造完美的自定義側滑選單

這篇文章主要介紹了Android控制元件View打造完美的自定義側滑選單的相關資料,具有一定的參考價值,感興趣的小夥伴們可以參考一下

一、概述

  在App中,經常會出現側滑選單,側滑滑出View等效果,雖然說Android有很多第三方開源庫,但是實際上咱們可以自己也寫一個自定義的側滑View控制元件,其實不難,主要涉及到以下幾個要點:

1.對Android中Window類中的DecorView有所瞭解

2.對Scroller類實現平滑移動效果

3.自定義ViewGroup的實現

首先來看看效果圖吧:

   

  

  下面現在就來說說這裡咱們實現側滑View的基本思路吧,這裡我採用的是自定義一個繼承於RelativeLayout的控制元件叫做XCSlideView類吧。

首先從佈局檔案中inflater出來一個menuView,然後通過addView的方法,將該側滑View新增到自定義的控制元件View中怎麼讓XCSlideView 這個側滑View 隱藏到螢幕之外呢?很簡單通過ScrollTo方法,移動一個螢幕寬度的距離即可,這裡以左側滑出為例吧,只需要這樣 XCSlideView.this.scrollTo(mScreenWidth, 0);mScreenWidth是螢幕寬度。下面還要處理的就是底下的半透明黑色的蒙層效果,這個其實就是一個View,然後設定半透明效果。這個當然簡單了,關鍵是咱們讓他顯示在咱們的自定義側滑View的下面呢,這裡咱們先給出DecorView的簡單分析,方便下面介紹新增半透明View蒙層下:

下面是對上面這張圖的解釋:

1、DecorView為整個Window介面的最頂層View。

2、DecorView只有一個子元素為LinearLayout。代表整個Window介面,包含通知欄,標題欄,內容顯示欄三塊區域。

3、LinearLayout裡有兩個FrameLayout子元素。

  (20)為標題欄顯示介面。只有一個TextView顯示應用的名稱。也可以自定義標題欄,載入後的自定義標題欄View將加入FrameLayout中。

  (21)為內容欄顯示介面。就是setContentView()方法載入的佈局介面,加入其中。 

有了上面的DecorVIew知識背景,現在就來說說 怎麼新增蒙層View和將自定義側滑View新增到Activity的DecorView中,首先把蒙層View新增到

(31)customView中去,然後將自定義側滑View新增到 (21)FrameLayout中去,至於為什麼要這樣,是因為考慮到自定義側滑View不一定是寬度為螢幕寬度,所以才這麼做,而且也方面處理有無標題欄,有無採用沉浸式狀態列設計等情況。

二、自定義側滑View的實現

根據上面的概述,大家應該知道大概的思路了,下面我就給出自定義側滑View類的核心程式碼:

1、自定義側滑View用到的變數:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

//側滑方向-從哪側滑出

public static enum Positon {

LEFT, RIGHT

}

private Context mContext;

private Activity mActivity;

private Scroller mScroller = null;

//側滑選單佈局View

private View mMenuView;

//底部蒙層View

private View mMaskView;

private int mMenuWidth = 0;

//螢幕寬度

private int mScreenWidth = 0;

//是否在滑動中

private boolean mIsMoving = false;

//顯示登入介面與否

private boolean mShow = false;

//滑動動畫時間

private int mDuration = 600;

//預設側滑方向為左

private Positon mPositon = Positon.LEFT;

2、初始化建立自定義側滑View:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

**

* 建立側滑選單View

*/

public static XCSlideView create(Activity activity) {

XCSlideView view = new XCSlideView(activity);

return view;

}

/**

* 建立側滑選單View

*/

public static XCSlideView create(Activity activity, Positon positon) {

XCSlideView view = new XCSlideView(activity);

view.mPositon = positon;

return view;

}

3、建立半透明蒙層View,並新增到contentView中去

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

* 建立 蒙層View並新增到contentView中

*/

private void attachToContentView(Activity activity, Positon positon) {

mPositon = positon;

ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(android.R.id.content);

ViewGroup contentView = ((ViewGroup) contentFrameLayout.getChildAt(0));

mMaskView = new View(activity);

mMaskView.setBackgroundColor(mContext.getResources().getColor(R.color.mask_color));

contentView.addView(mMaskView, contentView.getLayoutParams());

mMaskView.setVisibility(View.GONE);

mMaskView.setClickable(true);

mMaskView.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View view) {

if (isShow()) {

dismiss();

}

}

});

}

4、設定側滑選單View,並新增到DectorView->LinearLayout->內容顯示區域View(FrameLayout)中

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

/**

* 設定側滑選單View,並新增到DectorView->LinearLayout->內容顯示區域View中

*/

public void setMenuView(Activity activity, View view) {

mActivity = activity;

mMenuView = view;

LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

addView(mMenuView, params);

mMenuView.post(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

mMenuWidth = mMenuView.getWidth();

switch (mPositon) {

case LEFT:

XCSlideView.this.scrollTo(mScreenWidth, 0);

break;

case RIGHT:

XCSlideView.this.scrollTo(-mScreenWidth, 0);

break;

}

}

});

ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(android.R.id.content);

ViewGroup contentView = contentFrameLayout;

contentView.addView(this);

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) this.getLayoutParams();

switch (mPositon) {

case LEFT:

layoutParams.gravity = Gravity.LEFT;

layoutParams.leftMargin = 0;

break;

case RIGHT:

layoutParams.gravity = Gravity.RIGHT;

layoutParams.rightMargin = 0;

break;

}

TextView titleFrameLayout = (TextView) activity.findViewById(android.R.id.title);

if( titleFrameLayout != null){

layoutParams.topMargin = DensityUtil.getStatusBarHeight(mContext);

}

int flags = mActivity.getWindow().getAttributes().flags;

int flag = (flags & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

if(flag == WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS){

//說明狀態列使用沉浸式

layoutParams.topMargin = DensityUtil.getStatusBarHeight(mContext);

}

this.setLayoutParams(layoutParams);

}

5、處理自定義側滑View的側滑滑動和隱藏效果:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

/**

* 顯示側滑選單View

*/

public void show(){

if(isShow() && !mIsMoving)

return;

switch (mPositon) {

case LEFT:

startScroll(mMenuWidth, -mMenuWidth, mDuration);

break;

case RIGHT:

startScroll(-mMenuWidth, mMenuWidth, mDuration);

break;

}

switchMaskView(true);

mShow = true;

}

/**

* 蒙層顯示開關

*/

private void switchMaskView(boolean bShow){

if(bShow){

mMaskView.setVisibility(View.VISIBLE);

Animation animation = new AlphaAnimation(0.0f, 1.0f);

animation.setDuration(mDuration);

mMaskView.startAnimation(animation);

}else{

mMaskView.setVisibility(View.GONE);

}

}

/**

* 關閉側滑選單View

*/

public void dismiss() {

// TODO Auto-generated method stub

if(!isShow() && !mIsMoving)

return;

switch (mPositon) {

case LEFT:

startScroll(XCSlideView.this.getScrollX(), mMenuWidth, mDuration);

break;

case RIGHT:

startScroll(XCSlideView.this.getScrollX(), -mMenuWidth, mDuration);

break;

}

switchMaskView(false);

mShow = false;

}

public boolean isShow(){

return mShow;

}

@Override

public void computeScroll() {

// TODO Auto-generated method stub

if (mScroller.computeScrollOffset()) {

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

// 更新介面

postInvalidate();

mIsMoving = true;

} else {

mIsMoving = false;

}

super.computeScroll();

}

/**

* 拖動移動

*/

public void startScroll(int startX, int dx,int duration){

mIsMoving = true;

mScroller.startScroll(startX,0,dx,0,duration);

invalidate();

}

三、如何使用該自定義側滑View控制元件

使用起來,比較簡單,通過create方法建立一個側滑VIew,然後通過setMenuView方法設定一個側滑View進去,有需要設定寬度的話, 通過setMenuWidth方法來設定即可,最後用show()方法滑出來就可以啦,使用起來是不是很方便?

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

private XCSlideView mSlideViewLeft;

//螢幕寬度

private int mScreenWidth = 0;

View menuViewLeft = LayoutInflater.from(mContext).inflate(R.layout.layout_slideview,null);

mSlideViewLeft = XCSlideView.create(this, XCSlideView.Positon.LEFT);

mSlideViewLeft.setMenuView(MainActivity.this, menuViewLeft);

mSlideViewLeft.setMenuWidth(mScreenWidth * 7 / 9);

Button left = (Button)findViewById(R.id.btn_left);

left.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

if (!mSlideViewLeft.isShow())

mSlideViewLeft.show();

}

});