多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android提供的系統服務之--WindowManager(窗口管理服務)

Android提供的系統服務之--WindowManager(窗口管理服務)

來源:程序員人生   發布時間:2015-03-16 10:50:03 閱讀次數:5967次

Android提供的系統服務之--WindowManager(窗口管理服務)

                                                          ――轉載請注明出處:coder-pig


本節引言:

本節我們來探討下這個Android系統服務中的WindowManager(窗口管理服務),

他是顯示View的最底層,好像我們的Actviity和Dialog,和Toast的底層實現都用到

這個WindowManager,他是全局的!核心其實就是WindowManager調用addView,

removeView,updateViewLayout這幾個方法來顯示View;還有WindowManager.LayoutParams

這個API來設置相干的屬性!本節我們就寫兩個關于WindowManger的實用例子吧:

分別是獲得屏幕寬高,和弄1個Android的懸浮框!還有保持屏幕的常亮和全屏設置

好了,開始本節內容!



本節正文:

1.相干概念圖:


   


2.使用例子:

①獲得手機屏幕寬高:

我們通過調用getDefaultDisplay( )可以取得默許的Display顯示對象,接著調用getWidth( )

getHeight( )便可取得屏幕寬高

代碼以下:

WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); setTitle(windowManager.getDefaultDisplay().getWidth() + "*" + windowManager.getDefaultDisplay().getHeight());

運行截圖:





②Android懸浮框的實現:

先來看下效果圖吧,這里只是1個簡單的按鈕,大家可以按自己的需求來自定義~

后面還提供1個類似于QQ懸浮發射小火箭的demo,有需要的可以下載來自己研究研究~



實現流程解析:

step 1:我們需要1個后臺的Service在后臺等待我們的操作,比如完成,View的繪制,移除等~

我們先創建1個空的Service類:MyWindowService繼承Service,然后我們需要在

AndroidManifest.xml為這個Service來進行注冊!

<service android:name=".MyWindowService"/>
另外還需要加上下述兩個權限:

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



step 2:在我們的MainActivity中設置兩個按鈕的點擊事件,我們還要為intent寫入

1個extra,根據這個值,我們在Service進行判斷,是開啟懸浮框,還是關閉懸浮框

package com.jay.example.windowmanagerdemo1; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Button btnShow; private Button btnClose; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnShow = (Button) findViewById(R.id.btnShow); btnClose = (Button) findViewById(R.id.btnClose); btnShow.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent show = new Intent(MainActivity.this, MyWindowService.class); show.putExtra(MyWindowService.OPERATION, MyWindowService.OPERATION_SHOW); startService(show); Toast.makeText(MainActivity.this,"懸浮框已開啟~", Toast.LENGTH_SHORT).show(); } }); btnClose.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent hide = new Intent(MainActivity.this, MyWindowService.class); hide.putExtra(MyWindowService.OPERATION, MyWindowService.OPERATION_HIDE); startService(hide); Toast.makeText(MainActivity.this,"懸浮框已開啟~", Toast.LENGTH_SHORT).show(); } }); } }


step 3:接下來就需要開始編寫我們的Service類了,我們想一想這個Service需要干嗎?

①肯定需要1個創建View的方法啦,因而乎,我們定義1個createWindowView( )方法用于創建

懸浮框的View!

// 定義1個創建懸浮框的方法: private void createWindowView() { btnView = new Button(getApplicationContext()); btnView.setBackgroundResource(R.drawable.pig); windowManager = (WindowManager) getApplicationContext() .getSystemService(Context.WINDOW_SERVICE); params = new WindowManager.LayoutParams(); // 設置Window Type params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 設置懸浮框不可觸摸 params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 懸浮窗不可觸摸,不接受任何事件,同時不影響后面的事件響應 params.format = PixelFormat.RGBA_8888; // 設置懸浮框的寬高 params.width = 200; params.height = 200; params.gravity = Gravity.LEFT; params.x = 200; params.y = 000; // 設置懸浮框的Touch監聽 btnView.setOnTouchListener(new OnTouchListener() { //保存懸浮框最后位置的變量 int lastX, lastY; int paramX, paramY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); paramX = params.x; paramY = params.y; break; case MotionEvent.ACTION_MOVE: int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; params.x = paramX + dx; params.y = paramY + dy; // 更新懸浮窗位置 windowManager.updateViewLayout(btnView, params); break; } return true; } }); windowManager.addView(btnView, params); isAdded = true; }


②這個時候我們只需在OnCreate( )方法中調用上述的createWindowView( )方法便可啟動加載懸浮框了

但是,我們發現1點...這玩意貌似關不掉啊,臥槽,好吧,接下來我們就要分析下需求了!當處于手機的普通界面,

即桌面的時候,這玩意才顯示,而當我們啟動其他App時,這個懸浮框應當消失不見,當我們推出app又回到

桌面,這個懸浮框又要重新出現!那末我們首先需要判斷App是不是位于桌面,我們通過下面的代碼就能夠完成這個

判斷:

/** * 判斷當前界面是不是是桌面 */ public boolean isHome(){ if(mActivityManager == null) { mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); } List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1); return homeList.contains(rti.get(0).topActivity.getPackageName()); } /** * 取得屬于桌面的利用的利用包名稱 * @return 返回包括所有包名的字符串列表 */ private List<String> getHomes() { List<String> names = new ArrayList<String>(); PackageManager packageManager = this.getPackageManager(); // 屬性 Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for(ResolveInfo ri : resolveInfo) { names.add(ri.activityInfo.packageName); } return names; }

③好了,接下來我們需要每隔1段時間來進行1系列的判斷,比如:是不是在桌面,是不是已加載懸浮框,否則加載;

否則,如果加載了,就將這個懸浮框移除!這里我們使用handler~,由于不能在子線程直接更新UI,所以,你懂的

所以我們自己寫1個handler來完成上述的操作:


//定義1個更新界面的Handler private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch(msg.what) { case HANDLE_CHECK_ACTIVITY: if(isHome()) { if(!isAdded) { windowManager.addView(btnView, params); isAdded = true; new Thread(new Runnable() { public void run() { for(int i=0;i<10;i++){ try { Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace();} Message m = new Message(); m.what=2; mHandler.sendMessage(m); } } }).start();} } else { if(isAdded) { windowManager.removeView(btnView); isAdded = false; } } mHandler.sendEmptyMessageDelayed(HANDLE_CHECK_ACTIVITY, 0); break; } } };

④最后要做的1件事,就是重寫Service的onStartCommand( )方法了,就是做判斷,取出Intent中的

數據,判斷是需要添加懸浮框,還是要移除懸浮框!


@Override public int onStartCommand(Intent intent, int flags, int startId) { int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW); switch(operation) { case OPERATION_SHOW: mHandler.removeMessages(HANDLE_CHECK_ACTIVITY); mHandler.sendEmptyMessage(HANDLE_CHECK_ACTIVITY); break; case OPERATION_HIDE: mHandler.removeMessages(HANDLE_CHECK_ACTIVITY); break; } return super.onStartCommand(intent, flags, startId); }


好了,這個程序的實現流程就這是這樣,1次看不懂看多幾遍就可以了解了!




最后還獻上WindowManager的兩個經常使用實例吧:

③設置窗口全屏顯示:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);


④保持窗口打開,即屏幕常亮:

public void setKeepScreenOn(Activity activity,boolean keepScreenOn) { if(keepScreenOn) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); }else{ activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } }


最后說幾句:

好了,關于這個WindowManager就寫到這里!

本節實例代碼下載:

1.利用WindowManager實現簡單的懸浮框:http://pan.baidu.com/s/1pJiHSXP

2.Android模仿QQ小火箭:http://pan.baidu.com/s/1eQeW2um




ps:對WindowManager.LayoutParams的相干標記可見下述鏈接,有需要的自己查,筆者就不在這里詳述了:

Android官方:http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html

csdn他人寫的1篇blog:http://blog.csdn.net/chenyafei617/article/details/6577940



~好了,最后祝大家元宵節快樂~大笑




生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲女人被黑人巨大进入 | 亚洲成人黄色网址 | 成人国产精品一级毛片视频 | 欧美亚洲国产色综合 | 国产aaa级一级毛片 国产aaa免费视频国产 | 国产精品成人免费福利 | 福利精品| 一本毛片 | 国产主播福利一区二区 | 久久亚洲精品一区成人 | 一区二区三区视频在线播放 | 亚洲美女色视频 | 久久精品国产精品亚洲毛片 | 欧美一级毛片高清免费观看 | 亚洲人成网站在线播放942一 | 国产成人在线免费视频 | 九色国产 | 亚洲不卡视频在线 | 成人淫片 | 亚洲一区二区影院 | 国产成人一区二区在线不卡 | 久久久久国产精品美女毛片 | 91爱视频 | 最新中文字幕第一页 | 亚洲性影院 | 日日麻批视频 | 国产欧美日韩不卡一区二区三区 | 日本free护士videosxxxx动漫 | 最近中字视频在线观看 | 免费 欧美 自拍 在线观看 | 丁香婷婷激情综合 | 成人性毛片| 一级毛片视频免费观看 | 欧美伦理片在线播放 | 欧美成人在线观看 | 老司机成人免费精品视频 | 久久观看视频 | 欧美整片完整片视频在线 | 欧美成人在线免费 | 国产免费一区2区3区4区 | 九色国产在线 |