首先,一个按钮要实现悬浮,就要用到系统顶级窗口相关的WindowManager,WindowManager.LayoutParams。那么在AndroidManifest.xml中添加权限:
1
|
< uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" /> |
然后,我们要对WindowManager,WindowManager.LayoutParams的相关属性进行下设置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
private WindowManager wm= null ; private WindowManager.LayoutParams wmParams= null ; private void initFloatView(){ //获取WindowManager wm=(WindowManager)getApplicationContext().getSystemService( "window" ); //设置LayoutParams(全局变量)相关参数 wmParams = new WindowManager.LayoutParams(); wmParams.type=LayoutParams.TYPE_PHONE; //设置window type wmParams.format=PixelFormat.RGBA_8888; //设置图片格式,效果为背景透明 //设置Window flag wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE; //以屏幕左上角为原点,设置x、y初始值 wmParams.x= 0 ; wmParams.y= 0 ; //设置悬浮窗口长宽数据 wmParams.width= 50 ; wmParams.height= 50 ; } |
通过WindowManager的addView方法创建的View可以实现悬浮窗口效果!因此,我们需要为屏幕创建2个悬浮按钮了。
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
|
/** * 创建左边悬浮按钮 */ private void createLeftFloatView(){ leftbtn= new ImageView( this ); leftbtn.setImageResource(R.drawable.prev); leftbtn.setAlpha( 0 ); leftbtn.setOnClickListener( new View.OnClickListener() { public void onClick(View arg0) { //上一篇 } }); //调整悬浮窗口 wmParams.gravity=Gravity.LEFT|Gravity.CENTER_VERTICAL; //显示myFloatView图像 wm.addView(leftbtn, wmParams); } /** * 创建右边悬浮按钮 */ private void createRightFloatView(){ rightbtn= new ImageView( this ); rightbtn.setImageResource(R.drawable.next); rightbtn.setAlpha( 0 ); rightbtn.setOnClickListener( new View.OnClickListener() { public void onClick(View arg0) { //下一篇 } }); //调整悬浮窗口 wmParams.gravity=Gravity.RIGHT|Gravity.CENTER_VERTICAL; //显示myFloatView图像 wm.addView(rightbtn, wmParams); } |
我把图片的Alpha值设置为0,是因为不想让悬浮按钮一开始就展现出来;我想通过对屏幕的触摸来实现悬浮按钮的渐变显示和渐变隐藏。那么我们还要对图片的渐变效果进行下处理:
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
|
// ImageView的alpha值 private int mAlpha = 0 ; private boolean isHide; /** * 图片渐变显示处理 */ private Handler mHandler = new Handler() { public void handleMessage(Message msg) { if (msg.what== 1 && mAlpha< 255 ){ //System.out.println("---"+mAlpha); mAlpha += 50 ; if (mAlpha> 255 ) mAlpha= 255 ; leftbtn.setAlpha(mAlpha); leftbtn.invalidate(); rightbtn.setAlpha(mAlpha); rightbtn.invalidate(); if (!isHide && mAlpha< 255 ) mHandler.sendEmptyMessageDelayed( 1 , 100 ); } else if (msg.what== 0 && mAlpha> 0 ){ //System.out.println("---"+mAlpha); mAlpha -= 10 ; if (mAlpha< 0 ) mAlpha= 0 ; leftbtn.setAlpha(mAlpha); leftbtn.invalidate(); rightbtn.setAlpha(mAlpha); rightbtn.invalidate(); if (isHide && mAlpha> 0 ) mHandler.sendEmptyMessageDelayed( 0 , 100 ); } } }; |
我们再用2个方法分别来控制悬浮按钮的显示、隐藏:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
private void showFloatView(){ isHide = false ; mHandler.sendEmptyMessage( 1 ); } private void hideFloatView(){ new Thread(){ public void run() { try { Thread.sleep( 1500 ); isHide = true ; mHandler.sendEmptyMessage( 0 ); } catch (Exception e) { ; } } }.start(); } |
这里为了不让悬浮按钮显示后,马上就开始隐藏。我使用了一个线程,先暂停1.5秒钟,再开始渐变隐藏。
接下来,我要重写Activity的onTouchEvent触屏事件,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_DOWN: //System.out.println("========ACTION_DOWN"); showFloatView(); break ; case MotionEvent.ACTION_UP: //System.out.println("========ACTION_UP"); hideFloatView(); break ; } return true ; } |
最后,要在Activity销毁时销毁悬浮按钮,不然悬浮按钮会一直悬浮在那。因此,我们要再重写Activity的onDestroy()方法,并调用WindowManager的removeView()方法来移除悬浮按钮。
1
2
3
4
5
6
7
|
@Override public void onDestroy(){ super .onDestroy(); //在程序退出(Activity销毁)时销毁悬浮窗口 wm.removeView(leftbtn); wm.removeView(rightbtn); } |
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
package com.liux.pageflipper; import android.app.Activity; import android.graphics.PixelFormat; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.ImageView; import android.widget.ViewFlipper; /** * 悬浮按钮实现翻篇效果 * <a href="http://my.oschina.net/arthor" target="_blank" rel="nofollow">@author</a> liux http://my.oschina.net/liux * @date 2012-2-10 下午2:48:52 */ public class PageFlipperActivity extends Activity{ private WindowManager wm= null ; private WindowManager.LayoutParams wmParams= null ; private ImageView leftbtn= null ; private ImageView rightbtn= null ; // ImageView的alpha值 private int mAlpha = 0 ; private boolean isHide; private ViewFlipper viewFlipper = null ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); viewFlipper = (ViewFlipper) this .findViewById(R.id.myViewFlipper); //初始化悬浮按钮 initFloatView(); } /** * 初始化悬浮按钮 */ private void initFloatView(){ //获取WindowManager wm=(WindowManager)getApplicationContext().getSystemService( "window" ); //设置LayoutParams(全局变量)相关参数 wmParams = new WindowManager.LayoutParams(); wmParams.type=LayoutParams.TYPE_PHONE; //设置window type wmParams.format=PixelFormat.RGBA_8888; //设置图片格式,效果为背景透明 //设置Window flag wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE; //以屏幕左上角为原点,设置x、y初始值 wmParams.x= 0 ; wmParams.y= 0 ; //设置悬浮窗口长宽数据 wmParams.width= 50 ; wmParams.height= 50 ; //创建悬浮按钮 createLeftFloatView(); createRightFloatView(); } /** * 创建左边悬浮按钮 */ private void createLeftFloatView(){ leftbtn= new ImageView( this ); leftbtn.setImageResource(R.drawable.prev); leftbtn.setAlpha( 0 ); leftbtn.setOnClickListener( new View.OnClickListener() { public void onClick(View arg0) { //上一篇 viewFlipper.setInAnimation(PageFlipperActivity. this , R.anim.in_leftright); viewFlipper.setOutAnimation(PageFlipperActivity. this , R.anim.out_leftright); viewFlipper.showPrevious(); } }); //调整悬浮窗口 wmParams.gravity=Gravity.LEFT|Gravity.CENTER_VERTICAL; //显示myFloatView图像 wm.addView(leftbtn, wmParams); } /** * 创建右边悬浮按钮 */ private void createRightFloatView(){ rightbtn= new ImageView( this ); rightbtn.setImageResource(R.drawable.next); rightbtn.setAlpha( 0 ); rightbtn.setOnClickListener( new View.OnClickListener() { public void onClick(View arg0) { //下一篇 viewFlipper.setInAnimation(PageFlipperActivity. this , R.anim.in_rightleft); viewFlipper.setOutAnimation(PageFlipperActivity. this , R.anim.out_rightleft); viewFlipper.showNext(); } }); //调整悬浮窗口 wmParams.gravity=Gravity.RIGHT|Gravity.CENTER_VERTICAL; //显示myFloatView图像 wm.addView(rightbtn, wmParams); } /** * 图片渐变显示处理 */ private Handler mHandler = new Handler() { public void handleMessage(Message msg) { if (msg.what== 1 && mAlpha< 255 ){ //System.out.println("---"+mAlpha); mAlpha += 50 ; if (mAlpha> 255 ) mAlpha= 255 ; leftbtn.setAlpha(mAlpha); leftbtn.invalidate(); rightbtn.setAlpha(mAlpha); rightbtn.invalidate(); if (!isHide && mAlpha< 255 ) mHandler.sendEmptyMessageDelayed( 1 , 100 ); } else if (msg.what== 0 && mAlpha> 0 ){ //System.out.println("---"+mAlpha); mAlpha -= 10 ; if (mAlpha< 0 ) mAlpha= 0 ; leftbtn.setAlpha(mAlpha); leftbtn.invalidate(); rightbtn.setAlpha(mAlpha); rightbtn.invalidate(); if (isHide && mAlpha> 0 ) mHandler.sendEmptyMessageDelayed( 0 , 100 ); } } }; private void showFloatView(){ isHide = false ; mHandler.sendEmptyMessage( 1 ); } private void hideFloatView(){ new Thread(){ public void run() { try { Thread.sleep( 1500 ); isHide = true ; mHandler.sendEmptyMessage( 0 ); } catch (Exception e) { ; } } }.start(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_DOWN: //System.out.println("========ACTION_DOWN"); showFloatView(); break ; case MotionEvent.ACTION_UP: //System.out.println("========ACTION_UP"); hideFloatView(); break ; } return true ; } @Override public void onDestroy(){ super .onDestroy(); //在程序退出(Activity销毁)时销毁悬浮窗口 wm.removeView(leftbtn); wm.removeView(rightbtn); } } |