设为首页 加入收藏

TOP

优质Android小部件:索尼滚动相册(一)
2017-10-13 10:30:50 】 浏览:10144
Tags:优质 Android 部件 索尼 滚动 相册

  虽然骚尼手机卖的不怎么样,但是有些东西还是做的挺好的,工业设计就不用说了,索尼的相册的双指任意缩放功能也是尤其炫酷。其桌面小部件滚动相册我觉得也挺好的,比谷歌原生的相册墙功能好多了,网上搜了一下也没发现有人写这个,于是,下面就介绍下我的高A货。

首先是效果图:

    

主要手势操作有:

  1. 上/下满速移动,可以上滑/下滑一张图片
  2. 上/下快读移动,则根据滑动速度,上滑/下滑多张图片
  3. 单击则请求系统图库展示该图片

  该小部件的主要优点:在屏幕内的小范围内提供一个很好的图片选择/浏览部件,尤其是切换图片时有很强的靠近/远离动画感,增加好感。

代码分析

  刚开始想这个小部件的时候以为是利用多个ImageView叠加实现的效果,例如谷歌原生的该部件就是利用多个ImageView叠加形成的,但是效果远比不上这个。但觉得通过多个ImageView叠加可能会没这么流畅,性能上也不好。该效果本身也比较规律,应该可以通过一个View来实现,达到更好的性能。于是通过View Hierarchy分析,sony这个果然是通过一个View实现的,于是通过如下方式这个小部件。

  代码主要由三个部分组成:

  • RollImageView:实际的View
  • CellCalculater:用来实时计算每张图片的绘制区域以及透明度,这个是本小部件的核心部件。接口定义如下:  
    /**
     * get all rects for drawing image
     * @return
     */
    public Cell[] getCells();

    /**
     *
     * @param distance the motion distance during the period from ACTION_DOWN to this moment
     * @return 0 means no roll, positive number means roll forward and negative means roll backward
     */
    public int setStatus(float distance);


    /**
     * set the dimen of view
     * @param widht
     * @param height
     */
    public void setDimen(int widht, int height);

    /**
     * set to the status for static
     */
    public void setStatic();
View Code
  • ImageLoader:用来加载图片,提供Bitmap给RollImageView绘制。接口定义如下:  
    /**
     * the images shown roll forward
     */
    public void rollForward();

    /**
     * the images shown roll backward
     */
    public void rollBackward();

    /**
     * get bitmaps
     * @return
     */
    public Bitmap[] getBitmap();

    /**
     * use invalidate to invalidate the view
     * @param invalidate
     */
    public void setInvalidate(RollImageView.InvalidateView invalidate);

    /**
     * set the dimen of view
     * @param width
     * @param height
     */
    public void setDimen(int width, int height);


    /**
     * the image path to be show
     * @param paths
     */
    public void setImagePaths(List<String> paths);

    /**
     * get large bitmap while static
     */
    public void loadCurrentLargeBitmap();
View Code

  下面分析每个部分的核心代码。

RollImageView

  View的主要职责是draw各个bitmap以及响应用户的手势操作,相对比较简单。

  绘制部分就是把从ImageLoader获得的的各个Bitmap按照从CellCalculater中获得的绘制区域以及透明度绘制到屏幕上,目前本代码实现的比较简单,没有考虑不同尺寸的图片需要进行一些更加协调的显示方式,比如像ImageView.ScaleType中定义的一些显示方式。  

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Bitmap[] bitmaps = mImageLoader.getBitmap();
        Cell[] cells = mCellCalculator.getCells();  //得到每张Image的显示区域与透明度
        canvas.translate(getWidth() / 2, 0);
        for (int i = SHOW_CNT - 1; i >= 0; i--) { //从最底层的Image开始绘制
            Bitmap bitmap = bitmaps[i];
            Cell cell = cells[i];
            if (bitmap != null && !bitmap.isRecycled()) {
                mPaint.setAlpha(cell.getAlpha());
                LOG("ondraw " + i + bitmap.getWidth() + " " + cell.getRectF() + " alpha " + cell.getAlpha());
                canvas.drawBitmap(bitmap, null, cell.getRectF(), mPaint);
            }
        }
    }

  手势部分采用了GestureListener,主要代码如下:  

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getPointerCount() > 1) {
            return false;
        }
        mGestureDetector.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:  //这里主要用于处理没有触发Fling事件时,使界面保持没有移动的状态
                if(!mIsFling){
                    if(mRollResult == CellCalculator.ROLL_FORWARD){
                        mImageLoader.rollForward();
                    } else if (mRollResult == CellCalculator.ROLL_BACKWARD && !mScrollRollBack){
                        mImageLoader.rollBackward();
                    }
                    LOG("OnGestureListener ACTION_UP setstatic "
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android 高级面试题及答案 下一篇Android防微信首页左右滑动切换

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目