现在越来越多的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);
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();
}
第一次发表文章,欢迎指正