您的位置:首页 > 移动开发 > Android开发

android浮动小窗口设计

2014-09-26 11:24 281 查看
1\//创建创建全局变量类

public class MyApplication extends Application {

    

    /**

     * 创建全局变量

     * 全局变量一般都比较倾向于创建一个单独的数据类文件,并使用static静态变量

     * 

     * 这里使用了在Application中添加数据的方法实现全局变量

     * 注意在AndroidManifest.xml中的Application节点添加android:name=".MyApplication"属性

     * 

     */

    private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();

    public WindowManager.LayoutParams getMywmParams(){

        return wmParams;

    }

2\//Activity类 

public class MyFloatViewActivity extends Activity {

   

    /** Called when the activity is first created. */

    

    private WindowManager wm=null;

    private WindowManager.LayoutParams wmParams=null;

    

    private MyFloatView myFV=null;

    

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    

    }

    

    private void createView(){

        myFV=new MyFloatView(getApplicationContext());

        myFV.setImageResource(R.drawable.icon);

        //获取WindowManager

        wm=(WindowManager)getApplicationContext().getSystemService("window");

        //设置LayoutParams(全局变量)相关参数

        wmParams = ((MyApplication)getApplication()).getMywmParams();

         /**

         *以下都是WindowManager.LayoutParams的相关属性

         * 具体用途可参考SDK文档

         */

        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;

        /*

         * 下面的flags属性的效果形同“锁定”。

         * 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。

         wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL 

                               | LayoutParams.FLAG_NOT_FOCUSABLE

                               | LayoutParams.FLAG_NOT_TOUCHABLE;

        */

        

        

        wmParams.gravity=Gravity.LEFT|Gravity.TOP;   //调整悬浮窗口至左上角

        //以屏幕左上角为原点,设置x、y初始值

        wmParams.x=0;

        wmParams.y=0;

        

        //设置悬浮窗口长宽数据

        wmParams.width=40;

        wmParams.height=40;

    

        //显示myFloatView图像

        wm.addView(myFV, wmParams);

        

    }

    

    @Override

    public void onDestroy(){

        super.onDestroy();

        //在程序退出(Activity销毁)时销毁悬浮窗口

        wm.removeView(myFV);

    }

    

    @Override

    protected void onRestart() {

        // TODO Auto-generated method stub

        wm.removeView(myFV);

        super.onRestart();

    }

    @Override

    protected void onStop() {

        // TODO Auto-generated method stub

        //创建悬浮窗口

        createView();

        super.onStop();
    }

3\//浮动窗口内容类

public class MyFloatView extends ImageView {

    private float mTouchStartX;

    private float mTouchStartY;

    private float x;

    private float y;

    

    private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService("window");

    

    //此wmParams为获取的全局变量,用以保存悬浮窗口的属性

    private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams();

    public MyFloatView(Context context) {

        super(context);        

        // TODO Auto-generated constructor stub

    }

    

     @Override

     public boolean onTouchEvent(MotionEvent event) {

         

         //getRawX()获取相对屏幕的坐标,即以屏幕左上角为原点         

         x = event.getRawX();   

         y = event.getRawY()-25;   //25是系统状态栏的高度

         Log.i("currP", "currX"+x+"====currY"+y);

         switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                //getX()获取相对View的坐标,即以此View左上角为原点

                mTouchStartX =  event.getX(); 

                mTouchStartY =  event.getY();

                

                Log.i("startP", "startX"+mTouchStartX+"====startY"+mTouchStartY);

                

                break;

            case MotionEvent.ACTION_MOVE:                

                updateViewPosition();

                break;

            case MotionEvent.ACTION_UP:

                updateViewPosition();

                mTouchStartX=mTouchStartY=0;

                break;

            }

            return true;

        }

     

     private void updateViewPosition(){

        //更新浮动窗口位置参数,x是鼠标在屏幕的位置,mTouchStartX是鼠标在图片的位置

        wmParams.x=(int)( x-mTouchStartX);

        System.out.println(mTouchStartX);

        wmParams.y=(int) (y-mTouchStartY);

        wm.updateViewLayout(this, wmParams);

        

     }

}

4\

在androidManifest中设置:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 

附件:


获取Android状态栏高度的屡试不爽的方法


private int getStatusBarHeight() {
Class<?> c = null;

Object obj = null;

Field field = null;

int x = 0, sbar = 0;

try {

c = Class.forName("com.android.internal.R$dimen");

obj = c.newInstance();

field = c.getField("status_bar_height");

x = Integer.parseInt(field.get(obj).toString());

sbar = getContext().getResources().getDimensionPixelSize(x);

} catch (Exception e1) {

e1.printStackTrace();

}

return sbar;
}


这是一个牛人想出的办法。 方法有点二,主要原理是从系统R文件中找到dimen这个内部类,然后通过反射拿到dimen中的status_bar_height的值,这个值其实就是资源id,然后再通过getResource方法拿到该id对应的值,真所谓天衣无缝,无可挑剔! 此方法应该也适用于其他系统字段的值。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息