悬浮窗的实现(如360悬浮窗效果)for android

相信大家,都知晓360的悬浮窗口,非常潇洒。。。
如图:

现在,我也实现了具有吸附效果的悬浮窗。有图有真相...
看图: 吸附屏幕两侧的效果
废话少说,看代码。代码中,有详细注释...
布局文件:floating.xml(悬浮窗的布局)
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="wrap_content"
  4.     android:layout_height="wrap_content"
  5.     tools:context=".MainActivity" 
  6.     android:orientation="horizontal"
  7.     >

  8.     <ImageView 
  9.         android:id="@+id/icon"
  10.         android:layout_width="wrap_content"
  11.         android:layout_height="wrap_content"
  12.         android:background="@drawable/rekoo"
  13.         />
  14.     
  15.     <LinearLayout 
  16.         android:id="@+id/floats"
  17.         android:layout_width="wrap_content"
  18.         android:layout_height="wrap_content"
  19.         android:orientation="horizontal"
  20.         android:background="@drawable/settings_bg_right"
  21.         android:layout_marginTop="2dp"
  22.         android:visibility="gone"
  23.         >

  24.         <LinearLayout
  25.             android:id="@+id/btn1"
  26.             android:layout_width="wrap_content"
  27.             android:layout_height="wrap_content"
  28.             android:orientation="vertical" 
  29.             android:layout_marginLeft="2dp"
  30.             >
  31.             <ImageButton
  32.                 android:layout_width="wrap_content"
  33.                 android:layout_height="wrap_content"
  34.                 android:background="@drawable/settings_bbs_pressed" />
  35.             <TextView 
  36.                 android:layout_width="wrap_content"
  37.                 android:layout_height="wrap_content"
  38.                 android:text="论坛"
  39.                 android:textColor="@android:color/white"
  40.                 />
  41.         </LinearLayout>

  42.         <LinearLayout
  43.             android:id="@+id/btn2"
  44.             android:layout_width="wrap_content"
  45.             android:layout_height="wrap_content"
  46.             android:layout_marginLeft="10dp"
  47.             android:orientation="vertical" >

  48.             <ImageButton
  49.                 android:layout_width="wrap_content"
  50.                 android:layout_height="wrap_content"
  51.                 android:background="@drawable/settings_bind_phone_pressed" />

  52.             <TextView
  53.                 android:layout_width="wrap_content"
  54.                 android:layout_height="wrap_content"
  55.                 android:text="电话"
  56.                 android:textColor="@android:color/white" />
  57.         </LinearLayout>
  58.        
  59.         <LinearLayout
  60.             android:id="@+id/btn3"
  61.             android:layout_width="wrap_content"
  62.             android:layout_height="wrap_content"
  63.             android:layout_marginLeft="10dp"
  64.             android:orientation="vertical" >
  65.             <ImageButton
  66.                 android:layout_width="wrap_content"
  67.                 android:layout_height="wrap_content"
  68.                 android:background="@drawable/settings_service_pressed" />

  69.             <TextView
  70.                 android:layout_width="wrap_content"
  71.                 android:layout_height="wrap_content"
  72.                 android:text="关闭"
  73.                 android:textColor="@android:color/white" />
  74.         </LinearLayout>
  75.         
  76.     </LinearLayout>

  77. </LinearLayout>
复制代码
源码:
  1. package org.lqh.floatDemo;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.PixelFormat;
  5. import android.graphics.Rect;
  6. import android.os.Bundle;
  7. import android.view.Display;
  8. import android.view.Gravity;
  9. import android.view.LayoutInflater;
  10. import android.view.MotionEvent;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.view.Window;
  14. import android.view.WindowManager;
  15. import android.view.WindowManager.LayoutParams;
  16. import android.widget.ImageView;
  17. import android.widget.LinearLayout;
  18. import android.widget.Toast;

  19. public class MainActivity extends Activity implements OnClickListener
  20. {
  21.     private WindowManager windowManager = null; 
  22.     private WindowManager.LayoutParams windowManagerParams = null; 

  23.     private float mTouchX; 
  24.     private float mTouchY; 
  25.     private float x; 
  26.     private float y; 
  27.     private float mStartX; 
  28.     private float mStartY; 
  29.     
  30.     private View view;
  31.     private ImageView icon;
  32.     private LinearLayout floats;
  33.     private LinearLayout btn1;
  34.     private LinearLayout btn2;
  35.     private LinearLayout btn3;
  36.     @Override
  37.     public void onCreate(Bundle savedInstanceState) { 
  38.         super.onCreate(savedInstanceState); 
  39.         requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏 
  40.         getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN , 
  41.                 WindowManager.LayoutParams. FLAG_FULLSCREEN);//全屏 
  42.         setContentView(R.layout.activity_main); 
  43.         
  44.         view = LayoutInflater.from(this).inflate(R.layout.floating, null);
  45.         icon = (ImageView) view.findViewById(R.id.icon);
  46.         floats = (LinearLayout) view.findViewById(R.id.floats);
  47.         btn1 = (LinearLayout) floats.findViewById(R.id.btn1);
  48.         btn2 = (LinearLayout) floats.findViewById(R.id.btn2);
  49.         btn3 = (LinearLayout) floats.findViewById(R.id.btn3);
  50.         btn1.setOnClickListener(this);
  51.         btn2.setOnClickListener(this);
  52.         btn3.setOnClickListener(this);
  53.         createView();  
  54.     } 

  55.     private void createView() { 
  56.         
  57.         // 1、获取WindowManager对象 
  58.         windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); 
  59.         // 2、设置LayoutParams(全局变量)相关参数 
  60.         windowManagerParams = new WindowManager.LayoutParams();
  61. //        windowManagerParams = ((FloatApplication) getApplication()).getWindowParams(); 
  62.         //3、设置相关的窗口布局参数 (悬浮窗口效果)
  63.         windowManagerParams.type = LayoutParams.TYPE_PHONE; // 设置window type 
  64.         windowManagerParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明 
  65.         //4、设置Window flag == 不影响后面的事件  和  不可聚焦
  66.         windowManagerParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL 
  67.                 | LayoutParams.FLAG_NOT_FOCUSABLE; 
  68.         /* 
  69.          * 注意,flag的值可以为: 
  70.          * LayoutParams.FLAG_NOT_TOUCH_MODAL 不影响后面的事件 
  71.          * LayoutParams.FLAG_NOT_FOCUSABLE  不可聚焦 
  72.          * LayoutParams.FLAG_NOT_TOUCHABLE 不可触摸 
  73.          */
  74.         //5、 调整悬浮窗口至左上角,便于调整坐标 
  75.         windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP;  
  76.         // 以屏幕左上角为原点,设置x、y初始值 
  77.         windowManagerParams.x = 0; 
  78.         windowManagerParams.y = 80; 
  79.         //6、设置悬浮窗口长宽数据 
  80.         windowManagerParams.width = LayoutParams.WRAP_CONTENT; 
  81.         windowManagerParams.height = LayoutParams.WRAP_CONTENT; 
  82.         
  83.         //获得屏幕的宽高
  84.                 Display display = windowManager.getDefaultDisplay();
  85.                 final int screenWith = display.getWidth();
  86.                 int screenHeight = display.getHeight();
  87.                 System.out.println("screenWith="+screenWith+",screenHeight="+screenHeight);
  88.         
  89.         icon.setOnTouchListener(new View.OnTouchListener()
  90.         {
  91.             @Override
  92.             public boolean onTouch(View v, MotionEvent event)
  93.             {
  94.                 //1、获取到状态栏的高度 
  95.                 Rect frame =  new  Rect();   
  96.                 icon.getWindowVisibleDisplayFrame(frame); 
  97.                 int  statusBarHeight = frame.top; 
  98.                 System.out.println("状态栏高度:"+statusBarHeight); 
  99.                 //2、获取相对屏幕的坐标,即以屏幕左上角为原点 。y轴坐标= y(获取到屏幕原点的距离)-状态栏的高度
  100.                 x = event.getRawX(); 
  101.                 y = event.getRawY() - statusBarHeight; // statusBarHeight是系统状态栏的高度 
  102.                 
  103.                 System.out.println("x="+x+",y="+y);
  104.                 //3、处理触摸移动
  105.                 switch (event.getAction()) { 
  106.                 case MotionEvent.ACTION_DOWN: // 捕获手指触摸按下动作 
  107.                         // 获取相对View的坐标,即以此View左上角为原点 
  108.                         mTouchX = event.getX(); 
  109.                         mTouchY = event.getY(); 
  110.                         mStartX = x; 
  111.                         mStartY = y; 
  112.                         
  113.                         System.out.println(",mTouchX=" + mTouchX + ",mTouchY="
  114.                                         + mTouchY);
  115.                         break; 

  116.                 case MotionEvent.ACTION_MOVE: // 捕获手指触摸移动动作 
  117.                         updateViewPosition(); 
  118.                         break; 

  119.                 case MotionEvent.ACTION_UP: // 捕获手指触摸离开动作 
  120.                     float left = x-mTouchX;   
  121.                     if(left <= screenWith/2){//图标icon吸附在左边
  122.                            x = mTouchX;
  123.                        }else {//图标icon吸附在右边
  124.                         x = mTouchX + screenWith;
  125.                     }
  126.                         
  127.                         updateViewPosition(); 
  128.                         //移动终点的坐标,重置为0
  129.                         mTouchX = mTouchY = 0; 
  130.                         //移动距离少于5 ,则视为点击,触发点击的回调
  131.                         if ((x - mStartX) < 5 && (y - mStartY) < 5) { 
  132.                                 onClick(v); 
  133.                         }
  134.                         break; 
  135.                 } 
  136.                 return true; 
  137.             }
  138.         });
  139.         
  140.         windowManager.addView(view, windowManagerParams); // 显示myFloatView图像 
  141.     } 

  142.     /**
  143.      * 用于更新 悬浮窗位置参数
  144.      * */
  145.     private void updateViewPosition() { 
  146.             windowManagerParams.x = (int) (x - mTouchX); 
  147.             windowManagerParams.y = (int) (y - mTouchY); 
  148.             
  149.             System.out.println("wp.x="+windowManagerParams.x+",wp.y="+windowManagerParams.y);
  150.             // 刷新屏幕显示 
  151.             windowManager.updateViewLayout(view, windowManagerParams); 
  152.     } 

  153.     @Override
  154.     public void onClick(View v)
  155.     {
  156.         switch (v.getId())
  157.         {
  158.         case R.id.icon:
  159.             if (floats.getVisibility() == View.VISIBLE)
  160.             {
  161.                 floats.setVisibility(View.GONE);
  162.             } else {
  163.                 floats.setVisibility(View.VISIBLE);
  164.             }
  165.             break;
  166.         case R.id.btn1:
  167.             Toast.makeText(this,"亲,我是论坛!", 2).show();
  168.             break;
  169.         case R.id.btn2:
  170.             Toast.makeText(this,"亲,我是手机验证!", 2).show();
  171.             break;
  172.         case R.id.btn3:
  173.             windowManager.removeView(view); 
  174.             android.os.Process.killProcess(android.os.Process.myPid());
  175.             break;
  176.         default:
  177.             break;
  178.         }
  179.         
  180.     } 
  181.     
  182.     public void onDestroy() { 
  183.         super.onDestroy(); 
  184.         // 在程序退出(Activity销毁)时销毁悬浮窗口 
  185. //        windowManager.removeView(view); 
  186.     } 
  187.     
  188.     

  189. }
复制代码
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值