Android窗口化app位移
来源:互联网 发布:淘宝网背带裤女装 编辑:程序博客网 时间:2024/05/16 16:58
强制移动window窗口可以通过在PhoneWindowManager中强制指定window的显示区域即可, 但我需要的是一个有过渡动画的位移.
查找相关代码发现窗口动画有一个位移的函数:
|--frameworks/base/server/java/com/android/server/wm/WindowManagerService.java
// "Something has changed! Let's make it correct now." private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {...if (w.mHasSurface && w.shouldAnimateMove()) { // Frame has moved, containing content frame // has also moved, and we're not currently animating... // let's do something. Animation a = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.window_move_from_decor); winAnimator.setAnimation(a); winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left; winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top; try { w.mClient.moved(w.mFrame.left, w.mFrame.top); } catch (RemoteException e) { } }...}
|--frameworks/base/core/java/android/view/ViewRootImpl.java
static class W extends IWindow.Stub { ... @Override public void moved(int newX, int newY) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchMoved(newX, newY); } }...} public void dispatchMoved(int newX, int newY) { if (DEBUG_LAYOUT) Log.v(TAG, "Window moved " + this + ": newX=" + newX + " newY=" + newY); if (mTranslator != null) { PointF point = new PointF(newX, newY); mTranslator.translatePointInScreenToAppWindow(point); newX = (int) (point.x + 0.5); newY = (int) (point.y + 0.5); } Message msg = mHandler.obtainMessage(MSG_WINDOW_MOVED, newX, newY); mHandler.sendMessage(msg); } ...case MSG_WINDOW_MOVED: if (mAdded) { final int w = mWinFrame.width(); final int h = mWinFrame.height(); final int l = msg.arg1; final int t = msg.arg2; mWinFrame.left = l; mWinFrame.right = l + w; mWinFrame.top = t; mWinFrame.bottom = t + h; if (mView != null) { forceLayout(mView); } requestLayout(); } break;...private void performTraversals() {}->WindowManagerService.relayoutWindow().->WindowManagerService.performLayoutAndPlaceSurfacesLocked().
|--frameworks/base/service/java/com/android/server/wm/WindowState.java
/** * Return whether this window is wanting to have a translation * animation applied to it for an in-progress move. (Only makes * sense to call from performLayoutAndPlaceSurfacesLockedInner().) */ boolean shouldAnimateMove() {//有可能不满足的一个条件 return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay() && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) && (mAttrs.privateFlags&PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove()); } @Override public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf) { ... if (!mParentFrame.equals(pf)) { //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame // + " to " + pf); mParentFrame.set(pf); mContentChanged = true; } ...}
//也就是说, 只需要pf的值变化, 即可触发.
|--frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
//转了一圈还是回到了这里. /** {@inheritDoc} */ @Override public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, WindowState attached) { ...//AnsonCode 2016.12.21String mapPkg = "com.autonavi.amapauto";if(mapPkg.equals(attrs.packageName) && deadareaSide > 0){/****** resolution 1 //pf parentFrame//vf visibleFrame//df displayFrame//cf contentFrame//of overScanFrame//dcf decorContentFrame************//******** resolution 2 ************///0:off; 5:left; 6:rightint offset = 480;String b = pf.toShortString();if(deadareaSide == 5){pf.left += offset;pf.right += offset;}else if(deadareaSide == 6){pf.left -= offset;pf.right -= offset;}Log.d("ALog", "PhoneWindowManager.layoutWindowLw pfBefore(" + b + "): pfAfter(" + pf.toShortString() + ")");} win.computeFrameLw(pf, df, of, cf, vf, dcf); // Dock windows carve out the bottom of the screen, so normal windows // can't appear underneath them. if (attrs.type == TYPE_INPUT_METHOD && win.isVisibleOrBehindKeyguardLw() && !win.getGivenInsetsPendingLw()) { setLastInputMethodWindowLw(null, null); offsetInputMethodWindowLw(win); } }
OK, 完成
测试流程如下:
新增APP并把主题设置为Theme.Halo.Dialog.
APP打开后会显示在屏幕中间;
通过发送广播告诉PhoneWindowManager, 去修改pf的值.
带过渡动画的位移实现.
0 0
- Android窗口化app位移
- Android - 动画 - 位移 - XML
- android 位移、缩放动画
- Android控件位移
- Android 之 App Widegets(窗口小部件)
- Android 窗口小部件 App Widgets
- Android 窗口小部件--APP Widget
- Android窗口小部件APP Widget
- 浅谈Android之App窗口视图管理
- 窗口快速位移,形成的抖动效果
- 位移
- Android 动画 - TranslateAnimation位移动画
- android 动画之---位移抛物线
- android鼠标位移算法分析。
- Android:Android开发指南-窗口小部件(App Widgets)
- Android开发指南-窗口小部件(App Widgets)
- Android开发指南-窗口小部件(App Widgets)
- Android开发指南-窗口小部件(App Widgets)
- Js 识别 Android 或 Ios
- [Mapbox GL]测量距离
- 一段linux上统计平均响应时间的awk脚本
- Java中使用Jedis操作Redis
- openwrt源码树目录结构简介
- Android窗口化app位移
- React/React Native 的ES5 ES6写法对照表
- oracle 表空间利用率的查询
- Markdown
- 1栈和队列--仅用递归函数和栈操作逆序一个栈
- AI 初学者入门指南:深度学习的五级分类
- Sql语句函数
- MUI 控制安卓手机自带的返回键 禁止返回
- 汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp