Hi, this is part 2, while searching for a requirement I came across this at SO post. This is attractive, and thought why not I can make a view like this. It is nothing but view which fills from bottom to top like water fills in a container.
Screenshot_2014-09-27-19-52-18Do you like it?! concept behind is same as this view.

1) After extending a View class, I believe methods executed in following order(correct me if I am wrong!)
Constructor(with Context) -> Constructor(with Context and AttributeSet)(a special constructor gets executed when layout is inflated) -> onSizeChanged() etc…

2) More about onSizeChanged()

@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		
		centerPoint.x = getWidth() / 2;
		centerPoint.y = getHeight() / 2;
		
		radius = Math.min(getWidth(), getHeight()) / 2;
		circleRect.set(centerPoint.x - radius, centerPoint.y - radius, centerPoint.x + radius, centerPoint.y + radius);
		
		setPaths();
	}

x,y co ordinates marks to the middle of the screen and radius is decided based on minimum of width and height of screen(in order to fit both in portrait and landscape mode). A rect is set with left,top,right,bottom co ordinate values and then setPaths(setting x,y,startAngle and sweepAngle to Path).

3) Here is setPaths()

private void setPaths() {
		
		float y = centerPoint.y + radius - (2 * radius * value / 100 - 1);
        float x = centerPoint.x - (float) Math.sqrt(Math.pow(radius, 2) - Math.pow(y - centerPoint.y, 2));

        float angle = (float) Math.toDegrees(Math.atan((centerPoint.y - y) / (x - centerPoint.x)));
        float startAngle = 180 - angle;
        float sweepAngle = 2 * angle - 180;

        mPath.rewind();
        mPath.addArc(circleRect, startAngle, sweepAngle);
        mPath.close();
	}

where mPath – instance of Path,circleRect – a rect. I am trying to understand the maths behind this.

4) Inside onDraw() path and circle needs to be drawn.

@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		mPaint.setDither(true);
		mPaint.setColor(Color.LTGRAY);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(15);
		
		mFillPaint.setColor(Color.parseColor("#33b5e5"));
		mFillPaint.setStyle(Paint.Style.FILL_AND_STROKE);
		mFillPaint.setStrokeWidth(5);
		
		canvas.drawPath(mPath,mFillPaint);
		canvas.drawCircle(centerPoint.x, centerPoint.y, radius, mPaint);
	}

5) And hence from Activity call this method at regular interval of time. This method sets the value, path and invalidates the view.

//	values to be sent from activity
	public void setFillValue(int value) {
		adjustValues(value);
		setPaths();
		invalidate();
	}

6) A runnable in Activity is as below,

Runnable runnable = new Runnable() {
		
		@Override
		public void run() {
			if(value <= 60){
				((TextView) findViewById(R.id.percentText)).setText(String.valueOf(value));
				bottomTopCircularView.setFillValue(value++);
				myHandler.postDelayed(this, 20);
			}
		}
	};

For source code github.

Enjoy! and Happy coding !!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s