Android提高之多方向抽屉实现方法

时间:2021-08-25 08:09:46

说起在android上要实现类似launch的抽屉效果,大家一定首先会想起slidingdrawer。slidingdrawer是android官方控件之一,但是本文的主角并不是它,而是民间的控件工具集合:android-misc-widgets。android-misc-widgets里面包含几个widget:panel、smoothbutton、switcher、virtualkeyboard,还有一些动画特效,本文主要介绍抽屉容器panel的用法。android-misc-widgets的google工程地址:-widgets/http://code.google.com/p/android-misc。

工程代码中panel的演示效果如下所示:

Android提高之多方向抽屉实现方法

这个panel控件可以轻易实现不同方向的抽屉效果,比slidingdrawer有更强的扩展性!

在多次使用panel的过程中,发现panel有个bug,会间断性出现“闪烁”,也就是在ontouchlistener里面的触发action_down后,抽屉瞬间弹出然后瞬间回收(版本日期为feb 3, 2009)。把原panel的ontouchlistener加以替换,即以下代码:

?
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
ontouchlistener touchlistener = new ontouchlistener() {
 int initx;
 int inity;
 boolean setinitialposition;
 public boolean ontouch(view v, motionevent event) {
 if (mstate == state.animating) {
  // we are animating
  return false;
 }
//  log.d(tag, "state: " + mstate + " x: " + event.getx() + " y: " + event.gety());
 int action = event.getaction();
 if (action == motionevent.action_down) {
  if (mbringtofront) {
  bringtofront();
  }
  initx = 0;
  inity = 0;
  if (mcontent.getvisibility() == gone) {
  // since we may not know content dimensions we use factors here
  if (morientation == vertical) {
   inity = mposition == top? -1 : 1;
  } else {
   initx = mposition == left? -1 : 1;
  }
  }
  setinitialposition = true;
 } else {
  if (setinitialposition) {
  // now we know content dimensions, so we multiply factors...
  initx *= mcontentwidth;
  inity *= mcontentheight;
  // ... and set initial panel's position
  mgesturelistener.setscroll(initx, inity);
  setinitialposition = false;
  // for offsetlocation we have to invert values
  initx = -initx;
  inity = -inity;
  }
  // offset every action_move & action_up event
  event.offsetlocation(initx, inity);
 }
 if (!mgesturedetector.ontouchevent(event)) {
  if (action == motionevent.action_up) {
  // tup up after scrolling
  post(startanimation);
  }
 }
 return false;
 }
};

替换为:

?
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
ontouchlistener touchlistener = new ontouchlistener() {
 float touchx, touchy;
 public boolean ontouch(view v, motionevent event) {
 if (mstate == state.animating) {
  // we are animating
  return false;
 }
 int action = event.getaction();
 if (action == motionevent.action_down) {
  if (mbringtofront) {
  bringtofront();
  }
  touchx = event.getx();
  touchy = event.gety();
 }
 if (!mgesturedetector.ontouchevent(event)) {
  if (action == motionevent.action_up) {
  // tup up after scrolling
  int size = (int) (math.abs(touchx - event.getx()) + math
   .abs(touchy - event.gety()));
  if (size == mcontentwidth || size == mcontentheight) {
   mstate = state.about_to_animate;
   //log.e("size", string.valueof(size));
   //log.e(string.valueof(mcontentwidth),string.valueof(mcontentheight));
  }
  post(startanimation);
  }
 }
 return false;
 }
};

即可修复这个bug,并且也同样实现了onclicklistener的功能,可以把原panel的onclicklistener给删掉了!

希望本文所述实例对于大家进行android项目开发能有所帮助。