Obtain the screen height and width - android

I check the reference to obtain the Screen height and width. My mobile phone’s height and width like below
Point p = new Point();
getWindowManager().getDefaultDisplay().getSize(p);
p.x //width 540
p.y //height 960
I write a demo, but the value obtained not right
The demo like this
import android.graphics.Point;
public class Strike {
private StrikeView view;
private int left = 0;
private int top = 0;
private Point win;
private boolean isDown = true;
private boolean isRight = true;
public Strike(StrikeView view, Point win) {
this.view = view;
this.win = win;
this.left = view.getLeft();
this.top = view.getTop();
}
/**
* Set direction and refresh
*/
public void setPostion() {
view.setLeft(left);
view.setTop(top);
view.invalidate();
}
/**
* calculate view direction
*/
public void postion() {
if (isRight) {
if (left + 30 < win.x)
left++;
else {
isRight = false;
left--;
}
} else {
if (left > 0)
left--;
else {
isRight = true;
left++;
}
}
if (isDown) {
if (top + 30 < win.y)
top++;
else {
isDown = false;
top--;
}
} else {
if (top > 0)
top--;
else {
isDown = true;
top++;
}
}
}
}

Here is what I used (tested on Android 2.1+):
private void size() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
size_old(getWindowManager().getDefaultDisplay());
}
else {
size_new(getWindowManager().getDefaultDisplay());
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void size_new(Display display) {
Point point = new Point();
display.getSize(point);
// point.x and point.y
}
#SuppressWarnings("deprecation")
private String size_old(Display display) {
// display.getWidth() and display.getHeight()
}

To know size of any phone is worth to use such method...
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int wwidth = displaymetrics.widthPixels;

Use this:
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;

Related

MPAndroidChart: Multiple markers at the same highlight

I want to show on click, three tooltips/markers, with only one dataset.
Like in the below image:
How can I do it?
I have created a LineChart and gave data to it.
and for multiple markers i have created a class implementing IMarker and created 2 Object
of a class i made for the information of each marker.
the way which the second marker is shown , depends on the position of first marker.
and i know it is not a good implementation maybe , but worked...
here is the code that worked for me:
public class ImageMakerTwoINOne implements IMarker {
private Context mContext;
public static final String TAG = "marker class";
ObjectImage o1 = new ObjectImage();
ObjectImage o2 = new ObjectImage();
//constructor for initialization
public ImageMakerTwoINOne(Context context, int drawableResourceId,int drawableResourceId2) {
mContext = context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
o1.drawable = mContext.getResources().getDrawable(drawableResourceId, null);
o2.drawable = mContext.getResources().getDrawable(drawableResourceId2,null);
} else {
o1.drawable = mContext.getResources().getDrawable(drawableResourceId);
o2.drawable = mContext.getResources().getDrawable(drawableResourceId2);
}
}
//////////////////////////////offset////////////////////////////
//setting the offsets by the users
public void setOffset(MPPointF offset,MPPointF offset2) {
o1.offset = offset;
o2.offset = offset2;
//in case they were null :
if (offset == null) o1.offset = new MPPointF();
else if (offset2 == null) o2.offset = new MPPointF();
}
//setting the offsets by the user
public void setOffset(float offsetX, float offsetY , float offsetX2 , float offsetY2) {
o1.offset.x = offsetX;
o1.offset.y = offsetY;
o2.offset.x = offsetX2;
o2.offset.y = offsetY2;
}
#Override
public MPPointF getOffset() { return o2.offset; }
public MPPointF getOffset2(){ return o2.offset; }
////////////////////////size//////////////////////////////
//setting the size by the user
public void setSize(FSize size , FSize size2) {
o1.size = size;
o2.size = size2;
}
//getting the size of the objects
public FSize getSize1() { return o1.size; }
public FSize getSize2() { return o2.size; }
//////////////////chart///////////////////////////////////
//setting the charts
public void setChartView(Chart chart,Chart chart2) {
o1.weakChart = new WeakReference<>(chart);
o2.weakChart = new WeakReference<>(chart2);
}
//getting chart
public Chart getChartView1() {return o1.weakChart == null ? null : o1.weakChart.get(); }
public Chart getChartView2() { return o2.weakChart == null ? null : o2.weakChart.get(); }
//getting offset
#Override
public MPPointF getOffsetForDrawingAtPoint(float posX, float posY) {
MPPointF offset = getOffset();
Chart chart = getChartView1();
float width1 = o1.size.width;
float height1 = o1.size.height;
if (width1==0.f){ width1 = o1.drawable.getIntrinsicWidth(); }
if (height1==0.f){ height1 = o1.drawable.getIntrinsicHeight(); }
MPPointF alaki = getOffsetForDrawingAtPoint2(posX,posY);
return o1.offset;
}
public MPPointF getOffsetForDrawingAtPoint2(float posx , float posY){
MPPointF offset = getOffset();
Chart chart = getChartView1();
float width1 = o2.size.width;
float height1 = o2.size.height;
if (width1==0.f){ width1 = o2.drawable.getIntrinsicWidth(); }
if (height1==0.f){ height1 = o2.drawable.getIntrinsicHeight(); }
return o2.offset;
}
#Override
public void refreshContent(Entry e, Highlight highlight) {
}
#Override
public void draw(Canvas canvas, float posX, float posY) {
Canvas canvas2 = canvas;
if (o1.drawable == null) return;
MPPointF offset = getOffsetForDrawingAtPoint(posX,posY); //main position
MPPointF offset2 = o2.offset; //main position obj 2
float width = o1.size.width;
float height = o1.size.height;
if (width == 0.f) { width = o1.drawable.getIntrinsicWidth(); }
if (height == 0.f) { height = o1.drawable.getIntrinsicHeight();}
float width2 = 128;//o2.size.width;
float height2 = 129;//o2.size.height;
if (width == 0.f) { width = o2.drawable.getIntrinsicWidth(); }
if (height == 0.f) { height = o2.drawable.getIntrinsicHeight();}
o1.drawable.copyBounds(o1.drawableBoundsCache);
o1.drawable.setBounds(
o1.drawableBoundsCache.left,
o1.drawableBoundsCache.top,
(int) (o1.drawableBoundsCache.left+width),
(int) (o1.drawableBoundsCache.top+height)
);
o2.drawable.copyBounds(o2.drawableBoundsCache);
o2.drawable.setBounds(
o2.drawableBoundsCache.left,
o2.drawableBoundsCache.top,
(int) (o2.drawableBoundsCache.left+width2),
(int) (o2.drawableBoundsCache.top+height2)
);
int saveId = canvas.save();
int saveId2 = canvas2.save();
canvas.translate(posX + offset.x , posY + offset.y);
o1.drawable.draw(canvas);
canvas2.translate( 75 , -45 );
o2.drawable.draw(canvas2);
canvas2.restoreToCount(saveId2);
canvas.restoreToCount(saveId);
o1.drawable.setBounds(o1.drawableBoundsCache);
o2.drawable.setBounds(o2.drawableBoundsCache);
}
}
public class ObjectImage {
public Drawable drawable;
public MPPointF offset = new MPPointF();
public WeakReference<Chart> weakChart;
public FSize size = new FSize();
public Rect drawableBoundsCache = new Rect();
}

How to get the screen size?

I am trying to set a sprite image as a background
and I didn't success to set the image size to screen size.
I'm trying this:
public class Game extends SurfaceView implements Runnable {
private SurfaceHolder holder;
private boolean isRunning = false;
private Thread gameThread;
private Sprite s;
private int screenWidth;
private int screenHeight;
Canvas canvas;
// private Sprite[] sprites;
private final static int MAX_FPS = 40; //desired fps
private final static int FRAME_PERIOD = 1000 / MAX_FPS; // the frame period
public Game(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
screenWidth = width;
screenHeight = height;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
//====== not working
// Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
// int sWidth = display.getWidth();
// int sHeight = display.getHeight();
//====== not working
// DisplayMetrics dm = new DisplayMetrics();
// ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm);
// int sWidth = dm.widthPixels;
// int sHeight = dm.heightPixels;
//====== not working
// screenHeight=canvas.getHeight();
// screenWidth=canvas.getWidth();
s=new Sprite(0, 0, BitmapFactory.decodeResource(this.getResources(), R.mipmap.back));
}
/**
* Start or resume the game.
*/
public void resume() {
isRunning = true;
gameThread = new Thread(this);
gameThread.start();
}
/**
* Pause the game loop
*/
public void pause() {
isRunning = false;
boolean retry = true;
while (retry) {
try {
gameThread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}
class Sprite {
int x;
int y;
int directionX = 1;
int directionY = 1;
int speed = 10;
int color = 0;
Bitmap image;
public Sprite(int x, int y) {
this.x = x;
this.y = y;
}
public Sprite(int x, int y, Bitmap image) {
this(x, y);
this.image = image;
}
public Sprite(int x, int y, Bitmap image, int color) {
this(x, y, image);
this.color = color;
}
}
protected void step()
{
//blablabla
}
protected void render(Canvas canvas) {
canvas.drawColor(Color.BLACK);
Paint p = new Paint();
canvas.drawBitmap(s.image,s.x,s.y,p);
}
#Override
public void run() {
while(isRunning) {
// We need to make sure that the surface is ready
if (! holder.getSurface().isValid()) {
continue;
}
long started = System.currentTimeMillis();
// update
step();
// draw
canvas = holder.lockCanvas();
if (canvas != null) {
render(canvas);
holder.unlockCanvasAndPost(canvas);
}
float deltaTime = (System.currentTimeMillis() - started);
int sleepTime = (int) (FRAME_PERIOD - deltaTime);
if (sleepTime > 0) {
try {
gameThread.sleep(sleepTime);
}
catch (InterruptedException e) {
}
}
while (sleepTime < 0) {
step();
sleepTime += FRAME_PERIOD;
}
}
}
}
This options doesn't work:
//====== not working
// Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
// int sWidth = display.getWidth();
// int sHeight = display.getHeight();
//====== not working
// DisplayMetrics dm = new DisplayMetrics();
// ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm);
// int sWidth = dm.widthPixels;
// int sHeight = dm.heightPixels;
//====== not working
// screenHeight=canvas.getHeight();
// screenWidth=canvas.getWidth();
So how I can get the canvas or current screen size?
And set the Sprite.image to full screen ?
Try this for size in pixels,
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Try this when you decode your bitmap.
final int width = context.getResources().getDisplayMetrics().widthPixels;
final int height = context.getResources().getDisplayMetrics().heightPixels;
BitmapFactory.Options options = new BitmapFactory.Options();
options.outHeight = height;
options.outWidth = width;
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher, options)

Scale the Bitmap to screen in Live wallpaper

I'm new in Android Programming I'm Trying to make slideshow animated live wallpaper and all ok but the problem is when I set the wallpaper the scale of image is stretched to screen I want it to scale to all the phone screens and when swipe the wallpaper get the right part of image I Want Advice about this problem.
my code is :
public class CustomWallpaper extends WallpaperService {
#Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}
class WallpaperEngine extends Engine {
//Duration between slides in milliseconds
private final int SLIDE_DURATION = 8;
private int[] mImagesArray;
private int mImagesArrayIndex = 0;
private Thread mDrawWallpaper;
private String mImageScale = "Fit to screen";
private CustomWallpaperHelper customWallpaperHelper;
public WallpaperEngine() {
customWallpaperHelper = new CustomWallpaperHelper(getApplicationContext(), getResources());
mImagesArray = new int[] {R.drawable.image_1,R.drawable.image_2,R.drawable.image_3,R.drawable.image_4,R.drawable.image_5,R.drawable.image_6,R.drawable.image_7,R.drawable.image_8,R.drawable.image_9,R.drawable.image_10,R.drawable.image_11,R.drawable.image_12,R.drawable.image_13,R.drawable.image_14,R.drawable.image_15,R.drawable.image_16,R.drawable.image_17,R.drawable.image_18,R.drawable.image_19,R.drawable.image_20,R.drawable.image_21,R.drawable.image_22,R.drawable.image_23,R.drawable.image_24,R.drawable.image_25,R.drawable.image_26,R.drawable.image_27,R.drawable.image_28,R.drawable.image_29,R.drawable.image_30,R.drawable.image_31,R.drawable.image_32,R.drawable.image_33,R.drawable.image_34,R.drawable.image_35,R.drawable.image_36,R.drawable.image_37,R.drawable.image_38,R.drawable.image_39,R.drawable.image_40,R.drawable.image_41};
mDrawWallpaper = new Thread(new Runnable() {
#Override
public void run() {
try {
while (true) {
drawFrame();
incrementCounter();
Thread.sleep(SLIDE_DURATION);
}
} catch (Exception e) {
//
}
}
});
mDrawWallpaper.start();
}
private void incrementCounter() {
mImagesArrayIndex++;
if (mImagesArrayIndex >= mImagesArray.length) {
mImagesArrayIndex = 0;
}
}
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = null;
try {
canvas = holder.lockCanvas();
if (canvas != null) {
drawImage(canvas);
}
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
private void drawImage(Canvas canvas) {
//Get the image and resize it
Bitmap image = BitmapFactory.decodeResource(getResources(),
mImagesArray[mImagesArrayIndex]);
//Draw background
customWallpaperHelper.setBackground(canvas);
//Scale the canvas
PointF mScale = customWallpaperHelper.getCanvasScale(mImageScale, image.getWidth(), image.getHeight());
canvas.scale(mScale.x, mScale.y);
//Draw the image on screen
Point mPos = customWallpaperHelper.getImagePos(mScale, image.getWidth(), image.getHeight());
canvas.drawBitmap(image, mPos.x, mPos.y, null);
}
}
}
and the other class is:
public class CustomWallpaperHelper {
public final static String IMAGE_SCALE_STRETCH_TO_SCREEN = "Stretch to screen";
public final static String IMAGE_SCALE_FIT_TO_SCREEN = "Fit to screen";
private Context mContext;
private Resources mResources;
private Point screenSize = new Point();
private Bitmap bgImageScaled;
private Point bgImagePos = new Point(0, 0);
public CustomWallpaperHelper(Context mContext, Resources mResources) {
this.mContext = mContext;
this.mResources = mResources;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
screenSize.x = display.getWidth();
screenSize.y = display.getHeight();
;
}
private void scaleBackground() {
String imageScale = "Stretch to screen";
Bitmap bgImage = null;
if (imageScale.equals(IMAGE_SCALE_STRETCH_TO_SCREEN)) {
bgImagePos = new Point(0, 0);
bgImageScaled = Bitmap.createScaledBitmap(bgImage, screenSize.x, screenSize.y, true);
}
}
public void setBackground(Canvas canvas) {
if (bgImageScaled != null) {
canvas.drawBitmap(bgImageScaled, bgImagePos.x, bgImagePos.y, null);
} else {
canvas.drawColor(0xff000000);
}
}
public int getScreenWidth() {
return screenSize.x;
}
public int getScreenHeight() {
return screenSize.y;
}
public Point getImagePos(PointF canvasScale, int imageWidth, int imageHeight) {
Point imagePos = new Point();
imagePos.x = (int) (screenSize.x - (imageWidth * canvasScale.x)) / 2;
imagePos.y = (int) (screenSize.y - (imageHeight * canvasScale.y)) / 2;
return imagePos;
}
public PointF getCanvasScale(String imageScale, int imageWidth, int imageHeight) {
PointF canvasScale = new PointF(1f, 1f);
if (imageScale.equals(IMAGE_SCALE_STRETCH_TO_SCREEN)) {
canvasScale.x = getScreenWidth() / (1f * imageWidth);
canvasScale.y = getScreenHeight() / (1f * imageHeight);
} else {
boolean tooWide = false;
boolean tooTall = false;
if (getScreenWidth() < imageWidth) {
tooWide = true;
}
if (getScreenHeight() < imageHeight) {
tooTall = true;
}
if (tooWide && tooTall) {
int x = imageWidth / getScreenWidth();
int y = imageHeight / getScreenHeight();
if (x > y) {
canvasScale.x = getScreenWidth() / (1f * imageWidth);
canvasScale.y = 1;
} else {
canvasScale.x = 1;
canvasScale.y = getScreenHeight() / (1f * imageHeight);
}
} else if (tooWide) {
canvasScale.x = getScreenWidth() / (1f * imageWidth);
canvasScale.y = 1;
} else if (tooTall) {
canvasScale.x = 1;
canvasScale.y = getScreenHeight() / (1f * imageHeight);
}
}
return canvasScale;
}
}
I want Advice for this problem.
Thanks.
no need to do anything just Replace your below method with my code.
private void drawImage(Canvas canvas)
{
Bitmap image = BitmapFactory.decodeResource(getResources(),
mImagesArray[mImagesArrayIndex]);
Bitmap b=Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), true);
canvas.drawBitmap(b, 0,0, null);
}
I would suggest that you crop the images instead of resizing them. Something like:
Rect r = new Rect(left, top, right, bottom);
Bitmap croppedImage = null;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1){
InputStream in = mContentResolver.openInputStream(mSaveUri);
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(in, false);
croppedImage = decoder.decodeRegion(r, null);
} else {
final int width = r.width();
final int height = r.height();
croppedImage = Bitmap.createBitmap(mBitmap, r.left, r.top, width, height);
croppedImage.setDensity(croppedImage.getDensity() * mOutputX / width);
}
return croppedImage;
Hope this helps...

Canvas Touch not working in S4 Android device

The wheel View (CircleView) is working fine in major of devices but this error coming from S4 and Note 3 devices.
The touch is getting deducted but the that not fall under the weidgetregion.
false - 1 has to be true - 1
Region Log is:
My Circle View code is
public class CircleView extends View implements OnTouchListener{
boolean firstTime = false;
private List<CircleViewBean> mMenuEntries = new ArrayList<CircleViewBean>();
private OnCellTouchListener mOnCellTouchListener = null;
public interface OnCellTouchListener {
public void onTouch(Wedge cell);
}
private Shader mShader;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private float screen_density = getContext().getResources().getDisplayMetrics().density;
//Radius of inner ring size
private int mMinSize = scalePX(60);
//Radius of outer ring size
private int mMaxSize = scalePX(170);
private int mWedgeQty = 6;
//Center X location of Radial Menu
private int xPosition = scalePX(120);
//Center Y location of Radial Menu
private int yPosition = scalePX(120);
int touchIndex = -1;
private Wedge[] mWedges;
private RectF mViewRect = new RectF();
private int scalePX( int dp_size )
{
return (int) (dp_size * screen_density + 0.5f);
}
public CircleView(Context context) {
this(context, null);
}
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
HashMap<String, String> device = Constants.getDeviceDetails(getResources().getDisplayMetrics().heightPixels, getResources().getDisplayMetrics().widthPixels);
mMinSize = Integer.parseInt(device.get("in_arc"));
mMaxSize = Integer.parseInt(device.get("out_arc"));
setBackgroundResource(R.drawable.centre_wheel);
}
private void determineWedges() {
int entriesQty = mMenuEntries.size();
if ( entriesQty > 0) {
mWedgeQty = entriesQty;
float degSlice = 360 / mWedgeQty;
float start_degSlice = 270 - (degSlice/2);
//calculates where to put the images
this.mWedges = new Wedge[mWedgeQty];
double mid = 0, min = 0, max = 0;
for(int i = 0; i < this.mWedges.length; i++) {
this.mWedges[i] = new Wedge(xPosition, yPosition, mMinSize, mMaxSize, (i
* degSlice)+start_degSlice, degSlice, mMenuEntries.get(i).getIndex());
mid = this.mWedges[i].midValue = normalizeAngle( ((i * degSlice) + start_degSlice + degSlice) / 2 );
min = normalizeAngle( (i * degSlice) + start_degSlice );
max = normalizeAngle( (i * degSlice) + start_degSlice + degSlice);
this.mWedges[i].minValue = min;
this.mWedges[i].midValue = mid;
this.mWedges[i].maxValue = max;
mViewRect.union( new RectF( mWedges[i].getWedgeRegion().getBounds() ) );
}
mShader = new RadialGradient(xPosition, yPosition, mMaxSize, new int[] { 0xff595756, 0xffCCC5C3, 0xf878280}, null, Shader.TileMode.MIRROR);
invalidate();
}
}
#Override
public void onDraw(Canvas canvas) {
if(!firstTime){
firstTime = true;
this.xPosition = (int) (getWidth()/2f);
this.yPosition = (int) (getHeight()/2f);
determineWedges();
}
canvas.scale(getWidth() / mViewRect.width(), getHeight() / mViewRect.width(), xPosition, yPosition);
//Saving the canvas and later restoring it so only this image will be rotated.
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.restore();
canvas.save();
canvas.restore();
mPaint.setShader( mShader );
}
private double normalizeAngle(double angle) {
if(angle >= 0) {
while( angle > 360 ) {
angle -= 360;
}
}
else {
while( angle < -360) {
angle += 360;
}
}
return angle;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int wmode = MeasureSpec.getMode(widthMeasureSpec);
int hmode = MeasureSpec.getMode(heightMeasureSpec);
int wsize = MeasureSpec.getSize(widthMeasureSpec);
int hsize = MeasureSpec.getSize(heightMeasureSpec);
int width = (int)mViewRect.width();
int height = (int) mViewRect.height();
if (wmode == MeasureSpec.EXACTLY) {
width = wsize;
}
if (hmode == MeasureSpec.EXACTLY) {
height = hsize;
}
this.setMeasuredDimension(width, height);
invalidate();
}
public class Wedge extends Path {
private int x, y;
private int InnerSize, OuterSize;
private float StartArc;
private float ArcWidth;
private Region mWedgeRegion;
private int index=0;
public double minValue;
public double midValue;
public double maxValue;
private Wedge(int x, int y, int InnerSize, int OuterSize, float StartArc, float ArcWidth, int category) {
super();
this.index = category;
if (StartArc >= 360) {
StartArc = StartArc-360;
}
minValue = midValue = maxValue = 0;
mWedgeRegion = new Region();
this.x = x; this.y = y;
this.InnerSize = InnerSize;
this.OuterSize = OuterSize;
this.StartArc = StartArc;
this.ArcWidth = ArcWidth;
this.buildPath();
}
public int getCategoryIndex(){
return this.index;
}
public String toString() {
return minValue + " " + midValue + " " + maxValue;
}
/**
*
* #return the bottom rect that will be used for intersection
*/
public Region getWedgeRegion() {
return mWedgeRegion;
}
private void buildPath() {
final RectF rect = new RectF();
final RectF rect2 = new RectF();
//Rectangles values
rect.set(this.x-this.InnerSize, this.y-this.InnerSize, this.x+this.InnerSize, this.y+this.InnerSize);
rect2.set(this.x-this.OuterSize, this.y-this.OuterSize, this.x+this.OuterSize, this.y+this.OuterSize);
this.reset();
//this.moveTo(100, 100);
this.arcTo(rect2, StartArc, ArcWidth);
this.arcTo(rect, StartArc+ArcWidth, -ArcWidth);
this.close();
mWedgeRegion.setPath( this, new Region(0,0,480,800) );
}
}
public boolean addMenuEntry(CircleViewBean menuEntry) {
mMenuEntries.add(menuEntry);
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
if(mOnCellTouchListener!=null && touchIndex >-1){
int i=0;
for(Wedge day : mWedges) {
if(day.getWedgeRegion().getBounds().contains((int)event.getX(), (int)event.getY()) && touchIndex==i) {
mOnCellTouchListener.onTouch(mWedges[touchIndex]);
break;
}
i++;
}
}
}else if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){
int i=0;
for(Wedge day : mWedges) {
if(day.getWedgeRegion().getBounds().contains((int)event.getX(), (int)event.getY())) {
touchIndex = i;
setBackgroundResource(mMenuEntries.get(touchIndex).getIcon());
}
i++;
}
}
return true;
}
public void setOnCellTouchListener(OnCellTouchListener p) {
mOnCellTouchListener = p;
}
public boolean onTouch(View v, MotionEvent event) {
return false;
}
}
First of all, look at line 307. Learn how to read crash logs because it says exactly on what line the crash is, and then it shouldn't be too hard too determine what is wrong.
Not knowing what line it is I guess that mWedges might be null. in the onTouch you do for(Wedge day : mWedges) but it is not guaranteed that is isn't null there. You should check before you do that if it is null.
You put it to a non null value in determineWedges but only when there is at least 1 mMenuEntries. So when there are no entries when you do an onTouch it will crash.
At last i found my mistake in this code that it is working in mdpi and htpi and not in xxhdpi the reason is
mWedgeRegion.setPath( this, new Region(0,0,480,800) );
The bound exceeds the circle size, i mean the xxhdpi draws an circle with 1000x1000 values, so i made this too like this (max values)
mWedgeRegion.setPath( this, new Region(0,0,720,1200) )

Connecting 2 images in android

I want to connect 2 images in android. Example,
I want them to be like this,
I have already done it by hard coding. First I find the upper left of the green image and then find the the most lower left point of the green side.I do it with touch event's event.gerRawX() and event.getRawY() parameters. Now I know the distance in x and y between those two points. I do the similar thing for the red one too. Now when green piece is moved close to the red I just calculate if upper left point of red piece is near to the lower left of the green piece. if so I translate the green one/ red one to the other one. But this hard coded calculation should fail for same size tablet or phone with different resolution. I just want to know how do I generalize the solution. Thanks.
Edit: My GameActivity and ImageInfo class where I try to connect both images. I have actually 6 images like this. And i wanto connect them. Like image 1 will connect to image 2 and image 2 to 3 and so on.
GameActivity class
package com.example.JigSawPuzzle;
import com.example.test.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
#SuppressLint("NewApi")
public class GameActivity extends Activity implements OnTouchListener
{
static double screenInches;
int touchStartX = 0;
int touchStartY = 0;
int diffX = 0;
int diffY = 0;
int attachedPieces=0;
int imageX = 0;
int imageY = 0;
int height,width;
boolean [] flag = new boolean[7];
boolean isPortait;
RelativeLayout relataivelayoutLayout;
RelativeLayout.LayoutParams paramsA,paramsB,paramsC,paramsD,paramsE,paramsF;
ImageView imageA,imageB,imageC,imageD,imageE,imageF;
ImageInfo [] imageInfoArray = new ImageInfo[7];
// added for sound effect
private SoundPool soundPool;
private int correctPieceAttachSoundId,gameFinishSoundId;
private boolean loaded = false;
//for 10inch landscape height = 752, width = 1280; portrait height = 1232 width = 800
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
isPortait = (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ? false : true;
Display display = getWindowManager().getDefaultDisplay();
height = display.getHeight();
width = display.getWidth();
imageA = new ImageView(this);
imageB = new ImageView(this);
imageC = new ImageView(this);
imageD = new ImageView(this);
imageE = new ImageView(this);
imageF = new ImageView(this);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(dm.widthPixels/dm.xdpi,2);
double y = Math.pow(dm.heightPixels/dm.ydpi,2);
screenInches = Math.sqrt(x+y);
if(screenInches>9.0)
{
imageA.setBackgroundResource(R.drawable.a);
imageB.setBackgroundResource(R.drawable.b);
imageC.setBackgroundResource(R.drawable.c);
imageD.setBackgroundResource(R.drawable.d);
imageE.setBackgroundResource(R.drawable.e);
imageF.setBackgroundResource(R.drawable.f);
}
else
{
imageA.setBackgroundResource(R.drawable.aa);
imageB.setBackgroundResource(R.drawable.bb);
imageC.setBackgroundResource(R.drawable.cc);
imageD.setBackgroundResource(R.drawable.dd);
imageE.setBackgroundResource(R.drawable.ee);
imageF.setBackgroundResource(R.drawable.ff);
}
imageA.setId(1);
imageA.setTag("a");
paramsA = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //The WRAP_CONTENT parameters can be replaced by an absolute width and height or the FILL_PARENT option)
imageA.setLayoutParams(paramsA);
imageA.setOnTouchListener(this);
//Log.d("GameActivity", "")
imageB.setId(2);
imageB.setTag("b");
paramsB = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //The WRAP_CONTENT parameters can be replaced by an absolute width and height or the FILL_PARENT option)
imageB.setLayoutParams(paramsB);
imageB.setOnTouchListener(this);
imageC.setId(3);
imageC.setTag("c");
paramsC = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //The WRAP_CONTENT parameters can be replaced by an absolute width and height or the FILL_PARENT option)
imageC.setLayoutParams(paramsC);
imageC.setOnTouchListener(this);
imageD.setId(4);
imageD.setTag("d");
paramsD = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //The WRAP_CONTENT parameters can be replaced by an absolute width and height or the FILL_PARENT option)
imageD.setLayoutParams(paramsD);
imageD.setOnTouchListener(this);
imageE.setId(5);
imageE.setTag("e");
paramsE = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //The WRAP_CONTENT parameters can be replaced by an absolute width and height or the FILL_PARENT option)
imageE.setLayoutParams(paramsE);
imageE.setOnTouchListener(this);
imageF.setId(6);
imageF.setTag("f");
paramsF = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //The WRAP_CONTENT parameters can be replaced by an absolute width and height or the FILL_PARENT option)
imageF.setLayoutParams(paramsF);
imageF.setOnTouchListener(this);
setupPieces();
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener()
{
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
loaded = true;
}
});
gameFinishSoundId = soundPool.load(this, R.raw.bells, 1);
correctPieceAttachSoundId= soundPool.load(this, R.raw.bell, 1);
}
public void playSound(int soundId)
{
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
if (loaded)
{
soundPool.play(soundId, volume, volume, 1, 0, 1.0f);
}
}
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
// Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
}
else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
{
// Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
// Toast.makeText(this, "in OnConfiguaration Changed", Toast.LENGTH_SHORT).show();
isPortait = (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ? false : true;
((RelativeLayout)imageA.getParent()).removeAllViews();
Log.d("GameActivity", "in onconfigurationChanged");
setupPieces();
}
public void setupPieces()
{
RelativeLayout relataivelayoutLayout = new RelativeLayout(this);
Display display = getWindowManager().getDefaultDisplay();
height = display.getHeight();
width = display.getWidth();
if(!isPortait)
{
paramsA.leftMargin = 10; //Your X coordinate
paramsA.topMargin = 30; //Your Y coordinate
}
else
{
paramsA.leftMargin = 30; //Your X coordinate
paramsA.topMargin = 10; //Your Y coordinate
}
imageA.setLayoutParams(paramsA);
imageA.setOnTouchListener(this);
//Log.d("GameActivity", "")
if(!isPortait)
{
paramsB.leftMargin = 650; //Your X coordinate
paramsB.topMargin = 300; //Your Y coordinate
}
else
{
paramsB.leftMargin = 300; //Your X coordinate
paramsB.topMargin = 750; //Your Y coordinate
}
imageB.setLayoutParams(paramsB);
imageB.setOnTouchListener(this);
if(!isPortait)
{
paramsC.leftMargin = 400; //Your X coordinate
paramsC.topMargin = 380; //Your Y coordinate
}
else
{
paramsC.leftMargin = 400; //Your X coordinate
paramsC.topMargin = 350; //Your Y coordinate
}
imageC.setLayoutParams(paramsC);
imageC.setOnTouchListener(this);
if(!isPortait)
{
paramsD.leftMargin = 750; //Your X coordinate
paramsD.topMargin = 20; //Your Y coordinate
}
else
{
paramsD.leftMargin = 20; //Your X coordinate
paramsD.topMargin = 750; //Your Y coordinate
}
imageD.setLayoutParams(paramsD);
imageD.setOnTouchListener(this);
if(!isPortait)
{
paramsE.leftMargin = 900; //Your X coordinate
paramsE.topMargin = 400; //Your Y coordinate
}
else
{
paramsE.leftMargin = 475; //Your X coordinate
paramsE.topMargin = 700; //Your Y coordinate
}
imageE.setLayoutParams(paramsE);
imageE.setOnTouchListener(this);
if(!isPortait)
{
paramsF.leftMargin = 90; //Your X coordinate
paramsF.topMargin = 300; //Your Y coordinate
}
else
{
paramsF.leftMargin = 90; //Your X coordinate
paramsF.topMargin = 300; //Your Y coordinate
}
imageF.setLayoutParams(paramsF);
imageF.setOnTouchListener(this);
ImageInfo imageAinfo = new ImageInfo(imageA.getId(),imageA,1,2);
imageInfoArray[0] = imageAinfo;
ImageInfo imageBinfo = new ImageInfo(imageB.getId(),imageB,1,3);
imageInfoArray[1] = imageBinfo;
ImageInfo imageCinfo = new ImageInfo(imageC.getId(),imageC,2,4);
imageInfoArray[2] = imageCinfo;
ImageInfo imageDinfo = new ImageInfo(imageD.getId(),imageD,3,5);
imageInfoArray[3] = imageDinfo;
ImageInfo imageEinfo = new ImageInfo(imageE.getId(),imageE,4,6);
imageInfoArray[4] = imageEinfo;
ImageInfo imageFinfo = new ImageInfo(imageF.getId(),imageF,5,6);
imageInfoArray[5] = imageFinfo;
relataivelayoutLayout.addView(imageA);
relataivelayoutLayout.addView(imageB);
relataivelayoutLayout.addView(imageC);
relataivelayoutLayout.addView(imageD);
relataivelayoutLayout.addView(imageE);
relataivelayoutLayout.addView(imageF);
setContentView(relataivelayoutLayout);
}
private void updatePosition(int id)
{
if(flag[imageInfoArray[id-1].id])
return;
flag[imageInfoArray[id-1].id] = true;
RelativeLayout.LayoutParams param = (RelativeLayout.LayoutParams)imageInfoArray[id-1].imageView.getLayoutParams();
param.leftMargin = imageInfoArray[id-1].imageView.getLeft() + diffX;
param.topMargin = imageInfoArray[id-1].imageView.getTop() + diffY;
imageInfoArray[id-1].imageView.setLayoutParams(param);
if(imageInfoArray[id-1].isTopConnected)
updatePosition(imageInfoArray[id-1].topPieceId);
if(imageInfoArray[id-1].isBottomConnected)
updatePosition(imageInfoArray[id-1].bottomPieceId);
return;
}
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(v instanceof ImageView)
{
ImageView imageView = (ImageView) v;
ImageInfo imageInfo = imageInfoArray[imageView.getId()-1];
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
touchStartX = (int) event.getRawX();
touchStartY = (int) event.getRawY();
imageX = imageView.getLeft();
imageY = imageView.getTop();
//Toast.makeText(this, "x = "+event.getRawX()+" y = "+event.getRawY(), Toast.LENGTH_SHORT).show();
break;
case MotionEvent.ACTION_UP:
touchStartX = (int) event.getRawX();
touchStartY = (int) event.getRawY();
imageX = imageView.getLeft();
imageY = imageView.getTop();
int id = imageInfo.id;
while(imageInfo.isTopConnected)
{
if(imageInfo.id == imageInfo.topPieceId)
break;
imageInfo = imageInfoArray[imageInfo.topPieceId-1];
}
if(!imageInfo.isTopConnected)
{
imageView = imageInfo.imageView;
int topConnectingPieceId = imageInfo.topPieceId;
int topConnectingX=0,topConnectingY=0;
topConnectingX = imageInfo.calculateTopX(imageView.getLeft(), imageView.getId());
topConnectingY = imageInfo.calculateTopY(imageView.getTop(), imageView.getId());
ImageInfo topImageInfo = imageInfoArray[topConnectingPieceId-1];
int bottomConnectingX = topImageInfo.calculateBottomX(topImageInfo.imageView.getLeft(),topConnectingPieceId);
int bottomConnectingY = topImageInfo.calculateBottomY(topImageInfo.imageView.getTop(),topConnectingPieceId);
diffX = (bottomConnectingX-topConnectingX);
diffY = (bottomConnectingY-topConnectingY);
if(Math.abs(diffX)<=20 && Math.abs(diffY)<=20)
{
for(int i=0;i<7;i++)
flag[i]=false;
updatePosition(imageInfo.id);
imageInfo.setIsTopConnected(true);
topImageInfo.setIsBottomConnected(true);
attachedPieces++;
if(attachedPieces==5)
{
setupFinishDialogue();
playSound(gameFinishSoundId);
}
else
playSound(correctPieceAttachSoundId);
break;
}
}
imageInfo = imageInfoArray[id-1];
while(imageInfo.isBottomConnected)
{
if(imageInfo.id == imageInfoArray[imageInfo.bottomPieceId-1].id)
break;
imageInfo = imageInfoArray[imageInfo.bottomPieceId-1];
}
imageView = imageInfo.imageView;
if(!imageInfo.isBottomConnected)
{
int topConnectingX=0,topConnectingY=0;
int bottomConnectingX = imageInfo.calculateBottomX(imageView.getLeft(), imageView.getId());
int bottomConnectingY = imageInfo.calculateBottomY(imageView.getTop(), imageView.getId());
int bottomConnectingPieceId = imageInfo.bottomPieceId;
ImageInfo bottomImageInfo = imageInfoArray[bottomConnectingPieceId-1];
topConnectingX = bottomImageInfo.calculateTopX(bottomImageInfo.imageView.getLeft(),bottomConnectingPieceId);
topConnectingY = bottomImageInfo.calculateTopY(bottomImageInfo.imageView.getTop(), bottomConnectingPieceId);
diffX = (topConnectingX-bottomConnectingX);
diffY = (topConnectingY-bottomConnectingY);
if(Math.abs(diffX)<=20 && Math.abs(diffY)<=20)
{
for(int i=0;i<7;i++)
flag[i]=false;
updatePosition(imageInfo.id);
imageInfo.setIsBottomConnected(true);
bottomImageInfo.setIsTopConnected(true);
attachedPieces++;
if(attachedPieces==5)
{
setupFinishDialogue();
playSound(gameFinishSoundId);
}
else
playSound(correctPieceAttachSoundId);
}
}
break;
case MotionEvent.ACTION_MOVE:
diffX = (int) (event.getRawX() - touchStartX);
diffY = (int) (event.getRawY() - touchStartY);
touchStartX = (int)event.getRawX();
touchStartY = (int)event.getRawY();
for(int i=0;i<7;i++)
flag[i]=false;
updatePosition(imageInfo.id);
break;
default:
break;
}
}
return true;
}
void lockOrientation()
{
switch (getResources().getConfiguration().orientation)
{
case Configuration.ORIENTATION_PORTRAIT:
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.FROYO)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else
{
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if(rotation == android.view.Surface.ROTATION_90|| rotation == android.view.Surface.ROTATION_180)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
else
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
break;
case Configuration.ORIENTATION_LANDSCAPE:
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.FROYO)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
else
{
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if(rotation == android.view.Surface.ROTATION_0 || rotation == android.view.Surface.ROTATION_90){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
else
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
break;
}
}
void setupFinishDialogue()
{
/*if(getWindowManager().getDefaultDisplay().getRotation()==3)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else if(getWindowManager().getDefaultDisplay().getRotation()==1)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
else if(getWindowManager().getDefaultDisplay().getRotation()==2)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);*/
lockOrientation();
AlertDialog.Builder builderForAlertBox = new AlertDialog.Builder(this);
builderForAlertBox.setCancelable(false).setMessage("Good Job!").setPositiveButton("Restart", dialogClickListner).setNegativeButton("Quit", dialogClickListner).
setCancelable(true).show();
}
DialogInterface.OnClickListener dialogClickListner = new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
finish();
Intent intent = new Intent(getApplicationContext(),GameActivity.class);
startActivity(intent);
break;
case DialogInterface.BUTTON_NEGATIVE:
finish();
default:
break;
}
}
};
}
ImageInfo Class
package com.example.JigSawPuzzle;
import android.widget.ImageView;
import android.widget.Toast;
public class ImageInfo
{
ImageView imageView;
int imageATopLeftDifferenceX = -1;
int imageATopLeftDifferenceY = -1;
int imageABottomRightDifferenceX = 113;
int imageABottomRightDifferenceY = 140;
int imageBTopLeftDifferenceX = 0;
int imageBTopLeftDifferenceY = 0;
int imageBBottomRightDifferenceX = 0;
int imageBBottomRightDifferenceY = 111;
int imageCTopLeftDifferenceX = 14;
int imageCTopLeftDifferenceY = 0;
int imageCBottomRightDifferenceX = 0;
int imageCBottomRightDifferenceY = 88;
int imageDTopLeftDifferenceX = 92;
int imageDTopLeftDifferenceY = 2;
int imageDBottomRightDifferenceX = 0;
int imageDBottomRightDifferenceY = 70;
/*int imageETopLeftDifferenceX = 0;
int imageETopLeftDifferenceY = 0;
int imageEBottomRightDifferenceX = 55;
int imageEBottomRightDifferenceY = 112;*/
int imageETopLeftDifferenceX = 55;
int imageETopLeftDifferenceY = 112;
int imageEBottomRightDifferenceX = 0;
int imageEBottomRightDifferenceY = 0;
/*int imageFTopLeftDifferenceX = 0;
int imageFTopLeftDifferenceY = 26;
int imageFBottomRightDifferenceX = 0;
int imageFBottomRightDifferenceY = 109;
int id,topPieceId,bottomPieceId;*/
int imageFTopLeftDifferenceX = 0;
int imageFTopLeftDifferenceY = 109;
int imageFBottomRightDifferenceX = 0;
int imageFBottomRightDifferenceY = 26;
int id,topPieceId,bottomPieceId;
boolean isTopConnected = false;
boolean isBottomConnected = false;
public ImageInfo(int id,ImageView imageView,int topPieceId,int bottomPieceId)
{
this.topPieceId = topPieceId;
this.bottomPieceId = bottomPieceId;
this.imageView = imageView;
this.id = id;
if(id==1)
isTopConnected = true;
else if(id==6)
isBottomConnected = true;
if(GameActivity.screenInches>9.0)
initializePiecesInfo();
}
private void initializePiecesInfo()
{
imageATopLeftDifferenceX = 0;
imageATopLeftDifferenceY = 0;
imageABottomRightDifferenceX = 150;
imageABottomRightDifferenceY = 184;
imageBTopLeftDifferenceX = 0;
imageBTopLeftDifferenceY = 0;
imageBBottomRightDifferenceX = 0;
imageBBottomRightDifferenceY = 148;
imageCTopLeftDifferenceX = 23;
imageCTopLeftDifferenceY = 0;
imageCBottomRightDifferenceX = 0;
imageCBottomRightDifferenceY = 115;
imageDTopLeftDifferenceX = 121;
imageDTopLeftDifferenceY = 0;
imageDBottomRightDifferenceX = 0;
imageDBottomRightDifferenceY = 91;
/*int imageETopLeftDifferenceX = 0;
int imageETopLeftDifferenceY = 0;
int imageEBottomRightDifferenceX = 55;
int imageEBottomRightDifferenceY = 112;*/
imageETopLeftDifferenceX = 74;
imageETopLeftDifferenceY = 147;
imageEBottomRightDifferenceX = 0;
imageEBottomRightDifferenceY = 0;
/*int imageFTopLeftDifferenceX = 0;
int imageFTopLeftDifferenceY = 26;
int imageFBottomRightDifferenceX = 0;
int imageFBottomRightDifferenceY = 109;
int id,topPieceId,bottomPieceId;*/
imageFTopLeftDifferenceX = 0;
imageFTopLeftDifferenceY = 144;
imageFBottomRightDifferenceX = 0;
imageFBottomRightDifferenceY = 26;
}
int calculateTopX(int realX,int id)
{
if(id==2)
return realX+imageBTopLeftDifferenceX;
if(id==3)
return realX+imageCTopLeftDifferenceX;
if(id==4)
return realX+imageDTopLeftDifferenceX;
if(id==5)
return realX+imageETopLeftDifferenceX;
if(id==6)
return realX+imageFTopLeftDifferenceX;
return realX;
}
int calculateTopY(int realY,int id)
{
if(id==2)
return realY+imageBTopLeftDifferenceY;
if(id==3)
return realY+imageCTopLeftDifferenceY;
if(id==4)
return realY+imageDTopLeftDifferenceY;
if(id==5)
return realY+imageETopLeftDifferenceY;
if(id==6)
return realY+imageFTopLeftDifferenceY;
return realY;
}
int calculateBottomX(int realX,int id)
{
if(id==1)
return realX+imageABottomRightDifferenceX;
if(id==2)
return realX+imageBBottomRightDifferenceX;
if(id==3)
return realX+imageCBottomRightDifferenceX;
if(id==4)
return realX+imageDBottomRightDifferenceX;
if(id==5)
return realX+imageEBottomRightDifferenceX;
return realX+imageFBottomRightDifferenceX;
}
int calculateBottomY(int realY,int id)
{
if(id==1)
return realY+imageABottomRightDifferenceY;
if(id==2)
return realY+imageBBottomRightDifferenceY;
if(id==3)
return realY+imageCBottomRightDifferenceY;
if(id==4)
return realY+imageDBottomRightDifferenceY;
if(id==5)
return realY+imageEBottomRightDifferenceY;
return realY+imageFBottomRightDifferenceY;
}
void setIsTopConnected(boolean isTopConnected)
{
this.isTopConnected = isTopConnected;
}
void setIsBottomConnected(boolean isBottomConnected)
{
this.isBottomConnected = isBottomConnected;
}
}
Given the images you provided it is straightforward to connect them in a generic way because the images have the same width and they have transparent background, here is the idea:
1- You need the overlap distance between the two images, which you can calculate from either the bottom or top image
The green line in the bottom picture should be equal to the red line in the top picture
Given that your images have transparent background you can calculate this distance easily, I will use the bottom image here.
The idea is to check every pixel in the last column of the bottom bitmap (i.e. width - 1) and stop once you hit a non-transparent pixel.
private int getOverlapDistance(Bitmap bottomBitmap) {
int height = bottomBitmap.getHeight();
int width = bottomBitmap.getWidth();
int distance = 0;
for (int i = 0; i < height; i++) {
if (Color.alpha(bottomBitmap.getPixel(width - 1, i)) != 0) {
distance = (i + 1);
break;
}
}
return distance;
}
To connect them you can do something like (assuming you have separate ImageView for the top and bottom image):
bitmap = ((BitmapDrawable) bottomImage.getDrawable()).getBitmap();
int overlapDistance = getOverlapDistance(bitmap);
bottomImage.setTop(topImage.getBottom() - overlapDistance);
Actually I tried this with a simple activity and it is working, here is how it look like before and after connecting the two images:
I just execute the above code when the button connect is clicked

Categories

Resources