Android Measurment Scale (My Scale)

Untitled
My scale is an android application to measure things with excellent UI which makes you feel like you are working with a scale, which has not measurement limit.
A scale is shown, user can scroll it and select any reading according to one’s weight or height etc.
MyScaleView
Create a class MyScaleView.java and extend this class with View class. All logics will be done in overide method onDraw(Canvas canvas) of view class, ehere we pla with the canvas to draw scale.
package com.android.myscale;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyScaleView extends View {
static int screenSize = 480;
static private float pxmm = screenSize / 67.f;
int width, height, midScreenPoint;
float startingPoint = 0;
float downpoint = 0, movablePoint = 0, downPointClone = 0;
private float mainPoint = 0, mainPointClone = 0;
boolean isDown = false;
boolean isUpward = false;
private boolean isMove;
private onViewUpdateListener mListener;
private Paint gradientPaint;
private float rulersize = 0;
private Paint rulerPaint, textPaint, goldenPaint;
private int endPoint;
boolean isSizeChanged = false;
float userStartingPoint = 0f;
private int scaleLineSmall;
private int scaleLineMedium;
private int scaleLineLarge;
private int textStartPoint;
private int yellowLineStrokeWidth;
boolean isFirstTime = true;

public MyScaleView(Context context, AttributeSet foo) {
super(context, foo);
if (!isInEditMode()) {
init(context);
}
}

private void init(Context context) {
yellowLineStrokeWidth = (int) getResources().getDimension(R.dimen.yellow_line_stroke_width);
gradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
rulersize = pxmm * 10;
rulerPaint = new Paint();
rulerPaint.setStyle(Paint.Style.STROKE);
rulerPaint.setStrokeWidth(0);
rulerPaint.setAntiAlias(false);
rulerPaint.setColor(Color.WHITE);
textPaint = new TextPaint();
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/segoeuil.ttf");
textPaint.setTypeface(typeface);
textPaint.setStyle(Paint.Style.STROKE);
textPaint.setStrokeWidth(0);
textPaint.setAntiAlias(true);
textPaint.setTextSize(getResources().getDimension(R.dimen.txt_size));
textPaint.setColor(Color.WHITE);
goldenPaint = new Paint();
goldenPaint.setStyle(Paint.Style.FILL_AND_STROKE);
goldenPaint.setColor(context.getResources().getColor(R.color.yellow));
goldenPaint.setStrokeWidth(yellowLineStrokeWidth);
goldenPaint.setStrokeJoin(Paint.Join.ROUND);
goldenPaint.setStrokeCap(Paint.Cap.ROUND);
goldenPaint.setPathEffect(new CornerPathEffect(10));
goldenPaint.setAntiAlias(true);
scaleLineSmall = (int) getResources().getDimension(R.dimen.scale_line_small);
scaleLineMedium = (int) getResources().getDimension(R.dimen.scale_line_medium);
scaleLineLarge = (int) getResources().getDimension(R.dimen.scale_line_large);
textStartPoint = (int) getResources().getDimension(R.dimen.text_start_point);
}

public void setUpdateListener(onViewUpdateListener onViewUpdateListener) {
mListener = onViewUpdateListener;
}

@Override
public void onSizeChanged(int w, int h, int oldW, int oldH) {
width = w;
height = h;
screenSize = height;
pxmm = screenSize / 67.f;
midScreenPoint = height / 2;
endPoint = width - 40;
if (isSizeChanged) {
isSizeChanged = false;
mainPoint = midScreenPoint - (userStartingPoint * 10 * pxmm);
}
gradientPaint.setShader(new LinearGradient(0, 0, width, rulersize, getResources().getColor(R.color.green),
getResources().getColor(R.color.transparent_white), android.graphics.Shader.TileMode.MIRROR));
}

@Override
public void onDraw(Canvas canvas) {
canvas.drawRect(0f, midScreenPoint - (rulersize / 2), width, midScreenPoint + (rulersize / 2), gradientPaint);
startingPoint = mainPoint;
for (int i = 1;; ++i) {
if (startingPoint > screenSize) {
break;
}
startingPoint = startingPoint + pxmm;
int size = (i % 10 == 0) ? scaleLineLarge : (i % 5 == 0) ? scaleLineMedium : scaleLineSmall;
canvas.drawLine(endPoint - size, startingPoint, endPoint, startingPoint, rulerPaint);
if (i % 10 == 0) {
System.out.println("done   " + i);
canvas.drawText((i / 10) + " cm", endPoint - textStartPoint, startingPoint + 8, textPaint);
}
}
canvas.drawLine(0f, midScreenPoint, width - 20, midScreenPoint, goldenPaint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("touch event fire");
mainPointClone = mainPoint;
if (mainPoint < 0) {
mainPointClone = -mainPoint;
}
float clickPoint = ((midScreenPoint + mainPointClone) / (pxmm * 10));
if (mListener != null) {
mListener.onViewUpdate((midScreenPoint + mainPointClone) / (pxmm * 10));
}
System.out.println("click point" + clickPoint + "");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isMove = true;
isDown = false;
isUpward = false;
downpoint = event.getY();
downPointClone = event.getY();
break;
case MotionEvent.ACTION_MOVE:
movablePoint = event.getY();
if (downPointClone > movablePoint) {
/**
* if user first starts moving downward and then upwards then
* this method makes it to move upward
*/
if (isUpward) {
downpoint = event.getY();
downPointClone = downpoint;
}
isDown = true;
isUpward = false;
/**
* make this differnce of 1, otherwise it moves very fast and
* nothing shows clearly
*/
if (downPointClone - movablePoint > 1) {
mainPoint = mainPoint + (-(downPointClone - movablePoint));
downPointClone = movablePoint;
invalidate();
}
} else {
// downwards
if (isMove) {
/**
* if user first starts moving upward and then downwards,
* then this method makes it to move upward
*/
if (isDown) {
downpoint = event.getY();
downPointClone = downpoint;
}
isDown = false;
isUpward = true;
if (movablePoint - downpoint > 1) {
mainPoint = mainPoint + ((movablePoint - downPointClone));
downPointClone = movablePoint;
if (mainPoint > 0) {
mainPoint = 0;
isMove = false;
}
invalidate();
}
}
}
break;
case MotionEvent.ACTION_UP:
System.out.println("up");
default:
break;
}
return true;
}

public void setStartingPoint(float point) {
userStartingPoint = point;
isSizeChanged = true;
if (isFirstTime) {
isFirstTime = false;
if (mListener != null) {
mListener.onViewUpdate(point);
}
}
}
}

Use MyScaleView.java class in your xml to create the view
Crate a xml file activity_my_scale.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:background=”#123456″
android:gravity=”right|center_vertical”
android:orientation=”horizontal” >

<TextView
android:id=”@+id/txt_height”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:textAppearance=”?android:attr/textAppearanceLarge”
android:textColor=”@android:color/white” />

<com.android.myscale.MyScaleView
android:id=”@+id/my_scale”
android:layout_width=”200dp”
android:layout_height=”match_parent”
android:layout_gravity=”right”
android:background=”#123456″ />

</LinearLayout>
MyScaleActivity class


Create a class My scaleActivity

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MyScaleActivity extends Activity {

 private TextView txtValue;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_scale);
final MyScaleView rulerViewMm = (MyScaleView) findViewById(R.id.my_scale);
txtValue = (TextView) findViewById(R.id.txt_height);
rulerViewMm.setStartingPoint(70);
rulerViewMm.setUpdateListener(new onViewUpdateListener() {

@Override
public void onViewUpdate(float result) {
float value = (float) Math.round(result * 10f) / 10f;
txtValue.setText(value + ” cm”);
}
});
}
}
Thats all!
A scale will be shown and you can select any reading just by scrolling it.

Download

MyScale Video

27 thoughts on “Android Measurment Scale (My Scale)

  1. Hi kimmi i tried your code it showed the view but touch listener not working.in code there is some typo mistake in TouchEvent

    what is it mean if (mainPoint movablePoint)

    Like

  2. Hello! Nice tutorial. Can you help me with this: lets say i have another scale (exact copy) next to the first one. How can i make two scales move simultaneously when i scroll just one?

    Like

Leave a comment