-> 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