0

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);
    }
user3164083
  • 1,053
  • 6
  • 18
  • 35

1 Answers1

0

You should use Activity onSaveInstanceState to save whatever information you need to when the activity is destroyed, and that information will be passed via the bundle in onCreate.

I don't know why you need to do this on every onPause and onResume though, can you just not unload and reload the images?

Greg Ennis
  • 14,917
  • 2
  • 69
  • 74
  • Thanks! I have commented out `photoSorter.unloadImages();` within myActivity.onPause(). There is no exception but the images still move. I think if I edit PhotoSortrView.load() I can stop them moving. If you were to have a look at that method in my question too and see what you think that would be much appreciated thank you. – user3164083 Jan 13 '14 at 01:40
  • If I comment out `photoSorter.loadImages(this);` it causes a nullPointerException in the Image.draw method. I guess without loading the images, they are not there. But I'm not unloading them so that's strange. – user3164083 Jan 13 '14 at 01:44
  • Also having trouble implementing onSaveInstance state. I added code from [here](http://stackoverflow.com/a/6525808/3164083) to my activity but it never fired as it did not make the toast message. It wouldn't add to PhotoSortrView because its super class doesn't implement it. Thanks. – user3164083 Jan 13 '14 at 02:22