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.
packagecom.androidgreeve.circularprogress;
importandroid.content.Context;
importandroid.content.res.Resources;
importandroid.graphics.Bitmap;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.PorterDuff;
importandroid.graphics.PorterDuffXfermode;
importandroid.graphics.RectF;
importandroid.graphics.Xfermode;
importandroid.util.AttributeSet;
importandroid.view.View;
/*
Class used to show a determinate progress indicator.
Two display modes are supported "wheel" and "pie"
*/
classProgressIndicator 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 = newPorterDuffXfermode(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;
publicProgressIndicator(Context context) {
this(context, null);
}
publicProgressIndicator(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 voidsetForegroundColor(int color) {
this.mColorForeground = color;
mPaintForeground.setColor(color);
invalidate();
}
public voidsetBackgroundColor(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!
EmoticonEmoticon