-> We will make a circle progress bar with increasing percentage in between the circle.
What we need?
- attrs.xml
- MainActivity.java
- MeterView.java
- activity_main.java
Step 2 : Give a name to your application as CircleProgress and package name as com.mia.circleprogress. Click Next continuously
Click Finish
Step 3 : Create a new xml file in res->values and name it as attrs. Right click on values folder->New->Android XML File and name it as attrs.
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MeterViewAttr"> <attr name="angle" format="integer" /> <attr name="spacing" format="integer" /> <attr name="lineWidth" format="integer" /> <attr name="lineColor" format="color" /> <attr name="pathColor" format="color" /> </declare-styleable></resources>
Step 4 : Make a new class in src->com.mia.circleprogress. Right click on com.mia.circleprogress->New->Class and name it as MeterView.
MeterView.java
package com.mia.circleprogress;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
interface OnFinishListener {
public void onFinish();
}
public class MeterView extends View implements Runnable {
private int angle = 0, spacing = 0, lineWidth = 0;
private int lineColor = 0, pathColor = 0;
private boolean runasync = true, count = false, done = false;
private int start = 0, stop;
private int interval = 1000, value = 0, total = 1;
private Thread thread = new Thread(this);
private Handler handler = new Handler();
private OnFinishListener f = new OnFinishListener() {
public void onFinish() { }
};
public MeterView(Context context) {
super(context);
}
public MeterView(Context context, AttributeSet attributes) {
//store values from attrs.xml in TypedArray a
super(context, attributes);
TypedArray a = context.obtainStyledAttributes(attributes, R.styleable.MeterViewAttr);
this.angle = a.getInteger(R.styleable.MeterViewAttr_angle, 0);
this.spacing = a.getInteger(R.styleable.MeterViewAttr_spacing, 0);
this.lineWidth = a.getInteger(R.styleable.MeterViewAttr_lineWidth, 0);
this.lineColor = a.getInteger(R.styleable.MeterViewAttr_lineColor, 0);
this.pathColor = a.getInteger(R.styleable.MeterViewAttr_pathColor, 0);
a.recycle();
}
public void runAsync(boolean runasync) {
this.runasync = runasync;
}
public void setValue(int value, int total) {
this.angle = (value * 360) / total; //angle at any instance
this.invalidate();
}
public int getValue() { return this.angle; }
public void onDraw(Canvas canvas) {
int width = this.getWidth(); //width of screen
int height = this.getHeight(); //height of screen
int minLength = (width < height) ? width : height;
int textSize = minLength / 4; //size of number percentage
int left = (width > minLength) ? spacing + (width - minLength) / 2 : spacing;
int top = (height > minLength) ? spacing + (height - minLength) / 2 : spacing;
int right = (width > minLength) ? width - left : minLength - left;
int bottom = (height > minLength) ? height - top : minLength - top;
Paint p = new Paint();
p.setTextSize(textSize);
p.setStrokeWidth(lineWidth);
p.setAntiAlias(true);
p.setStyle(Paint.Style.STROKE);
p.setTextAlign(Paint.Align.CENTER);
RectF area = new RectF(left, top, right, bottom); //rectangle whose all sides are tangent to the circle
// Draw path
p.setColor(pathColor);
canvas.drawArc(area, -90, 360, false, p);
// Draw actual value
p.setColor(lineColor);
canvas.drawArc(area, -90, angle, false, p);
int offsetX = getWidth() / 2;
int offsetY = (getHeight() - ((int) p.ascent() + (int) p.descent())) / 2;
int num = (angle * 100) / 360;
String value = (num == 0 || num == 100) ? String.valueOf("") : String.valueOf(num);
p.setStyle(Paint.Style.FILL);
if(minLength >= textSize || !value.matches("0") || !value.matches("100"))
canvas.drawText(value, offsetX, offsetY, p);
if(num >= 100 && !this.runasync) {
this.setValue(0, 1);
this.f.onFinish();
}
}
public int hex2rgb(String hex) {
int r = (hex.length() < 6) ? Integer.valueOf(hex.substring(1, 2) + hex.substring(1, 2), 16) : Integer.valueOf(hex.substring(1, 3), 16);
int g = (hex.length() < 6) ? Integer.valueOf(hex.substring(2, 3) + hex.substring(2, 3), 16) : Integer.valueOf(hex.substring(3, 5), 16);
int b = (hex.length() < 6) ? Integer.valueOf(hex.substring(3, 4) + hex.substring(3, 4), 16) : Integer.valueOf(hex.substring(5, 7), 16);
return Color.rgb(r, g, b);
}
public void run() { //run thread to count value at each instance
while (this.runasync) {
try {
if (this.count) this.value += 1;
if (this.value >= this.total) {
this.count = false;
this.done = true;
}
if (this.done) {
this.handler.post(new Runnable() {
public void run() {
value = start;
total = stop;
f.onFinish();
}
});
this.done = false;
}
Thread.sleep(this.interval);
} catch (InterruptedException e) {
Log.i("HIR", e.getMessage());
e.printStackTrace();
} catch (Exception e) {
Log.i("HIR", "Error!");
}
this.handler.post(new Runnable() {
public void run() {
setValue(value, total);
}
});
} }
public void prepare(int stop, int interval) {
this.stop = stop;
this.value = this.start;
this.total = this.stop;
this.interval = interval;
if (this.thread.isAlive()) {
this.thread = new Thread(this);
this.done = false;
}
this.thread.start();
}
public void start() { this.count = true; }
public void pause() { this.count = false; }
public void stop() { this.count = false; this.done = false; setValue(0, 1); }
public void setOnFinishListener(OnFinishListener f) { this.f = f; }
}
Step 5 : Go to activity_main.xml found in res->layout and copy the below code in it.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:meterview="http://schemas.android.com/apk/res/com.mia.circleprogress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/run"
android:text="@string/run"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp" />
</LinearLayout>
<com.mia.circleprogress.MeterView
android:id="@+id/meter"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
meterview:spacing="10"
meterview:lineWidth="5"
meterview:lineColor="#0af"
meterview:pathColor="#ccc" />
</LinearLayout>
Step 6 : Now open MainActivity.java from src->com.mia.circleprogress. Copy the below code into it.
MainActivity.java
package com.mia.circleprogress;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_layout);
final MeterView meter = (MeterView) this.findViewById(R.id.meter);
meter.runAsync(false);
meter.setOnFinishListener(new OnFinishListener() {
public void onFinish() {
Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_LONG).show();
}
});
final Button run = (Button) this.findViewById(R.id.run);
run.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
run.setEnabled(false);
new Thread(new Runnable() {
public void run() {
final int stop = 100;
for (int i = 1; i <= stop; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
final int n = i;
runOnUiThread(new Runnable() {
public void run() {
meter.setValue(n, stop);
}
});
}
runOnUiThread(new Runnable() {
public void run() {
run.setEnabled(true);
}
});
}
}).start();
}
});
}}
Step 7 : Run the application.
Explanation of the code:
Explanation from activity_main.xml :
- First we define a LinearLayout under which we have another Linear Layout and a meterview widget which we made it ourselves.
- In the inner LinearLayout we have a button with id=run. When we click the button the progress will start.
- In the widget of meterview having id=meter we also have some attributes of type meterview which we have defined in attrs.xml file in res->values
Explanation from MeterView.java :
- This class creates the widget MeterView which we have used in activity_main.xml.
- Explanation commented in the code above
Explanation from MainActivity,java :
- The onFinish() method of the MeterView we will make a Toast displaying done.
- In onClick() method of the Button run we will start a Thread which will run from 0 to 100.
Stay Tuned with Made In Android












No comments:
Post a Comment