Edit I commented out this code from PhotoSortrView.load()
if (this.maxX < SCREEN_MARGIN)
cx = SCREEN_MARGIN;
else if (this.minX > displayWidth - SCREEN_MARGIN)
cx = displayWidth - SCREEN_MARGIN;
if (this.maxY > SCREEN_MARGIN)
cy = SCREEN_MARGIN;
else if (this.minY > displayHeight - SCREEN_MARGIN)
cy = displayHeight - SCREEN_MARGIN;
And now it works. This is probably a hack fix. The professional fix may be in checking minX and display width and seeing why it fires the if statements there when it's on the screen. Maybe it should be changed to this.centreX instead of this.minX. Those if statements are firing too often. Anyways commented out it works, I am happy with that for now. Thanks.
I'm using this awesome library: https://code.google.com/p/android-multitouch-controller/ In particular, the PhotoSortrView class of the example app it provides. I provide enough code for anyone to try and help.
It is working great. It enables my images to be dragged, rotated, and scaled, with touch gestures. However I am constantly leaving my activity that implements it, to choose new images, and then adding the images and re-entering the activity. It seems as though it has to call onPause() and onResume() which have to call unloadImages() and loadImages(), otherwise it causes my app to crash because it tries to draw images that are null. However they cause the previous images to load in a different position on the screen each time. If I can either not call these so the images are not unloaded and just have a slower app but the images stay in their position, or reuse the image position and scale information so they reload into the same position each time, that would be great. Here is the code. When I say my activity, it is all one activity where this all takes place. The only other class involved is PhotoSortrView.
My Activity Class declaration:
public class MyActivity extends Activity implements OnClickListener {
My Activity.onPause():
@Override
protected void onPause() {
super.onPause();
photoSorter.unloadImages();
}
My Activity.onResume():
@Override
protected void onResume() {
super.onResume();
photoSorter.loadImages(this);
}
PhotoSortrView class declaration:
public class PhotoSortrView extends View implements MultiTouchObjectCanvas<PhotoSortrView.Img> {
PhotoSortrView.unloadImages():
/** Called by activity's onPause() method to free memory used for loading the images */
public void unloadImages() {
int n = mImages.size();
for (int i = 0; i < n; i++){
//this.imgX = mImages.get(i).getCenterX();
//this.imgY = mImages.get(i).getCenterY();
mImages.get(i).unload();
}
}
PhotoSortrView.loadImages() (Notice this calls PhotoSortrView.load())
/** Called by activity's onResume() method to load the images */
public void loadImages(Context context) {
Resources res = context.getResources();
int n = mImages.size();
for (int i = 0; i < n; i++)
mImages.get(i).load(res);
}
PhotoSortrView.load():
/** Called by activity's onResume() method to load the images */
public void load(Resources res) {
getMetrics(res);
this.drawable = res.getDrawable(resId);
this.width = drawable.getIntrinsicWidth();
this.height = drawable.getIntrinsicHeight();
float cx, cy, sx, sy;
if (firstLoad) {
cx = SCREEN_MARGIN + (float) (Math.random() * (displayWidth - 2 * SCREEN_MARGIN));
cy = SCREEN_MARGIN + (float) (Math.random() * (displayHeight - 2 * SCREEN_MARGIN));
float sc = (float) (Math.max(displayWidth, displayHeight) / (float) Math.max(width, height) * Math.random() * 0.3 + 0.2);
sx = sy = sc;
firstLoad = false;
} else {
// Reuse position and scale information if it is available
// FIXME this doesn't actually work because the whole activity is torn down and re-created on rotate
cx = this.centerX;
cy = this.centerY;
sx = this.scaleX;
sy = this.scaleY;
// Make sure the image is not off the screen after a screen rotation
if (this.maxX < SCREEN_MARGIN)
cx = SCREEN_MARGIN;
else if (this.minX > displayWidth - SCREEN_MARGIN)
cx = displayWidth - SCREEN_MARGIN;
if (this.maxY > SCREEN_MARGIN)
cy = SCREEN_MARGIN;
else if (this.minY > displayHeight - SCREEN_MARGIN)
cy = displayHeight - SCREEN_MARGIN;
}
setPos(cx, cy, sx, sy, 0.0f);
}
Notice in PhotoSortrView.load()
that it says "Reuse position and scale information if it is available. FIXME this doesn't actually work because the whole activity is torn down and re-created on rotate".
Now my app will not implememnt screen rotation. It will always be portrait. I have not yet implemented this. However I have tested the app while never rotating it and the images do not retain their position and scale upon reloading. Should I be implementing only portrait into my app first to see if that works? Or looking for the rotation code within the third party library and disabling it? Or trying to make my own method to capture the image position and scale and apply it on reload? I can get the image position easily.
Me leaving the myActivity:
private void chooseImages(int menuId) {
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("menuId", menuId);
startActivityForResult(intent, 1);
}
Me returning:
@SuppressLint("NewApi")
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case (1) : {
if (resultCode == Activity.RESULT_OK) {
//add LInearLayout
RelativeLayout myLInearLayout =(RelativeLayout) findViewById(R.id.layout);
//String newText = data.getStringExtra("imagePath");
int drawable = data.getIntExtra("imagePath", 0);
photoSorter.addDrawable(drawable, this);
//Log.d("tag", "I have set the text " + newText);
}
break;
}
}
}
My activity onCreate:
PhotoSortrView photoSorter;
public static String getmProfilePicPath(){
return mProfilePicPath;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if( savedInstanceState != null ) {
Toast.makeText(this, savedInstanceState.getString("message"), Toast.LENGTH_LONG).show();
Log.d("message", savedInstanceState.getString("message"));
}
setContentView(R.layout.activity_dressing_room);
mDb = new dbhelper(this);
this.mName = getMname();
AppUser user = mDb.getAppUser(mName);
mProfilePicPath = user.getImagePath();
setBackgroundImage();
photoSorter = new PhotoSortrView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.addContentView(photoSorter, params);
gd = new GestureDetector(this, new MyGestureDetector());
otl = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return gd.onTouchEvent(event);
}
};
photoSorter.setOnClickListener(this);
photoSorter.setOnTouchListener(otl);
}