public void run() {
   mAllImages.removeImageAt(mCurrentPosition);
   if (mAllImages.getCount() == 0) {
     finish();
     return;
   } else {
     if (mCurrentPosition == mAllImages.getCount()) {
       mCurrentPosition -= 1;
     }
   }
   mImageView.clear();
   mCache.clear(); // Because the position number is changed.
   setImage(mCurrentPosition, true);
 }
  void setMode(int mode) {
    if (mMode == mode) {
      return;
    }
    View slideshowPanel = findViewById(R.id.slideShowContainer);
    View normalPanel = findViewById(R.id.abs);

    Window win = getWindow();
    mMode = mode;
    if (mode == MODE_SLIDESHOW) {
      slideshowPanel.setVisibility(View.VISIBLE);
      normalPanel.setVisibility(View.GONE);

      win.addFlags(
          WindowManager.LayoutParams.FLAG_FULLSCREEN
              | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

      mImageView.clear();
      mActionIconPanel.setVisibility(View.GONE);

      slideshowPanel.getRootView().requestLayout();

      // The preferences we want to read:
      //   mUseShuffleOrder
      //   mSlideShowLoop
      //   mAnimationIndex
      //   mSlideShowInterval

      mUseShuffleOrder = mPrefs.getBoolean(PREF_SHUFFLE_SLIDESHOW, false);
      mSlideShowLoop = mPrefs.getBoolean(PREF_SLIDESHOW_REPEAT, false);
      mAnimationIndex = getPreferencesInteger(mPrefs, "pref_gallery_slideshow_transition_key", 0);
      mSlideShowInterval =
          getPreferencesInteger(mPrefs, "pref_gallery_slideshow_interval_key", 3) * 1000;
    } else {
      slideshowPanel.setVisibility(View.GONE);
      normalPanel.setVisibility(View.VISIBLE);

      win.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
      if (mFullScreenInNormalMode) {
        win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
      } else {
        win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
      }

      if (mGetter != null) {
        mGetter.cancelCurrent();
      }

      if (mShowActionIcons) {
        Animation animation = new AlphaAnimation(0F, 1F);
        animation.setDuration(500);
        mActionIconPanel.setAnimation(animation);
        mActionIconPanel.setVisibility(View.VISIBLE);
      }

      ImageViewTouchBase dst = mImageView;
      for (ImageViewTouchBase ivt : mSlideShowImageViews) {
        ivt.clear();
      }

      mShuffleOrder = null;

      // mGetter null is a proxy for being paused
      if (mGetter != null) {
        setImage(mCurrentPosition, true);
      }
    }
  }
 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
   if (mPaused) return false;
   ImageViewTouch imageView = mImageView;
   if (imageView.getScale() > 1F) {
     imageView.postTranslateCenter(-distanceX, -distanceY);
   }
   return true;
 }
    @Override
    public boolean onDoubleTap(MotionEvent e) {
      if (mPaused) return false;
      ImageViewTouch imageView = mImageView;

      // Switch between the original scale and 3x scale.
      if (imageView.getScale() > 2F) {
        mImageView.zoomTo(1f);
      } else {
        mImageView.zoomToPoint(3f, e.getX(), e.getY());
      }
      return true;
    }
  @Override
  public void onStop() {
    super.onStop();
    mPaused = true;

    // mGetter could be null if we call finish() and leave early in
    // onStart().
    if (mGetter != null) {
      mGetter.cancelCurrent();
      mGetter.stop();
      mGetter = null;
    }
    setMode(MODE_NORMAL);

    // removing all callback in the message queue
    mHandler.removeAllGetterCallbacks();

    if (mAllImages != null) {
      mSavedUri = getCurrentUri();
      mAllImages.close();
      mAllImages = null;
    }

    hideOnScreenControls();
    mImageView.clear();
    mCache.clear();

    for (ImageViewTouchBase iv : mSlideShowImageViews) {
      iv.clear();
    }
  }
  @Override
  public void onCreate(Bundle instanceState) {
    super.onCreate(instanceState);

    Intent intent = getIntent();
    mFullScreenInNormalMode = intent.getBooleanExtra(MediaStore.EXTRA_FULL_SCREEN, true);
    mShowActionIcons = intent.getBooleanExtra(MediaStore.EXTRA_SHOW_ACTION_ICONS, true);

    mPrefs = PreferenceManager.getDefaultSharedPreferences(this);

    setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.viewimage);

    mImageView = (ImageViewTouch) findViewById(R.id.image);
    mImageView.setEnableTrackballScroll(true);
    mCache = new BitmapCache(3);
    mImageView.setRecycler(mCache);

    makeGetter();

    mAnimationIndex = -1;

    mSlideShowInAnimation =
        new Animation[] {
          makeInAnimation(R.anim.transition_in),
          makeInAnimation(R.anim.slide_in),
          makeInAnimation(R.anim.slide_in_vertical),
        };

    mSlideShowOutAnimation =
        new Animation[] {
          makeOutAnimation(R.anim.transition_out),
          makeOutAnimation(R.anim.slide_out),
          makeOutAnimation(R.anim.slide_out_vertical),
        };

    mSlideShowImageViews[0] = (ImageViewTouchBase) findViewById(R.id.image1_slideShow);
    mSlideShowImageViews[1] = (ImageViewTouchBase) findViewById(R.id.image2_slideShow);
    for (ImageViewTouchBase v : mSlideShowImageViews) {
      v.setVisibility(View.INVISIBLE);
      v.setRecycler(mCache);
    }

    mActionIconPanel = findViewById(R.id.action_icon_panel);

    mParam = getIntent().getParcelableExtra(KEY_IMAGE_LIST);

    boolean slideshow;
    if (instanceState != null) {
      mSavedUri = instanceState.getParcelable(STATE_URI);
      slideshow = instanceState.getBoolean(STATE_SLIDESHOW, false);
      mShowControls = instanceState.getBoolean(STATE_SHOW_CONTROLS, true);
    } else {
      mSavedUri = getIntent().getData();
      slideshow = intent.getBooleanExtra(EXTRA_SLIDESHOW, false);
    }

    // We only show action icons for URIs that we know we can share and
    // delete. Although we get read permission (for the images) from
    // applications like MMS, we cannot pass the permission to other
    // activities due to the current framework design.
    if (!MenuHelper.isWhiteListUri(mSavedUri)) {
      mShowActionIcons = false;
    }

    if (mShowActionIcons) {
      int[] pickIds = {R.id.attach, R.id.cancel};
      int[] normalIds = {R.id.setas, R.id.play, R.id.share, R.id.discard};
      int[] connectIds = isPickIntent() ? pickIds : normalIds;
      for (int id : connectIds) {
        View view = mActionIconPanel.findViewById(id);
        view.setVisibility(View.VISIBLE);
        view.setOnClickListener(this);
      }
    }

    // Don't show the "delete" icon for SingleImageList.
    if (ImageManager.isSingleImageMode(mSavedUri.toString())) {
      mActionIconPanel.findViewById(R.id.discard).setVisibility(View.GONE);
    }

    if (slideshow) {
      setMode(MODE_SLIDESHOW);
    } else {
      if (mFullScreenInNormalMode) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
      }
      if (mShowActionIcons) {
        mActionIconPanel.setVisibility(View.VISIBLE);
      }
    }

    setupOnScreenControls(findViewById(R.id.rootLayout), mImageView);
  }
  void setImage(int pos, boolean showControls) {
    mCurrentPosition = pos;

    Bitmap b = mCache.getBitmap(pos);
    if (b != null) {
      IImage image = mAllImages.getImageAt(pos);
      mImageView.setImageRotateBitmapResetBase(
          new RotateBitmap(b, image.getDegreesRotated()), true);
      updateZoomButtonsEnabled();
    }

    ImageGetterCallback cb =
        new ImageGetterCallback() {
          public void completed() {}

          public boolean wantsThumbnail(int pos, int offset) {
            return !mCache.hasBitmap(pos + offset);
          }

          public boolean wantsFullImage(int pos, int offset) {
            return offset == 0;
          }

          public int fullImageSizeToUse(int pos, int offset) {
            // this number should be bigger so that we can zoom.  we may
            // need to get fancier and read in the fuller size image as the
            // user starts to zoom.
            // Originally the value is set to 480 in order to avoid OOM.
            // Now we set it to 2048 because of using
            // native memory allocation for Bitmaps.
            final int imageViewSize = 2048;
            return imageViewSize;
          }

          public int[] loadOrder() {
            return sOrderAdjacents;
          }

          public void imageLoaded(int pos, int offset, RotateBitmap bitmap, boolean isThumb) {
            // shouldn't get here after onPause()

            // We may get a result from a previous request. Ignore it.
            if (pos != mCurrentPosition) {
              bitmap.recycle();
              return;
            }

            if (isThumb) {
              mCache.put(pos + offset, bitmap.getBitmap());
            }
            if (offset == 0) {
              // isThumb: We always load thumb bitmap first, so we will
              // reset the supp matrix for then thumb bitmap, and keep
              // the supp matrix when the full bitmap is loaded.
              mImageView.setImageRotateBitmapResetBase(bitmap, isThumb);
              updateZoomButtonsEnabled();
            }
          }
        };

    // Could be null if we're stopping a slide show in the course of pausing
    if (mGetter != null) {
      mGetter.setPosition(pos, cb, mAllImages, mHandler);
    }
    updateActionIcons();
    if (showControls) showOnScreenControls();
    scheduleDismissOnScreenControls();
  }
 private void updateZoomButtonsEnabled() {
   ImageViewTouch imageView = mImageView;
   float scale = imageView.getScale();
   mZoomButtonsController.setZoomInEnabled(scale < imageView.mMaxZoom);
   mZoomButtonsController.setZoomOutEnabled(scale > 1);
 }