国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Android - android 添加隨意拖動(dòng)的桌面懸浮窗口

android 添加隨意拖動(dòng)的桌面懸浮窗口

2020-12-22 16:04Android教程網(wǎng) Android

用過(guò)新版本android 360手機(jī)助手都人都對(duì) 360中只在桌面顯示一個(gè)小小懸浮窗口羨慕不已吧,本文將介紹此功能的實(shí)現(xiàn)步驟,需要了解的朋友可以參考下

用過(guò)新版本android 360手機(jī)助手都人都對(duì) 360中只在桌面顯示一個(gè)小小懸浮窗口羨慕不已吧?
其實(shí)實(shí)現(xiàn)這種功能,主要有兩步:
1.判斷當(dāng)前顯示的是為桌面。這個(gè)內(nèi)容我在前面的帖子里面已經(jīng)有過(guò)介紹,如果還沒(méi)看過(guò)的趕快穩(wěn)步看一下哦。
2.使用windowManager往最頂層添加一個(gè)View
.這個(gè)知識(shí)點(diǎn)就是為本文主要講解的內(nèi)容哦。在本文的講解中,我們還會(huì)講到下面的知識(shí)點(diǎn):
a.如果獲取到狀態(tài)欄的高度
b.懸浮窗口的拖動(dòng)
c.懸浮窗口的點(diǎn)擊事件
有開(kāi)始之前,我們先來(lái)看一下效果圖:
android 添加隨意拖動(dòng)的桌面懸浮窗口 
接下來(lái)我們來(lái)看看FloatView的代碼:

復(fù)制代碼 代碼如下:


public class FloatView extends ImageView{
private float mTouchX;
private float mTouchY;
private float x;
private float y;
private float mStartX;
private float mStartY;
private OnClickListener mClickListener;
private WindowManager windowManager = (WindowManager) getContext()
.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
// 此windowManagerParams變量為獲取的全局變量,用以保存懸浮窗口的屬性
private WindowManager.LayoutParams windowManagerParams = ((FloatApplication) getContext()
.getApplicationContext()).getWindowParams();
public FloatView(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//獲取到狀態(tài)欄的高度
Rect frame = new Rect();
getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
System.out.println("statusBarHeight:"+statusBarHeight);
// 獲取相對(duì)屏幕的坐標(biāo),即以屏幕左上角為原點(diǎn)
x = event.getRawX();
y = event.getRawY() - statusBarHeight; // statusBarHeight是系統(tǒng)狀態(tài)欄的高度
Log.i("tag", "currX" + x + "====currY" + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // 捕獲手指觸摸按下動(dòng)作
// 獲取相對(duì)View的坐標(biāo),即以此View左上角為原點(diǎn)
mTouchX = event.getX();
mTouchY = event.getY();
mStartX = x;
mStartY = y;
Log.i("tag", "startX" + mTouchX + "====startY"
+ mTouchY);
break;
case MotionEvent.ACTION_MOVE: // 捕獲手指觸摸移動(dòng)動(dòng)作
updateViewPosition();
break;
case MotionEvent.ACTION_UP: // 捕獲手指觸摸離開(kāi)動(dòng)作
updateViewPosition();
mTouchX = mTouchY = 0;
if ((x - mStartX) < 5 && (y - mStartY) < 5) {
if(mClickListener!=null) {
mClickListener.onClick(this);
}
}
break;
}
return true;
}
@Override
public void setOnClickListener(OnClickListener l) {
this.mClickListener = l;
}
private void updateViewPosition() {
// 更新浮動(dòng)窗口位置參數(shù)
windowManagerParams.x = (int) (x - mTouchX);
windowManagerParams.y = (int) (y - mTouchY);
windowManager.updateViewLayout(this, windowManagerParams); // 刷新顯示
}
}


代碼解釋
int statusBarHeight = frame.top;
為獲取狀態(tài)欄的高度,為什么在event.getRawY()的時(shí)候減去狀態(tài)欄的高度呢?
因?yàn)槲覀兊膽腋〈翱诓豢赡茱@示到狀態(tài)欄中去,而后getRawY為獲取到屏幕原點(diǎn)的距離。當(dāng)我們屏幕處于全屏模式時(shí),獲取到的狀態(tài)欄高度會(huì)變成0
(x - mStartX) < 5 && (y - mStartY) < 5
如果我們?cè)谟|摸過(guò)程中,移動(dòng)距離少于5 ,則視為點(diǎn)擊,觸發(fā)點(diǎn)擊的回調(diào)。
另外我們需要自定義一個(gè)application:

復(fù)制代碼 代碼如下:


public class FloatApplication extends Application {
private WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
public WindowManager.LayoutParams getWindowParams() {
return windowParams;
}
}


代碼解釋
自定義application的目的是為了保存windowParams的值 ,因?yàn)槲覀冊(cè)谕蟿?dòng)懸浮窗口的時(shí)候,如果每次都重新new一個(gè)layoutParams的話,在update
的時(shí)候會(huì)在異常發(fā)現(xiàn)。
windowParams的值也不一定非得在自定義application里面來(lái)保存,只要是全局的都行。
最后我們?cè)賮?lái)看看Activity中的實(shí)現(xiàn)。

復(fù)制代碼 代碼如下:


public class MainActivity extends Activity implements OnClickListener{
private WindowManager windowManager = null;
private WindowManager.LayoutParams windowManagerParams = null;
private FloatView floatView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//取消標(biāo)題欄
getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,
WindowManager.LayoutParams. FLAG_FULLSCREEN);//全屏
setContentView(R.layout.activity_main);
createView();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void onDestroy() {
super.onDestroy();
// 在程序退出(Activity銷(xiāo)毀)時(shí)銷(xiāo)毀懸浮窗口
windowManager.removeView(floatView);
}
private void createView() {
floatView = new FloatView(getApplicationContext());
floatView.setOnClickListener(this);
floatView.setImageResource(R.drawable.ic_launcher); // 這里簡(jiǎn)單的用自帶的icon來(lái)做演示
// 獲取WindowManager
windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
// 設(shè)置LayoutParams(全局變量)相關(guān)參數(shù)
windowManagerParams = ((FloatApplication) getApplication()).getWindowParams();
windowManagerParams.type = LayoutParams.TYPE_PHONE; // 設(shè)置window type
windowManagerParams.format = PixelFormat.RGBA_8888; // 設(shè)置圖片格式,效果為背景透明
// 設(shè)置Window flag
windowManagerParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE;
/*
* 注意,flag的值可以為:
* LayoutParams.FLAG_NOT_TOUCH_MODAL 不影響后面的事件
* LayoutParams.FLAG_NOT_FOCUSABLE 不可聚焦
* LayoutParams.FLAG_NOT_TOUCHABLE 不可觸摸
*/
// 調(diào)整懸浮窗口至左上角,便于調(diào)整坐標(biāo)
windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP;
// 以屏幕左上角為原點(diǎn),設(shè)置x、y初始值
windowManagerParams.x = 0;
windowManagerParams.y = 0;
// 設(shè)置懸浮窗口長(zhǎng)寬數(shù)據(jù)
windowManagerParams.width = LayoutParams.WRAP_CONTENT;
windowManagerParams.height = LayoutParams.WRAP_CONTENT;
// 顯示myFloatView圖像
windowManager.addView(floatView, windowManagerParams);
}
public void onClick(View v) {
Toast.makeText(this, "Clicked", Toast.LENGTH_SHORT).show();
}
}


代碼解釋
在activity中我們主要是添加懸浮窗,并且設(shè)置他的位置。另外需要注意flags的應(yīng)用:
LayoutParams.FLAG_NOT_TOUCH_MODAL 不影響后面的事件
LayoutParams.FLAG_NOT_FOCUSABLE 不可聚焦
LayoutParams.FLAG_NOT_TOUCHABLE 不可觸摸
最后我們?cè)趏nDestroy()中移除到懸浮窗口。所以,我們測(cè)試的時(shí)候,記得按Home鍵來(lái)切換到桌面。
最后千萬(wàn)記得,在androidManifest.xml中來(lái)申明我們需要用到的android.permission.SYSTEM_ALERT_WINDOW權(quán)限
并且記得申明我們自定義的application哦。
AndroidManifest.xml代碼如下

復(fù)制代碼 代碼如下:


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.krislq.floating"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" android:name="FloatApplication">
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩精品一区二区三区在线播放 | 色在线看 | av一级毛片 | 99re视频| 精品国产精品三级精品av网址 | 日韩国产精品一区二区三区 | 日韩欧美一区二区三区免费观看 | 久久综合久久久 | 欧美一区三区 | 这里只有精品在线播放 | 国产在线精品一区二区三区 | 亚洲国产综合在线观看 | 欧洲亚洲精品久久久久 | 国产精品美女久久久久久免费 | 国产精品久久久久久久久免费桃花 | 日韩视频区 | 黄色在线观看网址 | 欧美一区二区大片 | 国产在线一区不卡 | 一本大道综合伊人精品热热 | 亚洲综合欧美 | 国产午夜精品美女视频明星a级 | 中文字幕乱码一区二区三区 | 日韩欧美三区 | 亚洲国产高清高潮精品美女 | 亚洲 欧美 另类 综合 偷拍 | 成人在线免费 | 激情综合网激情 | 国产精品综合 | 日韩欧美一区二区三区久久婷婷 | 亚洲一区中文 | 日本一区二区三区免费观看 | 亚洲精品片 | 欧美日韩精品一区二区三区蜜桃 | 久久久久久亚洲精品视频 | 希岛爱理av一区二区三区 | 在线观看a毛片 | 国产精品久久a | 久久精品久久久 | 欧美a v在线播放 | 亚洲色图在线观看 |