A tutorial on how to create the page preloading effect seen on the android app. We are going to use .The circular progress bar is used as an buffer element in most of the app.
Today we want to show you how to create a very simplepage preloading effect for android . For an android app, where it’s crucial to load all or part of the assets, these kind of progressbar can be made use of.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@color/skyblue">
//Demo 1
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal" >
<com.androidgreeve.circularprogress.ProgressIndicator
android:id="@+id/determinate_progress_indicator1"
android:layout_width="100dp"
android:layout_height="100dp" />
<com.androidgreeve.circularprogress.Progressndicator
android:id="@+id/determinate_progress_indicator2"
android:layout_width="100dp"
android:layout_height="100dp" />
<com.androidgreeve.circularprogress.ProgressIndicator
android:id="@+id/determinate_progress_indicator3"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
//Demo2 Layout
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal" >
<com.androidgreeve.circularprogress.ProgressIndicator
android:id="@+id/determinate_progress_indicator4"
android:layout_width="100dp"
android:layout_height="100dp" />
<com.androidgreeve.circularprogress.ProgressIndicator
android:id="@+id/determinate_progress_indicator5"
android:layout_width="100dp"
android:layout_height="100dp" />
<com.androidgreeve.circularprogress.ProgressIndicator
android:id="@+id/determinate_progress_indicator6"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
2) Now we are going thtrough to the java file to add the progress elements
First, we will create a ProgressIndicator.java class which will extends View class.
This class is used for showing Progressbar.
package
com.androidgreeve.circularprogress;
import
android.content.Context;
import
android.content.res.Resources;
import
android.graphics.Bitmap;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.graphics.PorterDuff;
import
android.graphics.PorterDuffXfermode;
import
android.graphics.RectF;
import
android.graphics.Xfermode;
import
android.util.AttributeSet;
import
android.view.View;
/*
Class used to show a determinate progress
indicator.
Two display modes are supported
"wheel" and "pie"
*/
class
ProgressIndicator extends View {
private final RectF mRect = new RectF();
private final RectF mRectInner = new RectF();
private final Paint mPaintForeground = new Paint();
private final Paint mPaintBackground = new Paint();
private final Paint mPaintErase = new Paint();
private static final Xfermode PORTER_DUFF_CLEAR = new
PorterDuffXfermode(PorterDuff.Mode.CLEAR);
private int mColorForeground = Color.WHITE;
private int mColorBackground = Color.BLACK;
private float mValue;
private boolean mPieStyle;
/*
Value which makes our custom drawn
indicator have roughly the same size
as the built-in ProgressBar
indicator.
*/
private static final float PADDING = 4;
private float mPadding;
private Bitmap mBitmap;
/**
Value which makes our custom drawn
indicator have roughly the same
thickness as the built-in ProgressBar
indicator.
*/
private static final float INNER_RADIUS_RATIO = 0.84f;
public
ProgressIndicator(Context context) {
this(context, null);
}
public
ProgressIndicator(Context context, AttributeSet attrs) {
super(context,
attrs);
Resources r = context.getResources();
float scale =
r.getDisplayMetrics().density;
mPadding = scale * PADDING ;
mPaintForeground.setColor(mColorForeground);
mPaintForeground.setAntiAlias(true);
mPaintBackground.setColor(mColorBackground);
mPaintBackground.setAntiAlias(true);
mPaintErase.setXfermode(PORTER_DUFF_CLEAR);
mPaintErase.setAntiAlias(true);
}
/*
Set the style of this indicator.The two
supported styles are "wheel" and "pie"
@param style One of {@link
STYLE_WHEEL} or {@link STYLE_PIE}
*/
public void setPieStyle(boolean pieStyle) {
if (mPieStyle == pieStyle) {
return;
}
mPieStyle = pieStyle;
updateBitmap();
}
/*
Return the current style of this
indicator.
*/
public boolean getIsPieStyle()
{
return mPieStyle;
}
@Override
protected void onDraw(Canvas
canvas) {
canvas.drawBitmap(mBitmap, getWidth() / 2
- mBitmap.getWidth() / 2,
getHeight() / 2 - mBitmap.getHeight() /
2, null);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
float bitmapWidth = w
- 2 * mPadding;
float bitmapHeight =
h - 2 * mPadding;
float radius = Math.min(bitmapWidth
/ 2, bitmapHeight / 2);
mRect.set(0, 0, bitmapWidth,
bitmapHeight);
radius *= INNER_RADIUS_RATIO;
mRectInner.set(bitmapWidth
/ 2f - radius, bitmapHeight / 2f - radius, bitmapWidth / 2f + radius,
bitmapHeight / 2f + radius);
updateBitmap();
}
public void
setForegroundColor(int color) {
this.mColorForeground = color;
mPaintForeground.setColor(color);
invalidate();
}
public void
setBackgroundColor(int color) {
this.mColorBackground = color;
mPaintBackground.setColor(color);
invalidate();
}
public synchronized void setValue(float value) {
mValue = value;
updateBitmap();
}
private void updateBitmap()
{
if (mRect == null || mRect.width() == 0) {
return;
}
mBitmap = Bitmap.createBitmap((int) mRect.width(), (int) mRect.height(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
canvas.drawArc(mRect, -90, 360, true, mPaintBackground);
if (mValue < 0.01f) {
canvas.drawLine(mRect.width() / 2, mRect.height() / 2, mRect.width() / 2, 0,
mPaintForeground);
}
float angle = mValue * 360;
canvas.drawArc(mRect, -90, angle, true, mPaintForeground);
if (!mPieStyle) {
canvas.drawArc(mRectInner, -90, 360, true, mPaintErase);
}
postInvalidate();
}
}
// @return <tt>True</tt> if the
indicator has the "pie" style
package com.androidgreeve.circularprogress;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Demo_Activity extends Activity{
ProgressIndicator mProgressIndicator1,mProgressIndicator2, mProgressIndicator3,
Button btnreset;
float max = 1;
float update = 0;
boolean threadRunning = false;;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressIndicator1 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator1);
mProgressIndicator2 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator2);
mProgressIndicator3 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator3);
mProgressIndicator4 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator4);
mProgressIndicator5 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator5);
mProgressIndicator6 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator6);
btnreset = (Button) findViewById(R.id.btnreset);
mProgressIndicator1.setForegroundColor(Color.parseColor("#9D5858"));
mProgressIndicator1.setBackgroundColor(Color.parseColor("#E40DAA"));
mProgressIndicator2.setForegroundColor(Color.parseColor("#E40DAA"));
mProgressIndicator2.setBackgroundColor(Color.parseColor("#f48fb1"));
mProgressIndicator3.setForegroundColor(Color.parseColor("#5BE40D"));
mProgressIndicator3.setBackgroundColor(Color.parseColor("#ce93d8"));
startThread();
btnreset.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(threadRunning)
return;
startThread();
}
});
}
private void startThread() {
new Thread(new Runnable() {
@Override
public void run() {
threadRunning = true;
update = 0;
while(update <= max){
update += 0.005;
updateProgressIndicatorValue();
try{
Thread.sleep(100);
}catch(Exception e){
}
}
threadRunning = false;
}
}).start();
}
private void updateProgressIndicatorValue() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressIndicator1.setValue(update);
mProgressIndicator2.setValue(update);
mProgressIndicator3.setValue(update);
}
});
}
}
C) mProgressIndicator4.setValue(update);
mProgressIndicator5.setValue(update);
mProgressIndicator6.setValue(update);
The Mainactivity contains the mapping between the progressbar and the xml file
Demo1_activity.java
package com.androidgreeve.circularprogress;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Demo_Activity extends Activity{
ProgressIndicator mProgressIndicator1,mProgressIndicator2, mProgressIndicator3,
Button btnreset;
float max = 1;
float update = 0;
boolean threadRunning = false;;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressIndicator1 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator1);
mProgressIndicator2 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator2);
mProgressIndicator3 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator3);
mProgressIndicator4 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator4);
mProgressIndicator5 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator5);
mProgressIndicator6 = (ProgressIndicator) findViewById(R.id.determinate_progress_indicator6);
btnreset = (Button) findViewById(R.id.btnreset);
mProgressIndicator1.setForegroundColor(Color.parseColor("#9D5858"));
mProgressIndicator1.setBackgroundColor(Color.parseColor("#E40DAA"));
mProgressIndicator2.setForegroundColor(Color.parseColor("#E40DAA"));
mProgressIndicator2.setBackgroundColor(Color.parseColor("#f48fb1"));
mProgressIndicator3.setForegroundColor(Color.parseColor("#5BE40D"));
mProgressIndicator3.setBackgroundColor(Color.parseColor("#ce93d8"));
startThread();
btnreset.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(threadRunning)
return;
startThread();
}
});
}
private void startThread() {
new Thread(new Runnable() {
@Override
public void run() {
threadRunning = true;
update = 0;
while(update <= max){
update += 0.005;
updateProgressIndicatorValue();
try{
Thread.sleep(100);
}catch(Exception e){
}
}
threadRunning = false;
}
}).start();
}
private void updateProgressIndicatorValue() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressIndicator1.setValue(update);
mProgressIndicator2.setValue(update);
mProgressIndicator3.setValue(update);
}
});
}
}
Similarly for demo2_activity changes to be made are:
A)mProgressIndicator4,mProgressIndicator5,mProgressIndicator6;
B)mProgressIndicator4.setForegroundColor(Color.parseColor("#CCC000"));
mProgressIndicator4.setBackgroundColor(Color.parseColor("#aCbfff"));
mProgressIndicator4.setPieStyle(true);
mProgressIndicator5.setForegroundColor(Color.parseColor("#FAFFAF"));
mProgressIndicator5.setBackgroundColor(Color.parseColor("#80cbc4"));
mProgressIndicator5.setPieStyle(true);
mProgressIndicator6.setForegroundColor(Color.parseColor("#0d5302"));
mProgressIndicator6.setBackgroundColor(Color.parseColor("#72d572"));
mProgressIndicator6.setPieStyle(true);
mProgressIndicator4.setBackgroundColor(Color.parseColor("#aCbfff"));
mProgressIndicator4.setPieStyle(true);
mProgressIndicator5.setForegroundColor(Color.parseColor("#FAFFAF"));
mProgressIndicator5.setBackgroundColor(Color.parseColor("#80cbc4"));
mProgressIndicator5.setPieStyle(true);
mProgressIndicator6.setForegroundColor(Color.parseColor("#0d5302"));
mProgressIndicator6.setBackgroundColor(Color.parseColor("#72d572"));
mProgressIndicator6.setPieStyle(true);
C) mProgressIndicator4.setValue(update);
mProgressIndicator5.setValue(update);
mProgressIndicator6.setValue(update);
4 comments
Your tutorials are very nice and kept very simple.But why can't u just upload that code to server so that it would be more helpful.
A1 Awesome stuff man.. Nice post .Nice design and color combination . Thank u
Very nice .. It worked for me.. Thank u
Very useful!
I was working on a plain progress bar and I did not know how to draw it but this blog
entry made me do a similar onDraw method
Thanks a lot!