海报组的ImageView

转载请注明:http://blog.csdn.net/feather_wch/article/details/79585803

ImageView控件实现效果:设置一组图片或者url能在指定时间间隔内,不断循环切换,达到一组海报自动切换的功能。

具体内容只是初稿,还未完成,勿看!

ImageView和自定义ImageLoader的实现版本:

/**
 * @Tips: When you don't need this ImageView, must call clean() method.
 * If you dont't do this, your programe will have many unuseful threads.
 */
public class CarouselImageView extends GifImageView {

    private static final String TAG = CarouselImageView.class.getName();
    private static final int WIDTH_HEIGHT_DEFAULT = 500;

    private ArrayList<String> mUrlArray = new ArrayList<>(); //存储Url数组用于
    private ImageLoader mImageLoader;
    private int mTimeMs = 0;//毫秒
    private boolean isAlive = true;
    private int mWidth = WIDTH_HEIGHT_DEFAULT;
    private int mHeight = WIDTH_HEIGHT_DEFAULT;

    private float mScaleX = 1;
    private float mScaleY = 1;

    //1. 缩放所需要的时间,为了性能限定为 > 10(10ms刷新一次)
    private int mScaleTimeMs = 0;
    //2. 放大倍数
    private float mMagnification = 1.0f;

    //cpu核心数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    //cpu核心线程数
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    //cpu最大线程数
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    //线程超时时长
    private static final long KEEP_ALIVE = 10L;
    //线程工厂
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "imageLoader#" + mCount.getAndIncrement());
        }
    };
    //线程池
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAXIMUM_POOL_SIZE,
            KEEP_ALIVE,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(),
            sThreadFactory);

    //4-主线程Handler
    private Handler mMainHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_SET_IMAGE:
                    String url = (String) msg.obj;
                    mImageLoader.bindBitmap(url, CarouselImageView.this, mWidth, mHeight);
                    break;
                case MESSAGE_SCALE_IMAGE: {
                    Matrix matrix = new Matrix();
                    matrix.setScale(mScaleX, mScaleY, getWidth() / 2, getHeight() / 2);
                    CarouselImageView.this.setImageMatrix(matrix);
                    break;
                }
            }
        }
    };

    private static final int MESSAGE_SET_IMAGE = 1;
    private static final int MESSAGE_SCALE_IMAGE = 2;

    public CarouselImageView(Context context) {
        super(context);
        mImageLoader = new ImageLoader(context);
    }

    public CarouselImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mImageLoader = new ImageLoader(context);
    }

    public CarouselImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mImageLoader = new ImageLoader(context);
    }

    public CarouselImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mImageLoader = new ImageLoader(context);
    }

    public CarouselImageView setWidthHeight(int width, int height) {
        mWidth = width;
        mHeight = height;
        return this;
    }

    public CarouselImageView setTimeMs(int times) {
        mTimeMs = times;
        return this;
    }

    public CarouselImageView setScaleTimeMs(int times) {
        mScaleTimeMs = times;
        return this;
    }

    public CarouselImageView setImageUrls(ArrayList<String> urlArray) {
        mUrlArray = urlArray;
        return this;
    }

    public CarouselImageView setUrl(String url) {
        mUrlArray.add(0, url);
        return this;
    }

    public CarouselImageView setMagnification(float mMagnification) {
        this.mMagnification = mMagnification;
        return this;
    }

    public void commit() {
        Runnable carousel = new Runnable() {
            @Override
            public void run() {
                if (mTimeMs > 0) {
                    while (isAlive) {
                        for (String url : mUrlArray) {
                            if (!isAlive) {
                                return;
                            }
                            mMainHandler.obtainMessage(MESSAGE_SET_IMAGE, url).sendToTarget();
                            try {
                                Thread.sleep(mTimeMs);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        };
        THREAD_POOL_EXECUTOR.execute(carousel);
    }

    public void clean() {
        isAlive = false;
//        Log.i(TAG, "clean");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        isAlive = false;
//        Log.i(TAG, "finalize");
    }

    public void startScale() {
        Runnable carousel = new Runnable() {
            @Override
            public void run() {
                int count = mScaleTimeMs / 10;
                if(count == 0){
                    count = 1;
                }
                float everyScale = (mMagnification - 1.0f) / count;
                for(int i = 0; i < count; i++){
                    mScaleX += everyScale;
                    mScaleY += everyScale;
                    mMainHandler.obtainMessage(MESSAGE_SCALE_IMAGE).sendToTarget();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        THREAD_POOL_EXECUTOR.execute(carousel);
    }

    public void startScale(final boolean isCarousel) {
        this.setScaleType(ImageView.ScaleType.MATRIX);
        Runnable carousel = new Runnable() {
            @Override
            public void run() {
                if (mScaleTimeMs > 0) {
                    int whichUrl = 0;
                    while (isAlive) {
                        int count = mScaleTimeMs / 10;
                        mScaleX = 1f;
                        mScaleY = 1f;
                        if(count == 0){
                            count = 1;
                        }
                        float everyScale = (mMagnification - 1.0f) / count;

                        if(mUrlArray != null && mUrlArray.size() > 0){
                            //通过url组设置的图片, 否则直接是用户给ImageView设置的图片进行切换
                            String url = mUrlArray.get(whichUrl);
                            whichUrl++;
                            if(whichUrl == mUrlArray.size()){
                                whichUrl = 0;
                            }
                            mMainHandler.obtainMessage(MESSAGE_SET_IMAGE, url).sendToTarget();
                        }

                        for(int i = 0; i < count; i++){
                            mScaleX += everyScale;
                            mScaleY += everyScale;
                            mMainHandler.obtainMessage(MESSAGE_SCALE_IMAGE).sendToTarget();
                            try {
                                Thread.sleep(10);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //不轮播就return
                        if(isCarousel == false){
                            return;
                        }
                    }
                }
            }
        };
        THREAD_POOL_EXECUTOR.execute(carousel);
    }



}

Facebook的开源库Fresco的实现版本:

public class FDraweeView extends SimpleDraweeView{
    private static final String TAG = FDraweeView.class.getName();

    private ArrayList<String> mUrlArray = new ArrayList<>(); //存储Url数组用于
    private boolean isAlive = true;

    private Matrix mCurrentMatrix;

    private float mScaleX = 1;
    private float mScaleY = 1;

    //1. 缩放所需要的时间,为了性能限定为 > 10(10ms刷新一次)
    private int mScaleTimeMs = 0;
    //2. 放大倍数
    private float mMagnification = 1.0f;

    //cpu核心数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    //cpu核心线程数
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    //cpu最大线程数
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    //线程超时时长
    private static final long KEEP_ALIVE = 10L;
    //线程工厂
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "imageLoader#" + mCount.getAndIncrement());
        }
    };
    //线程池
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAXIMUM_POOL_SIZE,
            KEEP_ALIVE,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(),
            sThreadFactory);

    //4-主线程Handler
    private Handler mMainHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_SET_IMAGE:
                    String url = (String) msg.obj;
                    FDraweeView.this.setImageURI(url);
                    break;
                case MESSAGE_SCALE_IMAGE: {
                    invalidate();
                    break;
                }
            }
        }
    };

    @Override
    protected void onDraw(Canvas canvas) {
        int saveCount = canvas.save();
        canvas.concat(mCurrentMatrix);
        super.onDraw(canvas);
        canvas.restoreToCount(saveCount);
    }

    private static final int MESSAGE_SET_IMAGE = 1;
    private static final int MESSAGE_SCALE_IMAGE = 2;

    public FDraweeView(Context context) {
        super(context);
        mCurrentMatrix = new Matrix();
    }

    public FDraweeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mCurrentMatrix = new Matrix();
    }

    public FDraweeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mCurrentMatrix = new Matrix();
    }

    public FDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mCurrentMatrix = new Matrix();
    }

    public FDraweeView setScaleTimeMs(int times) {
        mScaleTimeMs = times;
        return this;
    }

    public FDraweeView setImageUrls(ArrayList<String> urlArray) {
        mUrlArray = urlArray;
        return this;
    }

    public FDraweeView setUrl(String url) {
        mUrlArray.add(0, url);
        return this;
    }

    public FDraweeView setMagnification(float mMagnification) {
        this.mMagnification = mMagnification;
        return this;
    }

    public void clean() {
        isAlive = false;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        isAlive = false;
    }

    public void startScale(final boolean isCarousel) {
        Runnable carousel = new Runnable() {
            @Override
            public void run() {
                if (mScaleTimeMs > 0) {
                    int whichUrl = 0;
                    while (isAlive) {
                        int count = mScaleTimeMs / 20;
//                        mCurrentMatrix.reset();
                        mScaleX = 1f;
                        mScaleY = 1f;
                        if(count == 0){
                            count = 1;
                        }
                        float everyScale = (mMagnification - 1.0f) / count;

                        if(mUrlArray != null && mUrlArray.size() > 0){
                            //通过url组设置的图片, 否则直接是用户给ImageView设置的图片进行切换
                            String url = mUrlArray.get(whichUrl);
                            whichUrl++;
                            if(whichUrl == mUrlArray.size()){
                                whichUrl = 0;
                            }
                            mMainHandler.obtainMessage(MESSAGE_SET_IMAGE, url).sendToTarget();
                        }

                        for(int i = 0; i < count; i++){
                            mScaleX += everyScale;
                            mScaleY += everyScale;
                            mCurrentMatrix.reset();
                            mCurrentMatrix.postScale(mScaleX, mScaleY, getWidth() / 2f, getHeight() / 2f);
                            mMainHandler.obtainMessage(MESSAGE_SCALE_IMAGE).sendToTarget();
                            try {
                                Thread.sleep(20);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //不轮播就return
                        if(isCarousel == false){
                            return;
                        }
                    }
                }
            }
        };
        THREAD_POOL_EXECUTOR.execute(carousel);
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值