现在越来越多的APP都会有图片展示,这里是模仿微信朋友圈图片展示效果,图片查看器。
主要分为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);
在BaseActivity里setContentView后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(); }
if (!is_full_screen){ ((FrameLayout.LayoutParams)rootView.getLayoutParams()).topMargin = SystemConfig.getTop(); }
在setContentView后要改变状态栏的显示隐藏调用showStatusBar();
hideStatusBar();
记录当前IamgeFragment以及上一个,下一个,为了按返回键的时候能够调用当前amgeFragment关闭的动画@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多图的图片大小
其中SystemConfig.getWidth() - NormalUtil.dip2px(mContext,90)是gridView的宽度,imageSize = (SystemConfig.getWidth() - NormalUtil.dip2px(mContext, 90) - 2*NormalUtil.dip2px(mContext, 3))/3;
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以及代码下载地址http://download.csdn.net/detail/yyyangyy/9777892
第一次发表文章,欢迎指正