在android原生代码中,长按图片中的向前屏切换或者向后屏切换或者中间的那个所有应用的按钮,在其上方就会出现5个小的屏幕缩略图。


由此,我们在launcher的代码里面查找一下,首先,我们要找到onLongClick(View v)这个方法,看下代码:

public boolean onLongClick(View v) {        switch (v.getId()) {            case R.id.previous_screen:                if (!isAllAppsVisible()) {                    mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                    showPreviews(v);                }                return true;            case R.id.next_screen:                if (!isAllAppsVisible()) {                    mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                    showPreviews(v);                }                return true;            case R.id.all_apps_button:                if (!isAllAppsVisible()) {                    mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                    showPreviews(v);                }                return true;                

在这里只截取了代码中的一部分,我们看到,都调用了showPreviews方法。
private void showPreviews(View anchor) {        showPreviews(anchor, 0, mWorkspace.getChildCount());    }    private void showPreviews(final View anchor, int start, int end) {        final Resources resources = getResources();        final Workspace workspace = mWorkspace;        CellLayout cell = ((CellLayout) workspace.getChildAt(start));                float max = workspace.getChildCount();                final Rect r = new Rect();        resources.getDrawable(R.drawable.preview_background).getPadding(r);        int extraW = (int) ((r.left + r.right) * max);        int extraH = r.top + r.bottom;        int aW = cell.getWidth() - extraW;        float w = aW / max;        int width = cell.getWidth();        int height = cell.getHeight();        int x = cell.getLeftPadding();        int y = cell.getTopPadding();        width -= (x + cell.getRightPadding());        height -= (y + cell.getBottomPadding());        float scale = w / width;        int count = end - start;        final float sWidth = width * scale;        float sHeight = height * scale;        LinearLayout preview = new LinearLayout(this);        PreviewTouchHandler handler = new PreviewTouchHandler(anchor);        ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(count);        for (int i = start; i < end; i++) {            ImageView image = new ImageView(this);            cell = (CellLayout) workspace.getChildAt(i);            final Bitmap bitmap = Bitmap.createBitmap((int) sWidth, (int) sHeight,                    Bitmap.Config.ARGB_8888);            final Canvas c = new Canvas(bitmap);            c.scale(scale, scale);            c.translate(-cell.getLeftPadding(), -cell.getTopPadding());            cell.dispatchDraw(c);                        image.setBackgroundDrawable(resources.getDrawable(R.drawable.preview_background));            image.setImageBitmap(bitmap);            image.setTag(i);            image.setOnClickListener(handler);            image.setOnFocusChangeListener(handler);            image.setFocusable(true);            if (i == mWorkspace.getCurrentScreen()) image.requestFocus();            //添加到LinearLayout中            preview.addView(image,                    LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);            //最后添加到ArrayList里面去            bitmaps.add(bitmap);                    }        //把上面的LinearLayout放到PopupWindow中。        final PopupWindow p = new PopupWindow(this);        p.setContentView(preview);        p.setWidth((int) (sWidth * count + extraW));        p.setHeight((int) (sHeight + extraH));        p.setAnimationStyle(R.style.AnimationPreview);        p.setOutsideTouchable(true);        p.setFocusable(true);        p.setBackgroundDrawable(new ColorDrawable(0));        p.showAsDropDown(anchor, 0, 0);        p.setOnDismissListener(new PopupWindow.OnDismissListener() {            public void onDismiss() {                dismissPreview(anchor);            }        });        anchor.setTag(p);        anchor.setTag(R.id.workspace, preview);        anchor.setTag(R.id.icon, bitmaps);            }

方法一共有三个参数,第一个,被点击的View,第二个从第几个开始,第三个是第几个结束。缩略图是从又向坐开始排列的。

在for循环中,是绘制预览图的代码。

 for (int i = start; i < end; i++) {            ImageView image = new ImageView(this);            //获取屏幕            cell = (CellLayout) workspace.getChildAt(i);               //按照上面设定的大小创建一个bitmap            final Bitmap bitmap = Bitmap.createBitmap((int) sWidth, (int) sHeight,             Bitmap.Config.ARGB_8888);             //绘制            final Canvas c = new Canvas(bitmap);             //设置比例             c.scale(scale, scale);             c.translate(-cell.getLeftPadding(), -cell.getTopPadding());             cell.dispatchDraw(c);             //设置image            image.setBackgroundDrawable(resources.getDrawable(R.drawable.preview_background));            image.setImageBitmap(bitmap);            //设置标记            image.setTag(i);            image.setOnClickListener(handler);            image.setOnFocusChangeListener(handler);            image.setFocusable(true);            if (i == mWorkspace.getCurrentScreen()) image.requestFocus();            //添加到LinearLayout中            preview.addView(image,                    LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);            //最后添加到ArrayList里面去            bitmaps.add(bitmap);          bitmaps.add(bitmap); }

在源代码中有很多setTag()和getTag()方法,主要用于标记被点击的View,判断跳转事件时,根据tag里面的信息进行相应的跳转。以上面的代码为例,简单说下setTag():

image.setTag(i);image.setOnClickListener(handler);image.setOnFocusChangeListener(handler);image.setFocusable(true);

我们找到Handler的代码:

class PreviewTouchHandler implements View.OnClickListener, Runnable, View.OnFocusChangeListener {        private final View mAnchor;        public PreviewTouchHandler(View anchor) {            mAnchor = anchor;        }        //响应image的点击事件        public void onClick(View v) {            mWorkspace.snapToScreen((Integer) v.getTag());            v.post(this);        }        public void run() {            dismissPreview(mAnchor);                    }        public void onFocusChange(View v, boolean hasFocus) {            if (hasFocus) {                mWorkspace.snapToScreen((Integer) v.getTag());            }        }    }
当点击image,会触发相应事件,然后是获取image中带的信息,然后跳转到相应屏幕。


更多相关文章

  1. Android(安卓)Studio Error: null, Cannot fit requested classe
  2. 关于Android中传递数据的一些讨论
  3. Intent 详解
  4. android 退出整个程序
  5. Android入门教程(九)之-----取得手机屏幕大小DisplayMetrics的应
  6. Android中Log信息的输出方法
  7. Android(安卓)Asynchronous Http Client-Android异步网络请求客
  8. Android(安卓)自定义View - 启航 一般View定义
  9. Android(安卓)布局 屏幕适配

随机推荐

  1. android之调用webservice 实现图片上传下
  2. Android(安卓)消息推送
  3. android eclipse 真机调试
  4. 【摘录】Google Android操作系统内核编译
  5. Android漫游记(1)---内存映射镜像(memory
  6. Android构建面试知识
  7. Activity启动流程详解
  8. 关于Android的开发经验总结
  9. android之命令行创建AVD
  10. Android(安卓)TTS 实战一:认识 TTS