What i am trying to achieve is to draw dot at the exact same location as black dot already present in image , but there are problem that i have to face regarding image:
Now problems regarding dots drawing:
I have moved all images to drawable
folder and done layout_width = wrap_content
and height the same as width.
<com.jutt.dotbot.ConnectDotsView
android:id="@+id/gfxImage"
android:layout_width="500dpi"
android:layout_height="600dpi"
android:layout_marginTop="100dip"
android:layout_centerHorizontal="true"/>
I've look hard coded points by Toast the point on each ACTION_DOWN
in onTouchEvent
and then noted then and given to the class ConnectDotsView .
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
L.s(getContext(), "x = "+x+"y = "+y);
break;
After i've noted all points drawn , i am giving this class back that same points to draw , by calling:
public void setPoints(List<Point> points) {
this.mPoints = points;
}
Now Biggest problem [which i think still persist] , (x,y) on screen 1152w*720h may not be same on 480w*600h , so what i've done is who a function to actually convert those points.
private static final int OLDSCREENX = 1152;
private static final int OLDSCREENY = 720;
private int[] makeDimentionGeneric(float oldScreenX, float oldScreenY,
float oldX, float oldY) {
// get screen size
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final float y = displaymetrics.heightPixels;
final float x = displaymetrics.widthPixels;
int[] i = new int[] { (int) ((oldX / oldScreenX) * x),
(int) ((oldY / oldScreenY) * y) };
return i;
}
and i am calling this while setting the points like makeDimentionGeneric(OLDSCREENX, OLDSCREENY, p.x, p.y);
when p.x and p.y
are hardcoded stored value from screen.
Now what happens when i try to run it in different devices.
When am i doing it wrong and how can i achieve it correctly ? please guys i've worked hard studied but can't seems to find a better approach than i've mentioned.
private int[] makeDimentionGeneric(float oldScreenX, float oldScreenY,
float oldX, float oldY) {
// convert all px to dp
oldScreenY = convertPixelsToDp(oldScreenY, this);
oldScreenX = convertPixelsToDp(oldScreenX,this);
oldX = convertPixelsToDp(oldX,this);
oldY = convertPixelsToDp(oldY,this);
// get screen size
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final float y = convertPixelsToDp(displaymetrics.heightPixels, this);
final float x = convertPixelsToDp(displaymetrics.widthPixels, this);
int[] i = new int[] { (int)((oldX / oldScreenX) * x),
(int) ((oldY / oldScreenY) * y) };
return i;
}
Since your image differs depending on DPI your pixel calculations must also differ depending on DPI. Consider the following question:
In your case (copied from answer in above question) you probably want to use this method:
/**
* This method converts device specific pixels to density independent pixels.
*
* @param px A value in px (pixels) unit. Which we need to convert into db
* @param context Context to get resources and device specific display metrics
* @return A float value to represent dp equivalent to px value
*/
public static float convertPixelsToDp(float px, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return dp;
}