- 浏览: 5825494 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (890)
- WindowsPhone (0)
- android (88)
- android快速迭代 (17)
- android基础 (34)
- android进阶 (172)
- android高级 (0)
- android拾遗 (85)
- android动画&效果 (68)
- Material Design (13)
- LUA (5)
- j2me (32)
- jQuery (39)
- spring (26)
- hibernate (20)
- struts (26)
- tomcat (9)
- javascript+css+html (62)
- jsp+servlet+javabean (14)
- java (37)
- velocity+FCKeditor (13)
- linux+批处理 (9)
- mysql (19)
- MyEclipse (9)
- ajax (7)
- wap (8)
- j2ee+apache (24)
- 其他 (13)
- phonegap (35)
最新评论
-
Memories_NC:
本地lua脚本终于执行成功了,虽然不是通过redis
java中调用lua脚本语言1 -
ZHOU452840622:
大神://处理返回的接收状态 这个好像没有监听到 遇 ...
android 发送短信的两种方式 -
PXY:
拦截部分地址,怎么写的for(int i=0;i<lis ...
判断是否登录的拦截器SessionFilter -
maotou1988:
Android控件之带清空按钮(功能)的AutoComplet ...
自定义AutoCompleteTextView -
yangmaolinpl:
希望有表例子更好。。。,不过也看明白了。
浅谈onInterceptTouchEvent、onTouchEvent与onTouch
Android_launcher的源码详细分析
http://www.cnblogs.com/playing/archive/2011/04/22/2024980.html
http://www.cnblogs.com/playing/archive/2011/04/22/2024980.html
/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Paint; import android.graphics.PorterDuffColorFilter;源码 import android.graphics.PorterDuff; import android.os.Vibrator; import android.os.SystemClock; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.KeyEvent; import android.widget.FrameLayout; /** * A ViewGroup that coordinated dragging across its dscendants */ public class DragLayer extends FrameLayout implements DragController { private static final int SCROLL_DELAY = 600; private static final int SCROLL_ZONE = 20; private static final int VIBRATE_DURATION = 35; private static final int ANIMATION_SCALE_UP_DURATION = 110; private static final boolean PROFILE_DRAWING_DURING_DRAG = false; // Number of pixels to add to the dragged item for scaling private static final float DRAG_SCALE = 24.0f; private boolean mDragging = false; private boolean mShouldDrop; private float mLastMotionX; private float mLastMotionY; /** * The bitmap that is currently being dragged */ private Bitmap mDragBitmap = null; private View mOriginator; private int mBitmapOffsetX; private int mBitmapOffsetY; /** * X offset from where we touched on the cell to its upper-left corner */ private float mTouchOffsetX; /** * Y offset from where we touched on the cell to its upper-left corner */ private float mTouchOffsetY; /** * Utility rectangle */ private Rect mDragRect = new Rect(); /** * Where the drag originated */ private DragSource mDragSource; /** * The data associated with the object being dragged */ private Object mDragInfo; private final Rect mRect = new Rect(); private final int[] mDropCoordinates = new int[2]; private final Vibrator mVibrator = new Vibrator(); private DragListener mListener; private DragScroller mDragScroller; private static final int SCROLL_OUTSIDE_ZONE = 0; private static final int SCROLL_WAITING_IN_ZONE = 1; private static final int SCROLL_LEFT = 0; private static final int SCROLL_RIGHT = 1; private int mScrollState = SCROLL_OUTSIDE_ZONE; private ScrollRunnable mScrollRunnable = new ScrollRunnable(); private View mIgnoredDropTarget; private RectF mDragRegion; private boolean mEnteredRegion; private DropTarget mLastDropTarget; private final Paint mTrashPaint = new Paint(); private Paint mDragPaint; private static final int ANIMATION_STATE_STARTING = 1; private static final int ANIMATION_STATE_RUNNING = 2; private static final int ANIMATION_STATE_DONE = 3; private static final int ANIMATION_TYPE_SCALE = 1; private float mAnimationFrom; private float mAnimationTo; private int mAnimationDuration; private long mAnimationStartTime; private int mAnimationType; private int mAnimationState = ANIMATION_STATE_DONE; /** * Used to create a new DragLayer from XML. * * @param context The application's context. * @param attrs The attribtues set containing the Workspace's customization values. */ public DragLayer(Context context, AttributeSet attrs) { super(context, attrs); final int srcColor = context.getResources().getColor(R.color.delete_color_filter); mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP)); } public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) { if (PROFILE_DRAWING_DURING_DRAG) { android.os.Debug.startMethodTracing("Launcher"); } if (mListener != null) { mListener.onDragStart(v, source, dragInfo, dragAction); } Rect r = mDragRect; r.set(v.getScrollX(), v.getScrollY(), 0, 0); offsetDescendantRectToMyCoords(v, r); mTouchOffsetX = mLastMotionX - r.left; mTouchOffsetY = mLastMotionY - r.top; v.clearFocus(); v.setPressed(false); boolean willNotCache = v.willNotCacheDrawing(); v.setWillNotCacheDrawing(false); v.buildDrawingCache(); Bitmap viewBitmap = v.getDrawingCache(); int width = viewBitmap.getWidth(); int height = viewBitmap.getHeight(); Matrix scale = new Matrix(); float scaleFactor = v.getWidth(); scaleFactor = (scaleFactor + DRAG_SCALE) /scaleFactor; scale.setScale(scaleFactor, scaleFactor); mAnimationTo = 1.0f; mAnimationFrom = 1.0f / scaleFactor; mAnimationDuration = ANIMATION_SCALE_UP_DURATION; mAnimationState = ANIMATION_STATE_STARTING; mAnimationType = ANIMATION_TYPE_SCALE; mDragBitmap = Bitmap.createBitmap(viewBitmap, 0, 0, width, height, scale, true); v.destroyDrawingCache(); v.setWillNotCacheDrawing(willNotCache); final Bitmap dragBitmap = mDragBitmap; mBitmapOffsetX = (dragBitmap.getWidth() - width) / 2; mBitmapOffsetY = (dragBitmap.getHeight() - height) / 2; if (dragAction == DRAG_ACTION_MOVE) { v.setVisibility(GONE); } mDragPaint = null; mDragging = true; mShouldDrop = true; mOriginator = v; mDragSource = source; mDragInfo = dragInfo; mVibrator.vibrate(VIBRATE_DURATION); mEnteredRegion = false; invalidate(); } @Override public boolean dispatchKeyEvent(KeyEvent event) { return mDragging || super.dispatchKeyEvent(event); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mDragging && mDragBitmap != null) { if (mAnimationState == ANIMATION_STATE_STARTING) { mAnimationStartTime = SystemClock.uptimeMillis(); mAnimationState = ANIMATION_STATE_RUNNING; } if (mAnimationState == ANIMATION_STATE_RUNNING) { float normalized = (float) (SystemClock.uptimeMillis() - mAnimationStartTime) / mAnimationDuration; if (normalized >= 1.0f) { mAnimationState = ANIMATION_STATE_DONE; } normalized = Math.min(normalized, 1.0f); final float value = mAnimationFrom + (mAnimationTo - mAnimationFrom) * normalized; switch (mAnimationType) { case ANIMATION_TYPE_SCALE: final Bitmap dragBitmap = mDragBitmap; canvas.save(); canvas.translate(mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY); canvas.translate((dragBitmap.getWidth() * (1.0f - value)) / 2, (dragBitmap.getHeight() * (1.0f - value)) / 2); canvas.scale(value, value); canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint); canvas.restore(); break; } } else { canvas.drawBitmap(mDragBitmap, mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX, mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY, mDragPaint); } } } private void endDrag() { if (mDragging) { mDragging = false; if (mDragBitmap != null) { mDragBitmap.recycle(); } if (mOriginator != null) { mOriginator.setVisibility(VISIBLE); } if (mListener != null) { mListener.onDragEnd(); } } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); final float x = ev.getX(); final float y = ev.getY(); switch (action) { case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_DOWN: // Remember location of down touch mLastMotionX = x; mLastMotionY = y; mLastDropTarget = null; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (mShouldDrop && drop(x, y)) { mShouldDrop = false; } endDrag(); break; } return mDragging; } @Override public boolean onTouchEvent(MotionEvent ev) { if (!mDragging) { return false; } final int action = ev.getAction(); final float x = ev.getX(); final float y = ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: // Remember where the motion event started mLastMotionX = x; mLastMotionY = y; if ((x < SCROLL_ZONE) || (x > getWidth() - SCROLL_ZONE)) { mScrollState = SCROLL_WAITING_IN_ZONE; postDelayed(mScrollRunnable, SCROLL_DELAY); } else { mScrollState = SCROLL_OUTSIDE_ZONE; } break; case MotionEvent.ACTION_MOVE: if (Launcher.sOpenGlEnabled) { mLastMotionX = x; mLastMotionY = y; invalidate(); } else { final int scrollX = mScrollX; final int scrollY = mScrollY; final float touchX = mTouchOffsetX; final float touchY = mTouchOffsetY; final int offsetX = mBitmapOffsetX; final int offsetY = mBitmapOffsetY; int left = (int) (scrollX + mLastMotionX - touchX - offsetX); int top = (int) (scrollY + mLastMotionY - touchY - offsetY); final Bitmap dragBitmap = mDragBitmap; final int width = dragBitmap.getWidth(); final int height = dragBitmap.getHeight(); final Rect rect = mRect; rect.set(left - 1, top - 1, left + width + 1, top + height + 1); mLastMotionX = x; mLastMotionY = y; left = (int) (scrollX + x - touchX - offsetX); top = (int) (scrollY + y - touchY - offsetY); rect.union(left - 1, top - 1, left + width + 1, top + height + 1); invalidate(rect); } final int[] coordinates = mDropCoordinates; DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); if (dropTarget != null) { if (mLastDropTarget == dropTarget) { dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); } else { if (mLastDropTarget != null) { mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); } dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); } } else { if (mLastDropTarget != null) { mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); } } mLastDropTarget = dropTarget; boolean inDragRegion = false; if (mDragRegion != null) { final RectF region = mDragRegion; final boolean inRegion = region.contains(ev.getRawX(), ev.getRawY()); if (!mEnteredRegion && inRegion) { mDragPaint = mTrashPaint; mEnteredRegion = true; inDragRegion = true; } else if (mEnteredRegion && !inRegion) { mDragPaint = null; mEnteredRegion = false; } } if (!inDragRegion && x < SCROLL_ZONE) { if (mScrollState == SCROLL_OUTSIDE_ZONE) { mScrollState = SCROLL_WAITING_IN_ZONE; mScrollRunnable.setDirection(SCROLL_LEFT); postDelayed(mScrollRunnable, SCROLL_DELAY); } } else if (!inDragRegion && x > getWidth() - SCROLL_ZONE) { if (mScrollState == SCROLL_OUTSIDE_ZONE) { mScrollState = SCROLL_WAITING_IN_ZONE; mScrollRunnable.setDirection(SCROLL_RIGHT); postDelayed(mScrollRunnable, SCROLL_DELAY); } } else { if (mScrollState == SCROLL_WAITING_IN_ZONE) { mScrollState = SCROLL_OUTSIDE_ZONE; mScrollRunnable.setDirection(SCROLL_RIGHT); removeCallbacks(mScrollRunnable); } } break; case MotionEvent.ACTION_UP: removeCallbacks(mScrollRunnable); if (mShouldDrop) { drop(x, y); mShouldDrop = false; } endDrag(); break; case MotionEvent.ACTION_CANCEL: endDrag(); } return true; } private boolean drop(float x, float y) { invalidate(); final int[] coordinates = mDropCoordinates; DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); if (dropTarget != null) { dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo)) { dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo); mDragSource.onDropCompleted((View) dropTarget, true); return true; } else { mDragSource.onDropCompleted((View) dropTarget, false); return true; } } return false; } DropTarget findDropTarget(int x, int y, int[] dropCoordinates) { return findDropTarget(this, x, y, dropCoordinates); } private DropTarget findDropTarget(ViewGroup container, int x, int y, int[] dropCoordinates) { final Rect r = mDragRect; final int count = container.getChildCount(); final int scrolledX = x + container.getScrollX(); final int scrolledY = y + container.getScrollY(); final View ignoredDropTarget = mIgnoredDropTarget; for (int i = count - 1; i >= 0; i--) { final View child = container.getChildAt(i); if (child.getVisibility() == VISIBLE && child != ignoredDropTarget) { child.getHitRect(r); if (r.contains(scrolledX, scrolledY)) { DropTarget target = null; if (child instanceof ViewGroup) { x = scrolledX - child.getLeft(); y = scrolledY - child.getTop(); target = findDropTarget((ViewGroup) child, x, y, dropCoordinates); } if (target == null) { if (child instanceof DropTarget) { dropCoordinates[0] = x; dropCoordinates[1] = y; return (DropTarget) child; } } else { return target; } } } } return null; } public void setDragScoller(DragScroller scroller) { mDragScroller = scroller; } public void setDragListener(DragListener l) { mListener = l; } public void removeDragListener(DragListener l) { mListener = null; } /** * Specifies the view that must be ignored when looking for a drop target. * * @param view The view that will not be taken into account while looking * for a drop target. */ void setIgnoredDropTarget(View view) { mIgnoredDropTarget = view; } /** * Specifies the delete region. * * @param region The rectangle in screen coordinates of the delete region. */ void setDeleteRegion(RectF region) { mDragRegion = region; } private class ScrollRunnable implements Runnable { private int mDirection; ScrollRunnable() { } public void run() { if (mDragScroller != null) { if (mDirection == SCROLL_LEFT) { mDragScroller.scrollLeft(); } else { mDragScroller.scrollRight(); } mScrollState = SCROLL_OUTSIDE_ZONE; } } void setDirection(int direction) { mDirection = direction; } } }
发表评论
-
NestedScrollView滚动到顶部固定子View悬停挂靠粘在顶端
2018-10-31 20:45 7011网上有一个StickyScrollView,称之为粘性Scro ... -
自定义Behavior实现AppBarLayout越界弹性效果
2017-03-31 09:33 10384一、继承AppBarLayout.Beha ... -
Android - 一种相似图片搜索算法的实现
2017-03-31 09:33 2631算法 缩小尺寸。 将图片缩小到8x8的尺寸,总共64个 ... -
使用SpringAnimation实现带下拉弹簧动画的 ScrollView
2017-03-30 11:30 2857在刚推出的 Support Library 25.3.0 里面 ... -
Android为应用添加角标(Badge)
2017-03-30 11:21 61951.需求简介 角标是什么意思呢? 看下图即可明了: 可 ... -
Android端与笔记本利用局域网进行FTP通信
2017-03-23 10:17 988先看图 打开前: 打开后: Activity类 ... -
PorterDuffColorFilter 在项目中的基本使用
2017-03-03 10:58 1361有时候标题栏会浮在内容之上,而内容会有颜色的变化,这时候就要求 ... -
ColorAnimationView 实现了滑动Viewpager 时背景色动态变化的过渡效果
2017-02-24 09:41 2230用法在注释中: import android.anima ... -
迷你轻量级全方向完美滑动处理侧滑控件SlideLayout
2017-01-16 16:53 2602纯手工超级迷你轻量级全方向完美滑动处理侧滑控件(比官方 sup ... -
Effect
2017-01-05 09:57 0https://github.com/JetradarMobi ... -
动态主题库Colorful,容易地改变App的配色方案
2016-12-27 14:49 2572Colorful是一个动态主题库,允许您很容易地改变App的配 ... -
对视图的对角线切割DiagonalView
2016-12-27 14:23 1126提供对视图的对角线切割,具有很好的用户定制 基本用法 ... -
仿淘宝京东拖拽商品详情页上下滚动黏滞效果
2016-12-26 16:53 3505比较常用的效果,有现成的,如此甚好!:) import ... -
让任意view具有滑动效果的SlideUp
2016-12-26 09:26 1712基本的类,只有一个: import android.a ... -
AdvancedWebView
2016-12-21 09:44 16https://github.com/delight-im/A ... -
可设置圆角背景边框的按钮, 通过调节色彩明度自动计算按下(pressed)状态颜色
2016-11-02 22:13 1931可设置圆角背景边框的的按钮, 通过调节色彩明度自动计算按下(p ... -
网络请求库相关
2016-10-09 09:35 62https://github.com/amitshekhari ... -
ASimpleCache一个简单的缓存框架
2015-10-26 22:53 2185ASimpleCache 是一个为android制定的 轻量级 ... -
使用ViewDragHelper实现的DragLayout开门效果
2015-10-23 10:55 3424先看一下图,有个直观的了解,向下拖动handle就“开门了”: ... -
保证图片长宽比的同时拉伸图片ImageView
2015-10-16 15:40 3740按比例放大图片,不拉伸失真 import android. ...
相关推荐
Android Launcher 源码详解 Android Launcher 是 Android 系统中一个非常重要的组件,负责显示桌面程序和管理应用程序图标。了解 Launcher 的源码可以帮助我们更好地理解 Android 系统的设计思想和实现机制。本文...
《深入剖析Android应用源码:聚焦Launcher2》 在Android操作系统中,Launcher是用户与系统交互的首要界面,它负责展示应用图标、快捷方式以及桌面小部件等。本篇文章将详细探讨Android应用源码中的Launcher2,这是...
`Launcher2`包含许多自定义视图,如`QuickStepView`(快速启动栏)、`DragLayer`(拖放层)等,它们扩展了Android的基础视图类,以满足特定需求。 ### 6. 广播接收器与服务 `BroadcastReceiver`用于监听系统广播,...
该源码分析了 Android_launcher 的主要组件和类,包括 Launcher.java、DragLayer.java、DragController.java、LauncherModel.java、Workspace.java、LauncherProvider.java、CellLayout.java、ItemInfo.java、User...
《深入剖析Android 4.0 Launcher源码》 在Android世界中,Launcher是用户与操作系统交互的首要界面,它承担着展示应用图标、快捷方式、主屏幕小部件等任务。对于开发者来说,研究Launcher的源码是理解Android系统...
理解并分析Launcher3的源码对于开发者来说具有重要意义,可以帮助我们深入理解Android系统的运行机制,定制个性化桌面,或者开发自己的启动器应用。 首先,我们需要从官方AOSP(Android Open Source Project)仓库...
深入理解Android Launcher的源码可以帮助开发者更好地定制系统桌面,优化用户体验,或者开发自定义启动器应用。本文将详细探讨Android桌面程序Launcher的相关知识点。 首先,我们来看看Launcher的基本架构。Android...
在Android 2.3(Gingerbread)版本中,Launcher源码提供了对主屏幕、应用抽屉、快捷方式和小部件等核心功能的实现。理解其源码有助于开发者深入掌握Android系统的运行机制,优化自定义Launcher或者进行桌面插件的...
5. **Drag and Drop**: Android桌面支持拖放操作,实现这一功能的关键是`DragLayer`和`DragController`。这些组件负责处理触摸事件,进行拖放操作,并更新UI。 6. **动画和过渡**: Android Launcher中的动画和过渡...
《Android 2.3 Launcher 源码解析》 Android 2.3,又被称为 Gingerbread,是Android操作系统的一个重要版本。在这个版本中,Launcher作为系统的核心组件之一,扮演着用户与系统交互的重要角色。Launcher,简单来说...
《深入解析Android 4.1 Launcher2源码与Eclipse编译》 在Android系统中,Launcher作为用户界面的核心部分,扮演着启动应用、管理桌面快捷方式和小部件的重要角色。在Android 4.1(代号Jelly Bean)版本中,Launcher...
这个源码版本对应的是Android 2.2(Froyo)系统,对于开发者来说,深入理解这个源码可以帮助他们自定义启动器、优化性能或者开发新的桌面功能。 一、Launcher2的架构 Launcher2 是一个基于Android Activity的组件...
《深入剖析Android 4.0 Launcher源码》 在Android操作系统中,Launcher是用户与系统交互的首要界面,也就是我们通常所说的桌面。它负责显示应用快捷方式、小部件以及主屏幕。本文将深入探讨Android 4.0 (Ice Cream ...
《深入解析Android 4.0 Launcher源码》 在Android操作系统中,Launcher是用户与系统交互的首要界面,它负责展示应用图标、桌面小部件以及管理屏幕。Android 4.0(Ice Cream Sandwich,简称ICS)是Android系统的一个...
Android 8.0引入了更流畅的过渡动画,这在`DragLayer`和`DropTarget`类中体现。通过`PropertyAnimator`实现平滑的拖放效果。 8. **个性化设置** 用户可以通过系统设置自定义Launcher3的壁纸、图标大小、网格布局...
Android 7.1 Launcher源码解析 Android 7.1的Launcher是系统桌面应用,它负责展示应用程序快捷方式、小部件以及主屏幕布局。深入理解其源码有助于开发者定制个性化启动器,提升用户体验,或者为自己的应用开发提供...
在Android 2.3(Gingerbread)版本中,Launcher的源码提供了深入理解Android系统启动流程、界面定制以及应用程序管理机制的机会。让我们一起探索这个源码中的关键知识点。 1. **Android启动流程**: - `...
以下是对 Android 4.0 Launcher2 源码的关键知识点的详细解析: 1. **组件结构**: - `Launcher` 类是 Launcher2 的核心,它是 Android 应用程序的基础组件,继承自 `Activity`。 - `Workspace` 和 `Hotseat` ...
《Android Launcher2.1源码解析与运行指南》 Android Launcher是系统启动器,它是用户与设备交互的首要界面,负责展示应用图标、桌面小部件等。本篇将深入探讨"android launcher2.1源码",并指导如何运行这个经过...
《Android 2.3.3 Launcher源码解析》 Android 2.3.3,代号Gingerbread,是Google发布的Android系统的一个重要版本。在这个版本中,Launcher作为用户界面的核心部分,负责呈现桌面图标、小部件以及启动应用程序。...