现在越来越多的APP都会有图片展示,这里是模仿微信朋友圈图片展示效果,图片查看器。


android 图片来回显示 安卓图片展示_图片放大效果

主要分为4部分:

1.透明Activity

2.计算gridView下iamgeView Item所在位置

3.一张图大小

4.图片展示动画



1.透明Activity

(1)设置透明Activity的theme

<style name="AppTheme.Transparent" parent="@style/AppTheme">
        <item name="android:windowBackground">@android:color/transparent</item>

        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:backgroundDimEnabled">false</item>
    </style>

(2)解决全屏,非全屏间切换导致的界面重绘(方法封装在BaseActivity,只要继承即可)


在setContentView前



getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);



public void hideStatusBar() {
   WindowManager.LayoutParams attrs = getWindow().getAttributes();
   attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
   getWindow().setAttributes(attrs);

   is_full_screen = false;
   ((FrameLayout.LayoutParams)rootView.getLayoutParams()).topMargin = 0;

}
public void showStatusBar() {
   WindowManager.LayoutParams attrs = getWindow().getAttributes();
   attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
   getWindow().setAttributes(attrs);
   is_full_screen = true;
   ((FrameLayout.LayoutParams)rootView.getLayoutParams()).topMargin = SystemConfig.getTop();

}

在BaseActivity里setContentView后

if (!is_full_screen){
			((FrameLayout.LayoutParams)rootView.getLayoutParams()).topMargin = SystemConfig.getTop();
		}



showStatusBar();
hideStatusBar();
@Override
    public void onPageSelected(int position) {
        Logger.i(Tag,Tag +" onPageSelected position:"+position);
        if (position + 1 == currentPosition){
            imageFragmentNext = imageFragmentCurrent;
            imageFragmentCurrent = imageFragmentPre;
        }else if (position - 1 == currentPosition){
            imageFragmentPre = imageFragmentCurrent;
            imageFragmentCurrent = imageFragmentNext;
        }
        currentPosition = position;
    }
 @Override
        public Fragment getItem(int position) {
            Logger.i(Tag,Tag +" ImagePagerAdapter getItem position:"+position);
            ImageFragment imageFragment = ImageFragment.newInstance(imgDatas.get(position),
                    item_width, item_hight, position, buildXY(position)[0],
                    buildXY(position)[1]);

            /**
             * 记录最多3个imageFragment
             */
            if (position == viewPager.getCurrentItem()){
                imageFragmentCurrent = imageFragment;
            }else if (position + 1 == viewPager.getCurrentItem()){
                imageFragmentPre = imageFragment;
            }else if (position - 1 == viewPager.getCurrentItem()){
                imageFragmentNext = imageFragment;
            }
            return imageFragment;
            // return fragments.get(position);
        }

要重写透明Activity的返回键调用关闭动画






2.计算gridView下iamgeView Item所在位置


/**
     * 当前位置获取首item x,y
     *
     * @param position
     * @return
     */
    public int[] buildOriginXY(int position) {
        int[] location = new int[2];
        int buildX = x - (position % column_num)
                * (item_width + horizontal_space);
        int buildY = y - (position / column_num)
                * (item_hight + vertical_space);
        location[0] = buildX;
        location[1] = buildY;
        return location;
    }

    /**
     * 根据首item x,y获取当前item 的x,y
     *
     * @param position
     * @return
     */
    public int[] buildXY(int position) {
        int[] location = new int[2];
        int buildX = x + (position % column_num)
                * (item_width + horizontal_space);
        int buildY = y + (position / column_num)
                * (item_hight + vertical_space);
        location[0] = buildX;
        location[1] = buildY;
        return location;
    }


3.一张图大小

(1).设置gridview的

if (list.get(position).getImageDatas().size() == 1) {

					viewHold.gvPic.setNumColumns(1);
					viewHold.gvPic.getLayoutParams().width = StringUtil
							.getThumbSize(list.get(position).getImageDatas().get(0) + "")
							.x;

				} else {
					viewHold.gvPic.setNumColumns(3);
					viewHold.gvPic.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
				}


(2).设置gridview 的imageVIewitem

多图的图片大小

imageSize = (SystemConfig.getWidth() - NormalUtil.dip2px(mContext, 90)
				- 2*NormalUtil.dip2px(mContext, 3))/3;

其中SystemConfig.getWidth() - NormalUtil.dip2px(mContext,90)是gridView的宽度,

NormalUtil.dip2px(mContext, 3)是horizontalSpacing,2是gridView默认列数-1,/3中的3是gridView默认列数
if (getCount() == 1) {
				Point sizeData = StringUtil.getThumbSize(imageUrl);
				width = sizeData.x;
				hight = sizeData.y;

			}else {
				width = itemSize;
				hight = itemSize;
			}


4.图片展示动画

(1)判断原图是否已经加载过

boolean originalBitmapExist = BitmapUtil.checkImageExist(StringUtil.getOrg(imgData));

		if (originalBitmapExist) {
			RelativeLayout.LayoutParams photoViewParams = (RelativeLayout.LayoutParams) photoView
					.getLayoutParams();
			photoViewParams.topMargin = (int)y;
			photoViewParams.leftMargin = (int)x;
			photoView.setLayoutParams(photoViewParams);
			loadOrgImg(StringUtil.getOrg(imgData),false);

		}else {
			loadThumbImg(StringUtil.getThumb(imgData, width, hight));
		}


(2).第一次加载背景透明度渐变

/**
	 * 第一次加载背景透明度渐变
	 */
	public  void setBgAlphaAnimation(){
		if (position == ((ShowPictureActivity)mContext).getPositon() && ((ShowPictureActivity)mContext).isFirst()){
			((ShowPictureActivity)mContext).setFirst(false);
			v_parent.setBackgroundColor(Color.BLACK);
			bgAlphaAnimation = new AlphaAnimation(0, (float) 1);
			bgAlphaAnimation.setDuration(NORMAL_SCALE_DURATION);
			bgAlphaAnimation.setFillAfter(true);
			v_parent.startAnimation(bgAlphaAnimation);

		}
	}


(3).缩略图从默认位置到中心位置动画

居中后才加载大图

/**
	 * 缩略图从默认位置到中心位置的动画
	 * 通过改变photoview 的 topMargin ,leftMargin
	 */
	public void centerView(){

		//第一张看到的图且第一次加载的动画
		if (((ShowPictureActivity)mContext).isFirst() && ((ShowPictureActivity)mContext).getPositon() == position) {
			setBgAlphaAnimation();
			valueAnimator = ValueAnimator.ofFloat(0,100);
			valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
				//持有一个IntEvaluator对象,方便下面估值的时候使用
				private IntEvaluator mEvaluator = new IntEvaluator();
				@Override
				public void onAnimationUpdate(ValueAnimator animation) {
					float currentValue = (float) animation.getAnimatedValue();
					//计算当前进度占整个动画过程的比例,浮点型,0-1之间
					float fraction = currentValue / 100f;
					RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) photoView.getLayoutParams();

					/**
					 * 估算当前值
					 */
					params.topMargin = mEvaluator.evaluate(fraction, y, SystemConfig.getHight()/2-hight/2);//从当前y到居中
					params.leftMargin = mEvaluator.evaluate(fraction, x, SystemConfig.getWidth()/2-width/2);//从当前x到居中
					photoView.setLayoutParams(params);


				}
			});
			valueAnimator.setDuration((long) (NORMAL_SCALE_DURATION));
			valueAnimator.addListener(new Animator.AnimatorListener() {
				@Override
				public void onAnimationStart(Animator animator) {

				}

				@Override
				public void onAnimationEnd(Animator animator) {
					errorTime = 0;
					/**
					 * 居中动画结束,加载原图
					 */
					loadOrgImg(StringUtil.getOrg(imgData),true);
				}

				@Override
				public void onAnimationCancel(Animator animator) {

				}

				@Override
				public void onAnimationRepeat(Animator animator) {

				}
			});
			valueAnimator.start();


		}else {//不是第一张或第一次,直接显示居中位置
			RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) photoView
					.getLayoutParams();
			params.topMargin = (int) SystemConfig.getHight()/2-hight/2;
			params.leftMargin = (int) SystemConfig.getWidth()/2-width/2;
			photoView.setLayoutParams(params);
			errorTime = 0;
			loadOrgImg(StringUtil.getOrg(imgData),true);

		}
	}


(4).photoview当前位置放大到全屏动画

/**
	 * photoview当前位置放大到全屏的动画
	 * 通过改变photoview 的 topMargin ,leftMargin,height,width
	 * @param x   photoview的左上角x坐标
	 * @param y   photoview的左上角y坐标
	 * @param from_center 是否从中心来的
     */
	public void fullScreen(final int x,final int y,boolean from_center){//int x, int y,int width,int hight

		Logger.i(Tag, Tag+"fullScreenrx:"+x+"y:"+y);

		if (((ShowPictureActivity)mContext).isFirst() && ((ShowPictureActivity)mContext).getPositon() == position
				|| (from_center && ((ShowPictureActivity)mContext).getCurrentPosition() == position)) {//第一张要显示的图或者居中的且是当前看到的位置
			setBgAlphaAnimation();
			valueAnimator = ValueAnimator.ofFloat(0,100);
			valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
				//持有一个IntEvaluator对象,方便下面估值的时候使用
				private IntEvaluator mEvaluator = new IntEvaluator();
				@Override
				public void onAnimationUpdate(ValueAnimator animation) {
					float currentValue = (float) animation.getAnimatedValue();
					//计算当前进度占整个动画过程的比例,浮点型,0-1之间
					float fraction = currentValue / 100f;
					RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) photoView.getLayoutParams();
					params.height = mEvaluator.evaluate(fraction, hight, SystemConfig.getHight());//从当前缩略图的高度到满屏
					params.width = mEvaluator.evaluate(fraction, width, SystemConfig.getWidth());//从当前缩略图的宽度到满屏
					params.topMargin = mEvaluator.evaluate(fraction, y, 0);//从photoview的y到0
					params.leftMargin = mEvaluator.evaluate(fraction, x, 0);//从photoview的x到0
					photoView.setLayoutParams(params);


				}
			});
			valueAnimator.setDuration((long) (NORMAL_SCALE_DURATION));
			valueAnimator.start();

		}else {
			RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) photoView
					.getLayoutParams();
			params.leftMargin = (int) 0;
			params.topMargin = (int) 0;
			params.height = (int) SystemConfig.getHight();
			params.width = (int) SystemConfig.getWidth();
			photoView.setLayoutParams(params);

		}

	}


(5),关闭动画

/**
	 * 关闭动画
	 */
	public void close(){
		/**
		 * 背景透明
		 */
		v_parent.setBackgroundColor(Color.TRANSPARENT);
		photoView.setBackgroundColor(Color.TRANSPARENT);
		mAttacher.setScaleType(ScaleType.CENTER_CROP);
		/*if (closeScaleType == 1) {
			mAttacher.setScaleType(ScaleType.CENTER_INSIDE);
		}else {
			mAttacher.setScaleType(ScaleType.CENTER_CROP);
		}*/
		final int closeHight = bitMapHight;//结束时的高度以photoView 加载的bitmap高度为准
		final int closeMarginTop = (SystemConfig.getHight() - bitMapHight)/2;

		valueAnimator = ValueAnimator.ofFloat(0,100);
		valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
			//持有一个IntEvaluator对象,方便下面估值的时候使用
			private IntEvaluator mEvaluator = new IntEvaluator();
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				float currentValue = (float) animation.getAnimatedValue();
				//计算当前进度占整个动画过程的比例,浮点型,0-1之间
				float fraction = currentValue / 100f;
				RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) photoView.getLayoutParams();
				params.height = mEvaluator.evaluate(fraction, closeHight, hight);//从当前满屏到缩略图的高度
				params.width = mEvaluator.evaluate(fraction, SystemConfig.getWidth(), width);//从当前满屏到缩略图的宽度
				params.topMargin = mEvaluator.evaluate(fraction, closeMarginTop, y);//从bitmap的左上角y坐标到缩略图的y
				params.leftMargin = mEvaluator.evaluate(fraction, 0, x);//从bitmap的左上角x坐标到缩略图的x
				photoView.setLayoutParams(params);


			}
		});
		valueAnimator.setDuration((long) (NORMAL_SCALE_DURATION));
		valueAnimator.addListener(new Animator.AnimatorListener() {
			@Override
			public void onAnimationStart(Animator animator) {

			}

			@Override
			public void onAnimationEnd(Animator animator) {
				((ShowPictureActivity)mContext).finishAct();
			}

			@Override
			public void onAnimationCancel(Animator animator) {

			}

			@Override
			public void onAnimationRepeat(Animator animator) {

			}
		});

		valueAnimator.start();


	}

demo以及代码下载地址 

第一次发表文章,欢迎指正