package com.duguang.baseanimation.ui.flip.issue5;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.net.URLConnection;
import junit.framework.Assert;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.aphidmobile.flip.FlipViewController;
import com.aphidmobile.utils.AphidLog;
import com.aphidmobile.utils.IO;
import com.duguang.baseanimation.R;
/**
* Modified from the issue#5 comment contributed by @cagkanciloglu <p/> Only corrected its async
* loading logic, although its layout hierarchy can be optimized too.
*/
public class GalleryFlipItem extends LinearLayout {
/**
* Borrowed from the official BitmapFun tutorial: http://developer.android.com/training/displaying-bitmaps/index.html
*/
private static final class AsyncDrawable extends BitmapDrawable {
private final WeakReference<ContentPhotosDownloader> taskRef;
public AsyncDrawable(Resources res, Bitmap bitmap, ContentPhotosDownloader task) {
super(res, bitmap);
this.taskRef = new WeakReference<ContentPhotosDownloader>(task);
}
public static ContentPhotosDownloader getTask(ImageView imageView) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
return ((AsyncDrawable) drawable).taskRef.get();
}
return null;
}
}
//Change to a static inner class from a normal inner class, otherwise it may holds a strong reference to GalleryFlipItem, which is not a good practise for AsyncTask
private static class ContentPhotosDownloader extends AsyncTask<Void, Void, Bitmap> {
private String url;
private WeakReference<FlipViewController> controllerRef;
//Use WeakReference
private WeakReference<ImageView> imgViewRef;
private WeakReference<ProgressBar> progressBarRef;
private int pageIndex;
private boolean hideProgress;
public ContentPhotosDownloader(String url, ImageView imgView, ProgressBar progressBar,
FlipViewController controller, int pageIndex) {
Assert.assertNotNull(url);
Assert.assertNotNull(imgView);
Assert.assertNotNull(controller);
//progressBar can be null
this.url = url;
this.imgViewRef = new WeakReference<ImageView>(imgView);
this.controllerRef = new WeakReference<FlipViewController>(controller);
this.pageIndex = pageIndex;
if (progressBar != null) {
progressBarRef = new WeakReference<ProgressBar>(progressBar);
}
}
public String getUrl() {
return url;
}
public int getPageIndex() {
return pageIndex;
}
private ProgressBar getProgressBar() {
return progressBarRef != null ? progressBarRef.get() : null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
ProgressBar bar = getProgressBar();
if (bar != null) {
bar.setVisibility(View.VISIBLE);
ImageView iv = imgViewRef.get();
if (iv != null) {
iv.setVisibility(GONE);
}
}
//Commented out; pd and imgBackground should not be accessed directly
/*
pd.setVisibility(View.VISIBLE);
imgBackground.setVisibility(View.GONE);
*/
}
@Override
protected Bitmap doInBackground(Void... params) {
InputStream is = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
is = new BufferedInputStream(conn.getInputStream());
return BitmapFactory.decodeStream(is);
} catch (IOException e) {
AphidLog.e(e, "Failed to load bitmap from url: " + url);
} finally {
IO.close(is);
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
if (isCancelled()) {
return;
}
ImageView imgView = imgViewRef.get();
if (imgView != null && AsyncDrawable.getTask(imgView)
== this) { //make sure the ImageView instance has not been reused for another page
if (result != null) {
imgView.setImageBitmap(result);
imgView.setVisibility(View.VISIBLE);
}
ProgressBar bar = getProgressBar();
if (bar != null) {
bar.setVisibility(View.GONE);
}
FlipViewController controller = controllerRef.get();
if (controller != null) {
controller.refreshPage(pageIndex);
}
}
}
}
public GalleryPage mGalleryPage;
private ImageView imgBackground;
private ProgressBar pd;
private LinearLayout lnlPlace;
private ImageView imgIcon;
private TextView txtName;
private TextView txtDistrict;
private TextView txtCity;
private Context mContext;
public void refreshView(GalleryPage mGalleryPage, FlipViewController controller, int pageIndex) {
this.mGalleryPage = mGalleryPage;
if (shouldStartAsyncLoad(imgIcon, mGalleryPage.getTargetURL(), pageIndex)) {
ContentPhotosDownloader
downloader =
new ContentPhotosDownloader(mGalleryPage.getTargetURL(), imgIcon, null, controller,
pageIndex);
imgIcon.setImageDrawable(new AsyncDrawable(getResources(), null, downloader));
downloader.execute();
}
txtName.setText(this.mGalleryPage.getPageTitle());
if (shouldStartAsyncLoad(imgBackground, mGalleryPage.getImageURL(), pageIndex)) {
ContentPhotosDownloader
downloader =
new ContentPhotosDownloader(mGalleryPage.getImageURL(), imgBackground, pd, controller,
pageIndex);
imgBackground.setImageDrawable(new AsyncDrawable(getResources(), null, downloader));
downloader.execute();
}
}
private boolean shouldStartAsyncLoad(ImageView imageView, String url, int pageIndex) {
ContentPhotosDownloader downloader = AsyncDrawable.getTask(imageView);
boolean shouldStart = true;
if (downloader != null) {
if (downloader.getPageIndex() == pageIndex && url.equals(downloader.getUrl())) {
shouldStart = false;
} else {
downloader.cancel(true);
}
}
return shouldStart;
}
@SuppressWarnings("deprecation")
public GalleryFlipItem(Context context, GalleryPage mGalleryPage, FlipViewController controller,
int pageIndex) {
super(context);
mContext = context;
LayoutInflater
inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.activity_filp_galleryflipitem, this);
pd = (ProgressBar) findViewById(R.id.gallery_flip_item_background_progressbar);
imgBackground = (ImageView) findViewById(R.id.gallery_flip_item_background_imageview);
lnlPlace = (LinearLayout) findViewById(R.id.gallery_flip_item_place_linearlayout);
imgIcon = (ImageView) findViewById(R.id.gallery_flip_item_place_icon_imageview);
txtName = (TextView) findViewById(R.id.gallery_flip_item_place_name_textview);
txtDistrict = (TextView) findViewById(R.id.gallery_flip_item_place_district_textview);
txtCity = (TextView) findViewById(R.id.gallery_flip_item_place_city_textview);
int measuredwidth = 0;
int measuredheight = 0;
WindowManager w = ((Activity) context).getWindowManager();
Display d = w.getDefaultDisplay();
measuredwidth = d.getWidth();
measuredheight = d.getHeight();
//notes: it's not the right approach to make the background fill its parent, using a RelativeLayout could be much better
imgBackground.setLayoutParams(new LayoutParams(measuredwidth, measuredheight));
refreshView(mGalleryPage, controller, pageIndex);
}
}