原文地址 http://www.open-open.com/lib/view/open1328883424280.html
今天给大家分享下自己用悬浮按钮点击实现翻页效果的例子。
首先,一个按钮要实现悬浮,就要用到系统顶级窗口相关的WindowManager,WindowManager.LayoutParams。那么在AndroidManifest.xml中添加权限:
1 |
< uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" /> |
然后,我们要对WindowManager,WindowManager.LayoutParams的相关属性进行下设置:
01 |
private WindowManager wm= null ; |
02 |
private WindowManager.LayoutParams wmParams= null ; |
03 |
04 |
private void initFloatView(){ |
05 |
//获取WindowManager |
06 |
wm=(WindowManager)getApplicationContext().getSystemService( "window" ); |
07 |
//设置LayoutParams(全局变量)相关参数 |
08 |
wmParams = new WindowManager.LayoutParams(); |
09 |
|
10 |
wmParams.type=LayoutParams.TYPE_PHONE; //设置window type |
11 |
wmParams.format=PixelFormat.RGBA_8888; //设置图片格式,效果为背景透明 |
12 |
//设置Window flag |
13 |
wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
14 |
| LayoutParams.FLAG_NOT_FOCUSABLE; |
15 |
16 |
//以屏幕左上角为原点,设置x、y初始值 |
17 |
wmParams.x= 0 ; |
18 |
wmParams.y= 0 ; |
19 |
//设置悬浮窗口长宽数据 |
20 |
wmParams.width= 50 ; |
21 |
wmParams.height= 50 ; |
22 |
} |
通过WindowManager的addView方法创建的View可以实现悬浮窗口效果!因此,我们需要为屏幕创建2个悬浮按钮了。
01 |
/** |
02 |
* 创建左边悬浮按钮 |
03 |
*/ |
04 |
private void createLeftFloatView(){ |
05 |
leftbtn= new ImageView( this ); |
06 |
leftbtn.setImageResource(R.drawable.prev); |
07 |
leftbtn.setAlpha( 0 ); |
08 |
leftbtn.setOnClickListener( new View.OnClickListener() { |
09 |
public void onClick(View arg0) { |
10 |
//上一篇 |
11 |
} |
12 |
}); |
13 |
//调整悬浮窗口 |
14 |
wmParams.gravity=Gravity.LEFT|Gravity.CENTER_VERTICAL; |
15 |
//显示myFloatView图像 |
16 |
wm.addView(leftbtn, wmParams); |
17 |
} |
18 |
/** |
19 |
* 创建右边悬浮按钮 |
20 |
*/ |
21 |
private void createRightFloatView(){ |
22 |
rightbtn= new ImageView( this ); |
23 |
rightbtn.setImageResource(R.drawable.next); |
24 |
rightbtn.setAlpha( 0 ); |
25 |
rightbtn.setOnClickListener( new View.OnClickListener() { |
26 |
public void onClick(View arg0) { |
27 |
//下一篇 |
28 |
} |
29 |
}); |
30 |
//调整悬浮窗口 |
31 |
wmParams.gravity=Gravity.RIGHT|Gravity.CENTER_VERTICAL; |
32 |
//显示myFloatView图像 |
33 |
wm.addView(rightbtn, wmParams); |
34 |
} |
我把图片的Alpha值设置为0,是因为不想让悬浮按钮一开始就展现出来;我想通过对屏幕的触摸来实现悬浮按钮的渐变显示和渐变隐藏。那么我们还要对图片的渐变效果进行下处理:
01 |
// ImageView的alpha值 |
02 |
private int mAlpha = 0 ; |
03 |
private boolean isHide; |
04 |
/** |
05 |
* 图片渐变显示处理 |
06 |
*/ |
07 |
private Handler mHandler = new Handler() |
08 |
{ |
09 |
public void handleMessage(Message msg) { |
10 |
if (msg.what== 1 && mAlpha< 255 ){ |
11 |
//System.out.println("---"+mAlpha); |
12 |
mAlpha += 50 ; |
13 |
if (mAlpha> 255 ) |
14 |
mAlpha= 255 ; |
15 |
leftbtn.setAlpha(mAlpha); |
16 |
leftbtn.invalidate(); |
17 |
rightbtn.setAlpha(mAlpha); |
18 |
rightbtn.invalidate(); |
19 |
if (!isHide && mAlpha< 255 ) |
20 |
mHandler.sendEmptyMessageDelayed( 1 , 100 ); |
21 |
} else if (msg.what== 0 && mAlpha> 0 ){ |
22 |
//System.out.println("---"+mAlpha); |
23 |
mAlpha -= 10 ; |
24 |
if (mAlpha< 0 ) |
25 |
mAlpha= 0 ; |
26 |
leftbtn.setAlpha(mAlpha); |
27 |
leftbtn.invalidate(); |
28 |
rightbtn.setAlpha(mAlpha); |
29 |
rightbtn.invalidate(); |
30 |
if (isHide && mAlpha> 0 ) |
31 |
mHandler.sendEmptyMessageDelayed( 0 , 100 ); |
32 |
} |
33 |
} |
34 |
35 |
}; |
我们再用2个方法分别来控制悬浮按钮的显示、隐藏:
01 |
private void showFloatView(){ |
02 |
isHide = false ; |
03 |
mHandler.sendEmptyMessage( 1 ); |
04 |
} |
05 |
06 |
private void hideFloatView(){ |
07 |
new Thread(){ |
08 |
public void run() { |
09 |
try { |
10 |
Thread.sleep( 1500 ); |
11 |
isHide = true ; |
12 |
mHandler.sendEmptyMessage( 0 ); |
13 |
} catch (Exception e) { |
14 |
; |
15 |
} |
16 |
} |
17 |
}.start(); |
18 |
} |
这里为了不让悬浮按钮显示后,马上就开始隐藏。我使用了一个线程,先暂停1.5秒钟,再开始渐变隐藏。
接下来,我要重写Activity的onTouchEvent触屏事件,代码如下:
01 |
@Override |
02 |
03 |
public boolean onTouchEvent(MotionEvent event) { |
04 |
switch (event.getAction()) { |
05 |
case MotionEvent.ACTION_MOVE: |
06 |
case MotionEvent.ACTION_DOWN: |
07 |
//System.out.println("========ACTION_DOWN"); |
08 |
showFloatView(); |
09 |
break ; |
10 |
case MotionEvent.ACTION_UP: |
11 |
//System.out.println("========ACTION_UP"); |
12 |
hideFloatView(); |
13 |
break ; |
14 |
} |
15 |
return true ; |
16 |
} |
最后,要在Activity销毁时销毁悬浮按钮,不然悬浮按钮会一直悬浮在那。因此,我们要再重写Activity的onDestroy()方法,并调用WindowManager的removeView()方法来移除悬浮按钮。
1 |
@Override |
2 |
public void onDestroy(){ |
3 |
super .onDestroy(); |
4 |
//在程序退出(Activity销毁)时销毁悬浮窗口 |
5 |
wm.removeView(leftbtn); |
6 |
wm.removeView(rightbtn); |
7 |
} |
给大家展示下效果图:
下面是程序的完整代码:
001 |
package com.liux.pageflipper; |
002 |
003 |
import android.app.Activity; |
004 |
import android.graphics.PixelFormat; |
005 |
import android.os.Bundle; |
006 |
import android.os.Handler; |
007 |
import android.os.Message; |
008 |
import android.view.Gravity; |
009 |
import android.view.MotionEvent; |
010 |
import android.view.View; |
011 |
import android.view.WindowManager; |
012 |
import android.view.WindowManager.LayoutParams; |
013 |
import android.widget.ImageView; |
014 |
import android.widget.ViewFlipper; |
015 |
/** |
016 |
* 悬浮按钮实现翻篇效果 |
017 |
* <a href="http://my.oschina.net/arthor" rel="nofollow" target="_blank">@author</a> liux http://my.oschina.net/liux |
018 |
* @date 2012-2-10 下午2:48:52 |
019 |
*/ |
020 |
public class PageFlipperActivity extends Activity{ |
021 |
|
022 |
private WindowManager wm= null ; |
023 |
private WindowManager.LayoutParams wmParams= null ; |
024 |
|
025 |
private ImageView leftbtn= null ; |
026 |
private ImageView rightbtn= null ; |
027 |
|
028 |
// ImageView的alpha值 |
029 |
private int mAlpha = 0 ; |
030 |
private boolean isHide; |
031 |
|
032 |
private ViewFlipper viewFlipper = null ; |
033 |
|
034 |
@Override |
035 |
public void onCreate(Bundle savedInstanceState) { |
036 |
super .onCreate(savedInstanceState); |
037 |
setContentView(R.layout.main); |
038 |
|
039 |
viewFlipper = (ViewFlipper) this .findViewById(R.id.myViewFlipper); |
040 |
|
041 |
//初始化悬浮按钮 |
042 |
initFloatView(); |
043 |
|
044 |
} |
045 |
/** |
046 |
* 初始化悬浮按钮 |
047 |
*/ |
048 |
private void initFloatView(){ |
049 |
//获取WindowManager |
050 |
wm=(WindowManager)getApplicationContext().getSystemService( "window" ); |
051 |
//设置LayoutParams(全局变量)相关参数 |
052 |
wmParams = new WindowManager.LayoutParams(); |
053 |
|
054 |
wmParams.type=LayoutParams.TYPE_PHONE; //设置window type |
055 |
wmParams.format=PixelFormat.RGBA_8888; //设置图片格式,效果为背景透明 |
056 |
//设置Window flag |
057 |
wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
058 |
| LayoutParams.FLAG_NOT_FOCUSABLE; |
059 |
060 |
//以屏幕左上角为原点,设置x、y初始值 |
061 |
wmParams.x= 0 ; |
062 |
wmParams.y= 0 ; |
063 |
//设置悬浮窗口长宽数据 |
064 |
wmParams.width= 50 ; |
065 |
wmParams.height= 50 ; |
066 |
|
067 |
//创建悬浮按钮 |
068 |
createLeftFloatView(); |
069 |
createRightFloatView(); |
070 |
071 |
} |
072 |
|
073 |
/** |
074 |
* 创建左边悬浮按钮 |
075 |
*/ |
076 |
private void createLeftFloatView(){ |
077 |
leftbtn= new ImageView( this ); |
078 |
leftbtn.setImageResource(R.drawable.prev); |
079 |
leftbtn.setAlpha( 0 ); |
080 |
leftbtn.setOnClickListener( new View.OnClickListener() { |
081 |
public void onClick(View arg0) { |
082 |
//上一篇 |
083 |
viewFlipper.setInAnimation(PageFlipperActivity. this , R.anim.in_leftright); |
084 |
viewFlipper.setOutAnimation(PageFlipperActivity. this , R.anim.out_leftright); |
085 |
viewFlipper.showPrevious(); |
086 |
} |
087 |
}); |
088 |
//调整悬浮窗口 |
089 |
wmParams.gravity=Gravity.LEFT|Gravity.CENTER_VERTICAL; |
090 |
//显示myFloatView图像 |
091 |
wm.addView(leftbtn, wmParams); |
092 |
} |
093 |
/** |
094 |
* 创建右边悬浮按钮 |
095 |
*/ |
096 |
private void createRightFloatView(){ |
097 |
rightbtn= new ImageView( this ); |
098 |
rightbtn.setImageResource(R.drawable.next); |
099 |
rightbtn.setAlpha( 0 ); |
100 |
rightbtn.setOnClickListener( new View.OnClickListener() { |
101 |
public void onClick(View arg0) { |
102 |
//下一篇 |
103 |
viewFlipper.setInAnimation(PageFlipperActivity. this , R.anim.in_rightleft); |
104 |
viewFlipper.setOutAnimation(PageFlipperActivity. this , R.anim.out_rightleft); |
105 |
viewFlipper.showNext(); |
106 |
} |
107 |
}); |
108 |
//调整悬浮窗口 |
109 |
wmParams.gravity=Gravity.RIGHT|Gravity.CENTER_VERTICAL; |
110 |
//显示myFloatView图像 |
111 |
wm.addView(rightbtn, wmParams); |
112 |
} |
113 |
/** |
114 |
* 图片渐变显示处理 |
115 |
*/ |
116 |
private Handler mHandler = new Handler() |
117 |
{ |
118 |
public void handleMessage(Message msg) { |
119 |
120 |
if (msg.what== 1 && mAlpha< 255 ){ |
121 |
//System.out.println("---"+mAlpha); |
122 |
mAlpha += 50 ; |
123 |
if (mAlpha> 255 ) |
124 |
mAlpha= 255 ; |
125 |
leftbtn.setAlpha(mAlpha); |
126 |
leftbtn.invalidate(); |
127 |
rightbtn.setAlpha(mAlpha); |
128 |
rightbtn.invalidate(); |
129 |
if (!isHide && mAlpha< 255 ) |
130 |
mHandler.sendEmptyMessageDelayed( 1 , 100 ); |
131 |
} else if (msg.what== 0 && mAlpha> 0 ){ |
132 |
//System.out.println("---"+mAlpha); |
133 |
mAlpha -= 10 ; |
134 |
if (mAlpha< 0 ) |
135 |
mAlpha= 0 ; |
136 |
leftbtn.setAlpha(mAlpha); |
137 |
leftbtn.invalidate(); |
138 |
rightbtn.setAlpha(mAlpha); |
139 |
rightbtn.invalidate(); |
140 |
if (isHide && mAlpha> 0 ) |
141 |
mHandler.sendEmptyMessageDelayed( 0 , 100 ); |
142 |
} |
143 |
} |
144 |
145 |
}; |
146 |
|
147 |
private void showFloatView(){ |
148 |
isHide = false ; |
149 |
mHandler.sendEmptyMessage( 1 ); |
150 |
} |
151 |
|
152 |
private void hideFloatView(){ |
153 |
new Thread(){ |
154 |
public void run() { |
155 |
try { |
156 |
Thread.sleep( 1500 ); |
157 |
isHide = true ; |
158 |
mHandler.sendEmptyMessage( 0 ); |
159 |
} catch (Exception e) { |
160 |
; |
161 |
} |
162 |
} |
163 |
}.start(); |
164 |
} |
165 |
|
166 |
@Override |
167 |
public boolean onTouchEvent(MotionEvent event) { |
168 |
switch (event.getAction()) { |
169 |
case MotionEvent.ACTION_MOVE: |
170 |
case MotionEvent.ACTION_DOWN: |
171 |
//System.out.println("========ACTION_DOWN"); |
172 |
showFloatView(); |
173 |
break ; |
174 |
case MotionEvent.ACTION_UP: |
175 |
//System.out.println("========ACTION_UP"); |
176 |
hideFloatView(); |
177 |
break ; |
178 |
} |
179 |
return true ; |
180 |
} |
181 |
182 |
@Override |
183 |
public void onDestroy(){ |
184 |
super .onDestroy(); |
185 |
//在程序退出(Activity销毁)时销毁悬浮窗口 |
186 |
wm.removeView(leftbtn); |
187 |
wm.removeView(rightbtn); |
188 |
} |
189 |
} |