From 3d37dd899fe3eb88745fcb2aee1bb2fec77b9878 Mon Sep 17 00:00:00 2001 From: Victor Date: Sun, 15 Jun 2014 18:46:20 +0300 Subject: [PATCH] Add horizontal progress bar --- src/com/blundell/tut/LoaderImageView.java | 95 ++++++++++++++++------- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/src/com/blundell/tut/LoaderImageView.java b/src/com/blundell/tut/LoaderImageView.java index 323366b..d4d2e9b 100644 --- a/src/com/blundell/tut/LoaderImageView.java +++ b/src/com/blundell/tut/LoaderImageView.java @@ -1,33 +1,39 @@ package com.blundell.tut; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; - +import java.net.URLConnection; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; -import android.os.Message; import android.os.Handler.Callback; +import android.os.Message; import android.util.AttributeSet; import android.view.View; +import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ProgressBar; /** * Free for anyone to use, just say thanks and share :-) * @author Blundell */ -public class LoaderImageView extends LinearLayout { +public final class LoaderImageView extends FrameLayout { private static final int COMPLETE = 0; private static final int FAILED = 1; + private static final int PROGRESS = 2; private Context mContext; private Drawable mDrawable; - private ProgressBar mSpinner; + private ProgressBar mProgressBar; private ImageView mImage; /** @@ -42,15 +48,11 @@ public class LoaderImageView extends LinearLayout { public LoaderImageView(final Context context, final AttributeSet attrSet) { super(context, attrSet); final String url = attrSet.getAttributeValue(null, "image"); - if (url != null) { - instantiate(context, url); - } else { - instantiate(context, null); - } + instantiate(context, url); } /** - * This is used when creating the view programatically + * This is used when creating the view programmatically * Once you have instantiated the view you can call * setImageDrawable(url) to change the image * @param context the Activity context @@ -62,7 +64,7 @@ public class LoaderImageView extends LinearLayout { } /** - * This is used when creating the view programatically + * This is used when creating the view programmatically * Once you have instantiated the view you can call * setImageDrawable(url) to change the image * @param context the Activity context @@ -82,15 +84,15 @@ public class LoaderImageView extends LinearLayout { mContext = context; mImage = new ImageView(mContext); - mImage.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - - mSpinner = new ProgressBar(mContext); - mSpinner.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - - mSpinner.setIndeterminate(true); - - addView(mSpinner); + mImage.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + + mProgressBar = new ProgressBar(mContext, null, android.R.attr.progressBarStyleHorizontal); + mProgressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + mProgressBar.setProgress(0); + mProgressBar.setMax(100); + addView(mImage); + addView(mProgressBar); if (imageUrl != null) { setImageDrawable(imageUrl); @@ -104,8 +106,9 @@ public class LoaderImageView extends LinearLayout { */ public void setImageDrawable(final String imageUrl) { mDrawable = null; - mSpinner.setVisibility(View.VISIBLE); - mImage.setVisibility(View.GONE); + mProgressBar.setVisibility(View.VISIBLE); + mProgressBar.setProgress(0); + mProgressBar.setMax(100); new Thread() { @Override public void run() { @@ -121,6 +124,10 @@ public class LoaderImageView extends LinearLayout { }.start(); } + public Drawable getDrawable() { + return mImage.getDrawable(); + } + /** * Callback that is received once the image has been downloaded */ @@ -130,9 +137,11 @@ public class LoaderImageView extends LinearLayout { switch (msg.what) { case COMPLETE: mImage.setImageDrawable(mDrawable); - mImage.setVisibility(View.VISIBLE); - mSpinner.setVisibility(View.GONE); + mProgressBar.setVisibility(View.GONE); break; + case PROGRESS: + mProgressBar.setProgress(msg.arg1); + break; case FAILED: default: // Could change image here to a 'failed' image @@ -149,8 +158,42 @@ public class LoaderImageView extends LinearLayout { * @throws IOException * @throws MalformedURLException */ - private static Drawable getDrawableFromUrl(final String url) throws IOException, MalformedURLException { - return Drawable.createFromStream(((InputStream) new URL(url).getContent()), "name"); + private Drawable getDrawableFromUrl(final String imageUrl) throws IOException, MalformedURLException { + final URL url = new URL(imageUrl); + final URLConnection conection = url.openConnection(); + conection.connect(); + // this will be useful so that you can show a typical 0-100% progress bar + int lenghtOfFile = conection.getContentLength(); + if (lenghtOfFile <= 0) { + // try to load by system call + return Drawable.createFromStream((InputStream) url.getContent(), "name"); + } + + // download the file + final InputStream input = new BufferedInputStream(url.openStream(), 8192); + ByteArrayOutputStream output = new ByteArrayOutputStream(lenghtOfFile); + final byte[] buffer = new byte[4096]; + long total = 0; + int count; + while ((count = input.read(buffer)) != -1) { + total += count; + // publishing the progress.... + imageLoadedHandler.obtainMessage(PROGRESS, (int) ((total * 100) / lenghtOfFile), 0) + .sendToTarget(); + // writing data + output.write(buffer, 0, count); + } + // flushing output + output.flush(); + // closing streams + output.close(); + input.close(); + + byte[] data = output.toByteArray(); + output = null; + Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); + data = null; + return new BitmapDrawable(mContext.getResources(), bitmap); } }