zoukankan      html  css  js  c++  java
  • 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

    有须要的能够联系


  • 相关阅读:
    【EF学习笔记11】----------查询中常用的扩展方法
    .NET 扩展方法
    【EF学习笔记10】----------主从表级联操作
    【EF学习笔记09】----------使用 EntityState 枚举标记实体状态,实现增删改查
    【EF学习笔记08】----------加载关联表的数据 显式加载
    【EF学习笔记07】----------加载关联表的数据 贪婪加载
    【EF学习笔记06】----------加载关联表的数据 延迟加载
    Linux内核ROP姿势详解(二)
    见微知著(三):解析ctf中的pwn--Fastbin和bins的溢出
    见微知著(二):解析ctf中的pwn--怎么利用double free
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7002925.html
Copyright © 2011-2022 走看看