android----懸浮窗

眾所周知,像qq音樂(lè),當(dāng)退出qq音樂(lè)app時(shí),歌詞會(huì)在桌面上顯示,這里可以用懸浮窗實(shí)現(xiàn)。

用一個(gè)很簡(jiǎn)單的TextView來(lái)實(shí)現(xiàn)懸浮窗效果。

點(diǎ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">

? ? ?<--以一個(gè)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的管理員

? ? ?//我們想要把一個(gè)view懸浮在window上,就要使用windowmanager來(lái)操作window

? ? ?private static WindowManager windowManager;

? ? ?//申請(qǐng)一個(gè)布局參數(shù)成員

? ? ?private WindowManager.LayoutParams lp;

? ? ?//懸浮窗view,現(xiàn)在我們簡(jiǎn)單用一個(gè)textView來(lái)做

? ? ?private static TextView txtInfo;

? ? ?private Context applicationContext;

? ? ?@Override

? ? ?protected void onCreate(Bundle savedInstanceState) {

? ? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? ? setContentView(R.layout.activity_main);

? ? ? ? ? applicationContext= getApplication();

? ? ? ? ? //windowManager的實(shí)例化,上下文對(duì)象get到

? ? ? ? ? if(windowManager==null){

? ? ? ? ? ? ? ? ? ? windowManager= ? ? ? ?(WindowManager)applicationContext.getSystemService(WINDOW_SERVICE);

? ? ? ? ? ?}

? ? ? ? ? if(txtInfo!=null){//刪除

? ? ? ? ? ? ? ? ? ? ?windowManager.removeView(txtInfo);

? ? ? ? ? ? ? ? ? ? ?txtInfo=null;

? ? ? ? ? }else{//添加

? ? ? ? ? ? ? ? ? ? ? //創(chuàng)建一個(gè)textView

? ? ? ? ? ? ? ? ? ? ? txtInfo=newTextView(applicationContext);

? ? ? ? ? ? ? ? ? ? ? txtInfo.setText("12345678");

? ? ? ? ? ? ? ? ? ? ? txtInfo.setTextSize(TypedValue.COMPLEX_UNIT_SP,40);

? ? ? ? ? ? ? ? ? ? ? //實(shí)例化布局參數(shù)

? ? ? ? ? ? ? ? ? ? ? lp=newWindowManager.LayoutParams();

? ? ? ? ? ? ? ? ? ? ? //設(shè)置布局參數(shù)

? ? ? ? ? ? //WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY|WindowManager.LayoutParams.TYPE_SYSTEM_ALERT

//TYPE_SYSTEM_OVERLAY意思是系統(tǒng)覆蓋物,可以實(shí)現(xiàn)系統(tǒng)桌面的懸浮? 2000+6=2006

//TYPE_SYSTEM_ALERT可以控制移動(dòng)? 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不獲取焦點(diǎn)

? ? ? ? ? //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è)置懸浮窗會(huì)顯示背景,也就是半透明

? ? ? ? ? lp.format= PixelFormat.TRANSPARENT;

? ? ? ? ?//windowManager添加一個(gè)view到window上

? ? ? ? ? //要帶著布局參數(shù)添加

? ? ? ? ?windowManager.addView(txtInfo,lp);

? ? ? ? ? //設(shè)置懸浮窗的點(diǎn)擊事件的監(jiān)聽(tīng)

? ? ? ? ?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的移動(dòng)處理

? ? ? ?txtInfo.setOnTouchListener(newView.OnTouchListener() {

? ? ? ?private WindowManager.LayoutParams mlp=lp;

? ? ? ?//用于記錄上一次的位置

? ? ? ?private intlastX,lastY;

? ? ? //記錄最后一次按下的時(shí)間,用于在UP的時(shí)候判斷是否小于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();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取手指的動(dòng)作的坐標(biāo)是用getX()

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //使用Rax()可以獲取相對(duì)于手機(jī)界面的坐標(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();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //計(jì)算和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ā)點(diǎn)擊

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?txtInfo.performClick();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? }

? ? return ret;

}

});

}

}

//如果同一個(gè)應(yīng)用同時(shí)調(diào)用了onClickListener和onTouchListener,只會(huì)調(diào)用onTouchListener

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這篇博客主要介紹的是 Android 主流各種機(jī)型和各種版本的懸浮窗權(quán)限適配,但是由于碎片化的問(wèn)題,所以在適配方面...
    Shawn_Dut閱讀 10,882評(píng)論 15 44
  • 帶有android懸浮窗的語(yǔ)音識(shí)別語(yǔ)義理解demo 轉(zhuǎn)載請(qǐng)注明CSDN博文地址:http://blog.csdn....
    ls0609閱讀 2,785評(píng)論 0 7
  • 轉(zhuǎn)載請(qǐng)注明出處:Android懸浮窗用法總結(jié) 最近項(xiàng)目里用到了懸浮窗,在這里做一下總結(jié)。 WindowManage...
    夏末m閱讀 28,084評(píng)論 4 26
  • 引言:需要實(shí)現(xiàn)一個(gè)視頻懸浮播放的功能,功能實(shí)現(xiàn)后發(fā)現(xiàn)懸浮權(quán)限的檢測(cè)與申請(qǐng)并沒(méi)有想象中那樣簡(jiǎn)單。時(shí)間:2017年04...
    JustDo23閱讀 14,905評(píng)論 2 31
  • 轉(zhuǎn)載請(qǐng)注明出處:Android懸浮窗權(quán)限適配 懸浮窗相信大家都不陌生,比如360手機(jī)衛(wèi)士的加速球,視頻應(yīng)用的小窗,...
    夏末m閱讀 11,952評(píng)論 1 6

友情鏈接更多精彩內(nèi)容