Launcher知识的demo,手机管家小伙家与悬浮窗

Launcher知识的demo。主要仿的手机管家小伙家与悬浮窗的效果。东西比較简单。直接贴代码

主要用到了windowManager 中的更新updateViewLayout(view,params),和 加入windowManager.addView()和删除windowManager.removeView()

移动launcher主要是updateViewLayout(view,params),中的params来实现

贴几个主要类,所有源代码请自己下载


package com.pzf.flow;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
/**
 * 开启服务。用来推断是否是主页面。假设在主页面则显示悬浮窗。否则隐藏悬浮框
 * @author pangzf
 * @time 2014年10月11日 上午11:19:42
 */
public class MyService extends Service {
	private Timer timer;
	private Handler mHandler = new Handler();

	public MyService() {
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {

		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// 开启定时器
		// 推断是否在主页面,假设在主页面同事small没有显示,则显示small
		// 开启定时器,每隔0.5秒刷新一次
		if (timer == null) {
			timer = new Timer();
			timer.scheduleAtFixedRate(new MyTimerTask(), 0, 500);
		}
		return super.onStartCommand(intent, flags, startId);
	}

	private class MyTimerTask extends TimerTask {

		@Override
		public void run() {
			showWindow();
		}

	}

	/**
	 * 推断是否在主页面,假设在主页面同事small没有显示。则显示small
	 */
	private void showWindow() {
		if (MyWindowManager.isHome(getApplicationContext()) && !MyWindowManager.isWindowShowing()) {
			mHandler.post(new Runnable() {

				@Override
				public void run() {
					MyWindowManager.createSmallWindow(getApplicationContext());
				}
			});

		} else if (!MyWindowManager.isHome(getApplicationContext()) && MyWindowManager.isWindowShowing()) {
			// 假设不是主页,可是已经有窗体了,关掉之前的窗体
			mHandler.post(new Runnable() {

				@Override
				public void run() {
					MyWindowManager.removeSmallWindow(getApplicationContext());

				}
			});
		} else if (MyWindowManager.isHome(getApplicationContext()) && MyWindowManager.isWindowShowing()) {
			mHandler.post(new Runnable() {

				@Override
				public void run() {
					 MyWindowManager.updatePercent(getApplicationContext());
				}
			});
		}
	}

	@Override
	public void onDestroy() {
		if (timer != null) {
			timer.cancel();
			timer = null;
		}
		super.onDestroy();
	}

}

package com.pzf.flow;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.TextView;
/**
 * 管理类。1.用来创建launcher 2.删除launcher 3.更新launcher 4.改变火箭发射台的背景图 5.推断是否主页 6.界面是否存在悬浮框 7。

获得执行内存等 * @author pangzf * @time 2014年10月11日 上午11:20:37 */ public class MyWindowManager { private static WindowManager mWindowManager; private static LayoutInflater mInflater; private static SmallView smallWindow; private static WindowManager.LayoutParams smallWindowParams; static int screenWidth; static int screenHeight; private static ActivityManager mActivityManager; private static BigView bigView; private static LayoutParams bigWindowParams; private static RocketLauncher mRocketLauncher; private static LayoutParams mRocketWindowParams; public MyWindowManager(Context context) { mWindowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); mInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * 推断是否是主页面 */ public static boolean isHome(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1); return getHome(context).contains( runningTasks.get(0).topActivity.getPackageName()); } /*** * 获得主页面 * * @return */ private static List<String> getHome(Context context) { PackageManager packageManager = context.getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); List<String> names = new ArrayList<String>(); List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); if (list != null) { for (ResolveInfo info : list) { names.add(info.activityInfo.packageName); } } return names; } /** * 是否有窗体在屏幕上显示 * * @return */ public static boolean isWindowShowing() { return smallWindow != null || bigView != null; } public static void removeSmallWindow(Context context) { if (smallWindow != null) { WindowManager windowManager = getWindowManager(context); windowManager.removeView(smallWindow); smallWindow = null; } } /** * 创建小的window */ // public void createSmallWindow() { // mWindowManager=getWindowManager(mContext); // screenWidth = mWindowManager.getDefaultDisplay().getWidth(); // screenHeight = mWindowManager.getDefaultDisplay().getHeight(); // if (smallView == null) { // smallView = new SmallView(mContext); // // // if (mSamllWindowParams == null) { // mSamllWindowParams = new LayoutParams(); // mSamllWindowParams.type = LayoutParams.TYPE_PHONE; // mSamllWindowParams.format = PixelFormat.RGBA_8888; // mSamllWindowParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE // | LayoutParams.FLAG_NOT_TOUCH_MODAL; // mSamllWindowParams.gravity = Gravity.LEFT | Gravity.TOP; // mSamllWindowParams.width = smallView.getWidth(); // mSamllWindowParams.height = smallView.getHeight(); // mSamllWindowParams.x = screenWidth; // mSamllWindowParams.y = screenHeight/2; // } // smallView.setParams(mSamllWindowParams); // mWindowManager.addView(smallView, mSamllWindowParams); // } // // } public static void createSmallWindow(Context context) { WindowManager windowManager = getWindowManager(context); int screenWidth = windowManager.getDefaultDisplay().getWidth(); int screenHeight = windowManager.getDefaultDisplay().getHeight(); if (smallWindow == null) { smallWindow = new SmallView(context); if (smallWindowParams == null) { smallWindowParams = new LayoutParams(); smallWindowParams.type = LayoutParams.TYPE_SYSTEM_ALERT; smallWindowParams.format = PixelFormat.RGBA_8888; smallWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE; smallWindowParams.gravity = Gravity.LEFT | Gravity.TOP; smallWindowParams.width = smallWindow.viewWidth; smallWindowParams.height = smallWindow.viewHeight; smallWindowParams.x = screenWidth; smallWindowParams.y = screenHeight / 2; } smallWindow.setParams(smallWindowParams); windowManager.addView(smallWindow, smallWindowParams); } } private static WindowManager getWindowManager(Context context) { if (mWindowManager == null) { mWindowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); } return mWindowManager; } /** * 计算已使用内存的百分比 * * @return */ public static String getUserPercent(Context context) { String dir = "/proc/meminfo"; try { // FileReader fr=new FileReader(dir); // BufferedReader br = new BufferedReader(fr, 2048); // String data = br.readLine(); // String subMemoryLine = data.substring(data.indexOf("MemTotal:")); // br.close(); // long totalMemorySize = // Integer.parseInt(subMemoryLine.replaceAll("\D+", "")); // long avaliableMemory= getAvalibaleMemory(context)/1024; // int // percent=(int)((totalMemorySize-avaliableMemory)/((float)totalMemorySize*100)); // return percent+"%"; FileReader fr = new FileReader(dir); BufferedReader br = new BufferedReader(fr, 2048); String memoryLine = br.readLine(); String subMemoryLine = memoryLine.substring(memoryLine .indexOf("MemTotal:")); br.close(); long totalMemorySize = Integer.parseInt(subMemoryLine.replaceAll( "\D+", "")); long availableSize = getAvalibaleMemory(context) / 1024; int percent = (int) ((totalMemorySize - availableSize) / (float) totalMemorySize * 100); return percent + "%"; } catch (Exception e) { e.printStackTrace(); } return "悬浮窗"; } /** * 返回可用的内存 * * @param context * @return */ private static long getAvalibaleMemory(Context context) { MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); getActivityManager(context).getMemoryInfo(memoryInfo); return memoryInfo.availMem; } private static ActivityManager getActivityManager(Context context) { if (mActivityManager == null) { mActivityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); } return mActivityManager; } public static void updatePercent(Context context) { if (smallWindow != null) { ((TextView) smallWindow.findViewById(R.id.tv_small_percent)) .setText(getUserPercent(context)); } } public static void createBigView(Context context) { WindowManager windowManager = getWindowManager(context); int screenWidth = windowManager.getDefaultDisplay().getWidth(); int screenHeight = windowManager.getDefaultDisplay().getHeight(); if (bigView == null) { bigView = new BigView(context); if (bigWindowParams == null) { bigWindowParams = new LayoutParams(); bigWindowParams.x = screenWidth / 2 - BigView.viewWidth / 2; bigWindowParams.y = screenHeight / 2 - BigView.viewHeight / 2; bigWindowParams.type = LayoutParams.TYPE_PHONE; bigWindowParams.format = PixelFormat.RGBA_8888; bigWindowParams.gravity = Gravity.LEFT | Gravity.TOP; bigWindowParams.width = BigView.viewWidth; bigWindowParams.height = BigView.viewHeight; } windowManager.addView(bigView, bigWindowParams); } } /** * 将大悬浮窗从屏幕上移除。 * * @param context * 必须为应用程序的Context. */ public static void removeBigWindow(Context context) { if (bigView != null) { WindowManager windowManager = getWindowManager(context); windowManager.removeView(bigView); bigView = null; } } // 火箭--------------- /** * 创建小火箭 * * @param context */ // public static void createRocketWindow(Context context) { // WindowManager windowManager = getWindowManager(context); // int screenWidth = windowManager.getDefaultDisplay().getWidth(); // int screenHeight = windowManager.getDefaultDisplay().getHeight(); // if (mRocketLauncher == null) { // mRocketLauncher = new RocketLauncher(context); // if (mRocketWindowParams == null) { // mRocketWindowParams = new LayoutParams(); // mRocketWindowParams.x = screenWidth / 2 - mRocketLauncher.mRocketWith/2; // mRocketWindowParams.y = screenHeight - mRocketLauncher.mRocketHeight; // // mRocketWindowParams.type = LayoutParams.TYPE_PHONE; // mRocketWindowParams.format = PixelFormat.RGBA_8888; // mRocketWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL // | LayoutParams.FLAG_NOT_FOCUSABLE; // mRocketWindowParams.gravity = Gravity.LEFT | Gravity.TOP; // mRocketWindowParams.width = mRocketLauncher.mRocketWith; // mRocketWindowParams.height = mRocketLauncher.mRocketHeight; // } // windowManager.addView(mRocketLauncher, mRocketWindowParams); // } // } // /** * 创建一个火箭发射台,位置为屏幕底部。

*/ public static void createRocketWindow(Context context) { WindowManager windowManager = getWindowManager(context); int screenWidth = windowManager.getDefaultDisplay().getWidth(); int screenHeight = windowManager.getDefaultDisplay().getHeight(); if (mRocketLauncher == null) { mRocketLauncher = new RocketLauncher(context); if (mRocketWindowParams == null) { mRocketWindowParams = new LayoutParams(); mRocketWindowParams.x = screenWidth / 2 - RocketLauncher.mRocketWith / 2; mRocketWindowParams.y = screenHeight - RocketLauncher.mRocketHeight; mRocketWindowParams.type = LayoutParams.TYPE_PHONE; mRocketWindowParams.format = PixelFormat.RGBA_8888; mRocketWindowParams.gravity = Gravity.LEFT | Gravity.TOP; mRocketWindowParams.width = RocketLauncher.mRocketWith; mRocketWindowParams.height = RocketLauncher.mRocketHeight; } windowManager.addView(mRocketLauncher, mRocketWindowParams); } } /** * 移除小火箭l * * @param context */ public static void removeRocketWindow(Context context) { WindowManager windowManager = getWindowManager(context); if (mRocketLauncher != null) { windowManager.removeView(mRocketLauncher); mRocketLauncher = null; } } /** * 更新火箭发射台的显示状态。

*/ public static void updateLauncher() { if (mRocketLauncher != null) { mRocketLauncher.updateRocketLaucher(isReadyToLaunch()); } } /** * 推断小火箭是否准备好发射了。

* * @return 当火箭被发到发射台上返回true,否则返回false。 */ public static boolean isReadyToLaunch() { if ((smallWindowParams.x > mRocketWindowParams.x && smallWindowParams.x + smallWindowParams.width < mRocketWindowParams.x + mRocketWindowParams.width) && (smallWindowParams.y + smallWindowParams.height > mRocketWindowParams.y)) { return true; } return false; } }


package com.pzf.flow;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
 * 小火箭的launcer的布局类。此处须要注意mRocketWith。mRocketHeight这两个字段须要public供外界使用,由于在你移动悬浮框的时候须要显示小火箭。这时候须要小火箭的宽和高
 * @author pangzf
 * @time 2014年10月11日 上午11:22:32
 */
public class RocketLauncher extends LinearLayout {

	public static int mRocketWith;
	public static int mRocketHeight;
	private ImageView mRocket;

	public RocketLauncher(Context context) {
		super(context);
		LayoutInflater.from(context).inflate(R.layout.launcher, this);
		mRocket = (ImageView) findViewById(R.id.launcher_img);
		mRocketWith = mRocket.getLayoutParams().width;
		mRocketHeight = mRocket.getLayoutParams().height;
	}
	/**
	 * 是否是发射状态
	 * @param isReadyLaunch
	 */
	public void updateRocketLaucher(boolean isReadyLaunch){
		mRocket.setImageResource(isReadyLaunch?R.drawable.launcher_bg_fire:R.drawable.launcher_bg_hold);
	}

}
package com.pzf.flow;

import java.lang.reflect.Field;

import android.content.Context;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
 * 悬浮框类
 * 1.显示内存使用情况
 * 2.移动悬浮框,位置改变  OnTouch();
 * 3.移动小悬浮框,变成小火箭 updateView() updateStatus();
 * 4.移动到发射台,小火箭发射 LaunchTask
 * @author pangzf
 * @time 2014年10月11日 上午11:23:48
 */
public class SmallView extends LinearLayout {
	
	private Context mContext;
	private int statusBarHeight;
	private float mXInView;
	private float mYInView;
	private float mXDownInScreen;
	private float mYDownInScreen;
	private float mXInScreen;
	private float mYInScreen;
    /** 
     * 小悬浮窗的參数 
     */  
    private WindowManager.LayoutParams mParams;
	public int viewWidth;
	public int viewHeight;
	private WindowManager mWindowManager;
	private LinearLayout view;  
	private boolean isPressed;
	private ImageView mIvRocket;
	private int rocketWidth;
	private int rocketHeight;

	public SmallView(Context context) {
		super(context);
		this.mContext=context;
		mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		LayoutInflater.from(context).inflate(R.layout.small, this);
		view = (LinearLayout) findViewById(R.id.ll_small_main);
		viewWidth = view.getLayoutParams().width;
		viewHeight = view.getLayoutParams().height;
	
		mIvRocket = (ImageView) findViewById(R.id.rocket_img);
		rocketWidth = mIvRocket.getLayoutParams().width;
		rocketHeight = mIvRocket.getLayoutParams().height;
		
		TextView mTvPercent = (TextView) view
				.findViewById(R.id.tv_small_percent);
		mTvPercent.setText(MyWindowManager.getUserPercent(context));
	}
	  
    /** 
     * 将小悬浮窗的參数传入,用于更新小悬浮窗的位置。

* * @param params * 小悬浮窗的參数 */ public void setParams(WindowManager.LayoutParams params) { mParams = params; } // 做单击处理和移动small位置 @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isPressed=true; mXInView = event.getX(); mYInView = event.getY(); mXDownInScreen = event.getRawX(); mYDownInScreen = event.getRawY() - getStatusBarHeight(); mXInScreen = event.getRawX(); mYInScreen = event.getRawY()-getStatusBarHeight(); break; case MotionEvent.ACTION_MOVE: //移动small mXInScreen=event.getRawX(); mYInScreen=event.getRawY() - getStatusBarHeight(); updateStatus(); updateView(); break; case MotionEvent.ACTION_UP: isPressed=false; if(MyWindowManager.isReadyToLaunch()){ //发射小火箭 launchRocket(); }else{ updateStatus(); //推断点击事件 if(mXDownInScreen==mXInScreen&&mYDownInScreen==mYInScreen){ //打开big openBigWindow(); } } break; default: break; } return true; } /** * 发射小火箭 */ private void launchRocket() { MyWindowManager.removeRocketWindow(getContext()); new LuanchTask().execute(); } private class LuanchTask extends AsyncTask<Void, Void, Void>{ @Override protected Void doInBackground(Void... params) { while(mParams.y>0){ mParams.y=mParams.y-10; publishProgress(); SystemClock.sleep(8); } return null; } @Override protected void onProgressUpdate(Void... values) { //依据进度更新小火箭的位置,实现发射效果 mWindowManager.updateViewLayout(SmallView.this, mParams); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // 火箭升空结束后。回归到悬浮窗状态 updateStatus(); mParams.x = (int) (mXDownInScreen - mXInView); mParams.y = (int) (mYDownInScreen - mYInView); mWindowManager.updateViewLayout(SmallView.this, mParams); } } /** * 更改小火箭的状态 */ private void updateStatus() { //假设是按下的状态,并且小火箭是不存在的,则显示小火箭。隐藏悬浮框 if(isPressed&&mIvRocket.getVisibility()!=View.VISIBLE){ mParams.width=rocketWidth; mParams.height=rocketHeight; mWindowManager.updateViewLayout(this, mParams); view.setVisibility(View.GONE); mIvRocket.setVisibility(View.VISIBLE); MyWindowManager.createRocketWindow(getContext()); }else if(!isPressed){ //显示悬浮框,隐藏小火箭 mParams.width=viewWidth; mParams.height=viewHeight; mWindowManager.updateViewLayout(this, mParams); view.setVisibility(View.VISIBLE); mIvRocket.setVisibility(View.GONE); MyWindowManager.removeRocketWindow(getContext()); } } /** * 打开大悬浮窗。同一时候关闭小悬浮窗。 */ private void openBigWindow() { MyWindowManager.createBigView(getContext()); MyWindowManager.removeSmallWindow(getContext()); } /** * 移动samll在屏幕上的位置 */ private void updateView() { mParams.x=(int) (mXInScreen-mXInView); mParams.y=(int) (mYInScreen-mYInView); mWindowManager.updateViewLayout(this, mParams); MyWindowManager.updateLauncher(); } /** * 获得状态栏的高度 * * @return */ private float getStatusBarHeight() { if (statusBarHeight == 0) { try { Class<?> clazz = Class.forName("com.android.internal.R$dimen"); Object o = clazz.newInstance(); Field field = clazz.getField("status_bar_height"); Integer size = (Integer) field.get(o); statusBarHeight = getResources().getDimensionPixelSize(size); } catch (Exception e) { e.printStackTrace(); } } return statusBarHeight; } }



效果图


源代码地址:点击打开链接


个人项目txtreader:已经公布google play,http://blog.csdn.net/pangzaifei/article/details/52756777

有须要的能够联系


原文地址:https://www.cnblogs.com/zsychanpin/p/7002925.html