現在越來越多的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();
}
在
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;
}
(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);
}
}
居中後才加載大圖
/**
* 縮略圖從默認位置到中心位置的動畫
* 通過改變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
第一次發表文章,歡迎指正