眾所周知胰坟,像qq音樂,當(dāng)退出qq音樂app時钙蒙,歌詞會在桌面上顯示茵瀑,這里可以用懸浮窗實現(xiàn)。
用一個很簡單的TextView來實現(xiàn)懸浮窗效果躬厌。
點擊退出后:
1马昨、需要添加的權(quán)限
<uses-permission ?
? ? ? ? android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
2、activity_main.xml(布局文件)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
? ? ? xmlns:android="http://schemas.android.com/apk/res/android"
? ? ?xmlns:tools="http://schemas.android.com/tools"
? ? ?android:layout_width="match_parent"
? ? ?android:layout_height="match_parent"
? ? ?tools:context="com.ws.day1025_01.MainActivity">
? ? ?<--以一個TextView為例的懸浮窗-->
? ? ?<TextView
? ? ? ? ? android:layout_width="wrap_content"
? ? ? ? ? android:layout_height="wrap_content"
? ? ? ? ? android:layout_alignParentBottom="true"
? ? ? ? ? android:layout_centerHorizontal="true"
? ? ? ? ? android:layout_marginBottom="20dp"
? ? ? ? ? android:text="123456"
? ? ? ? ?/>
</RelativeLayout>
3扛施、MainActivity.java
importandroid.content.Context;
importandroid.content.Intent;
importandroid.graphics.PixelFormat;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.util.TypedValue;
importandroid.view.Gravity;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.WindowManager;
importandroid.widget.TextView;
public class MainActivity extends AppCompatActivity {
? ? ?//WindowManager是管理Window的管理員
? ? ?//我們想要把一個view懸浮在window上鸿捧,就要使用windowmanager來操作window
? ? ?private static WindowManager windowManager;
? ? ?//申請一個布局參數(shù)成員
? ? ?private WindowManager.LayoutParams lp;
? ? ?//懸浮窗view,現(xiàn)在我們簡單用一個textView來做
? ? ?private static TextView txtInfo;
? ? ?private Context applicationContext;
? ? ?@Override
? ? ?protected void onCreate(Bundle savedInstanceState) {
? ? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? ? applicationContext= getApplication();
? ? ? ? ? //windowManager的實例化,上下文對象get到
? ? ? ? ? if(windowManager==null){
? ? ? ? ? ? ? ? ? ? windowManager= ? ? ? ?(WindowManager)applicationContext.getSystemService(WINDOW_SERVICE);
? ? ? ? ? ?}
? ? ? ? ? if(txtInfo!=null){//刪除
? ? ? ? ? ? ? ? ? ? ?windowManager.removeView(txtInfo);
? ? ? ? ? ? ? ? ? ? ?txtInfo=null;
? ? ? ? ? }else{//添加
? ? ? ? ? ? ? ? ? ? ? //創(chuàng)建一個textView
? ? ? ? ? ? ? ? ? ? ? txtInfo=newTextView(applicationContext);
? ? ? ? ? ? ? ? ? ? ? txtInfo.setText("12345678");
? ? ? ? ? ? ? ? ? ? ? txtInfo.setTextSize(TypedValue.COMPLEX_UNIT_SP,40);
? ? ? ? ? ? ? ? ? ? ? //實例化布局參數(shù)
? ? ? ? ? ? ? ? ? ? ? lp=newWindowManager.LayoutParams();
? ? ? ? ? ? ? ? ? ? ? //設(shè)置布局參數(shù)
? ? ? ? ? ? //WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY|WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
//TYPE_SYSTEM_OVERLAY意思是系統(tǒng)覆蓋物疙渣,可以實現(xiàn)系統(tǒng)桌面的懸浮? 2000+6=2006
//TYPE_SYSTEM_ALERT可以控制移動? 2000+3=2003
//2006|2003=(2000+6)|(2000+3) = 2000|2000+6|3 = 2007
// lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY|WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
? ? ? ? ? lp.type= WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
? ? ? ? ?//設(shè)置flags
? ? ? ? //FLAG_NOT_FOCUSABLE不獲取焦點
? ? ? ? ? //FLAG_FULLSCREEN使得View可以全屏拖拽
? ? ? ? ?lp.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_FULLSCREEN;
? ? ? ? ?lp.gravity= Gravity.LEFT|Gravity.TOP;
? ? ? ? ? //設(shè)置初始位置
? ? ? ? lp.x=10;
? ? ? ? lp.y=50;
? ? ? ? //設(shè)置寬高包裹內(nèi)容
? ? ? ? ?lp.width= WindowManager.LayoutParams.WRAP_CONTENT;
? ? ? ? ? lp.height= WindowManager.LayoutParams.WRAP_CONTENT;
? ? ? ? ?//設(shè)置懸浮窗會顯示背景匙奴,也就是半透明
? ? ? ? ? lp.format= PixelFormat.TRANSPARENT;
? ? ? ? ?//windowManager添加一個view到window上
? ? ? ? ? //要帶著布局參數(shù)添加
? ? ? ? ?windowManager.addView(txtInfo,lp);
? ? ? ? ? //設(shè)置懸浮窗的點擊事件的監(jiān)聽
? ? ? ? ?txtInfo.setOnClickListener(newView.OnClickListener() {
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public voidonClick(View v) {
? ? ? ? ? ? ? ? ? ? ? ? ? Intent intent =newIntent(applicationContext,MainActivity.class);
? ? ? ? ? ? ? ? ? ? ? ? ? ?intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
? ? ? ? ? ? ? ? ? ? ? ? ? ? applicationContext.startActivity(intent);
? ? ? ? ? ? ? ? ?}
? ? ? ?});
? ? ? ?//設(shè)置textView的移動處理
? ? ? ?txtInfo.setOnTouchListener(newView.OnTouchListener() {
? ? ? ?private WindowManager.LayoutParams mlp=lp;
? ? ? ?//用于記錄上一次的位置
? ? ? ?private intlastX,lastY;
? ? ? //記錄最后一次按下的時間,用于在UP的時候判斷是否小于300毫秒
? ? ? ? private longlastDownTime;
? ? ? ?@Override
? ? ? ? public boolean onTouch(View v, MotionEvent event) {
? ? ? ? ? ? ? ? ? boolean ret =false;
? ? ? ? ? ? ? ? ? int action = event.getAction();
? ? ? ? ? ? ? ? ? switch(action) {
? ? ? ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lastDownTime= System.currentTimeMillis();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取手指的動作的坐標(biāo)是用getX()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //使用Rax()可以獲取相對于手機界面的坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lastX= (int) event.getRawX();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lastY= (int) event.getRawY();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret =true;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ?case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? float x = event.getRawX();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? float y = event.getRawY();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //計算和last的差量
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int ix = (int) (x-lastX);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int iy = (int) (y-lastY);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mlp.x+= ix;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mlp.y+= iy;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?lastX= (int) x;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?lastY= (int) y;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //更新view
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? windowManager.updateViewLayout(txtInfo,mlp);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_UP://抬起
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? long ct = System.currentTimeMillis();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if(ct-lastDownTime<=300){//觸發(fā)點擊
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?txtInfo.performClick();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? return ret;
}
});
}
}
//如果同一個應(yīng)用同時調(diào)用了onClickListener和onTouchListener,只會調(diào)用onTouchListener
}