转载请注明:http://blog.youkuaiyun.com/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);
}
}
本文介绍了一种实现轮播图和图片自动缩放的方法,利用自定义的ImageView和FDraweeView组件,实现了图片的自动切换及缩放功能,并详细展示了其内部实现原理。
3616

被折叠的 条评论
为什么被折叠?



