有段时间闲来没事的时候,想研究一下微信朋友圈的图片点击效果,一开始的感觉是用跳转activity去实现。但是后面为了封装而好用。于是自己重新写了一个类,封装其它们。
我是准备用PopupWindow来做整体框架;简单来说,就是把涉及到的ViewPager,圈圈等都封装到一个类里面。
点击图片,会放大至全屏,移动到中心。因为图片是在listView里面的。如果针对原ImageView动画的话,会被其他控件遮挡。(尝试去写就会发现)。所以需要在PopupWindow新建一个原ImageView,去动画。(这里应该有其他更好的办法,如果有高手请提示一下!!)
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import java.util.ArrayList;
public class PhotoBrowser {
private int[] old_LeftTop = new int[2]; //初始 原图片 位置(相对Windows)
private final int ANIM_DURATION=300; //动画时间
private final int QUAN_HW=6; //圈圈大小
private final int QUAN_INTERVAL=2; //圈圈之间的间隔的一半
private ImageView srcImage; //发生事件的 原图片
private ArrayList imageUrls; //图片url集合
private int photo_index;// 原图片 索引
private PopupWindow window; //弹出窗口
private LinearLayout linQuanQuan; // 圈圈根布局
private ViewPager newView; //新的 ViewPager
private ImageView oldView; //复制的原图片
public PhotoBrowser(ImageView srcImage,int photo_index, ArrayList imageUrls) {
super();
this.srcImage = srcImage;
this.photo_index=photo_index;
this.imageUrls = imageUrls;
}
public void setSrcImage(ImageView srcImage) {
this.srcImage = srcImage;
}
public void setPhotoIndex(int photo_index) {
this.photo_index = photo_index;
}
public void setImageUrls(ArrayList imageUrls) {
this.imageUrls = imageUrls;
}
public void show(){
// 显示图片
FrameLayout popView=new FrameLayout(srcImage.getContext());
popView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
popView.addView(createSrcImage());
popView.addView(createViewPager());
if(imageUrls.size()>1){
popView.addView(createPoints());
}
window = new PopupWindow(popView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
window.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
srcImage=null;
imageUrls=null;
linQuanQuan=null;
oldView=null;
newView=null;
window=null;
}
});
window.setBackgroundDrawable(srcImage.getContext().getResources().getDrawable(android.R.color.black));
window.setAnimationStyle(0);
window.setFocusable(true);
window.update();
window.showAtLocation(srcImage, Gravity.CENTER, 0, 0);
animZoomBig();
}
private ImageView createSrcImage(){
oldView = new ImageView(srcImage.getContext());
srcImage.getLocationOnScreen(old_LeftTop);
FrameLayout.LayoutParams old_params=new FrameLayout.LayoutParams(srcImage.getWidth(), srcImage.getHeight());
old_params.leftMargin=old_LeftTop[0];
old_params.topMargin=old_LeftTop[1];
oldView.setLayoutParams(old_params);
oldView.setImageDrawable(srcImage.getDrawable());
return oldView;
}
private ViewPager createViewPager(){
newView = new HackyViewPager(srcImage.getContext());
FrameLayout.LayoutParams new_params=new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
newView.setLayoutParams(new_params);
newView.setAdapter(new PhotoAdapter());
newView.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int positioin) {
refreshQuanQuan(positioin);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
newView.setVisibility(View.GONE);
return newView;
}
private View createPoints(){
linQuanQuan = new LinearLayout(srcImage.getContext());
FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity=Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
params.bottomMargin=20;
linQuanQuan.setLayoutParams(params);
linQuanQuan.setVisibility(View.GONE);
addQuanQuan(imageUrls.size());
return linQuanQuan;
}
private void addQuanQuan(int size) {
linQuanQuan.removeAllViews();
float density=srcImage.getContext().getResources().getDisplayMetrics().density;
for (int i = 0; i < size; i++) {
ImageView imageView = new ImageView(srcImage.getContext());
LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams((int)(QUAN_HW*density), (int)(QUAN_HW*density));
lParams.leftMargin = (int)(QUAN_INTERVAL*density);
lParams.rightMargin = (int)(QUAN_INTERVAL*density);
imageView.setLayoutParams(lParams);
imageView.setBackgroundResource(android.R.color.darker_gray);
linQuanQuan.addView(imageView);
}
}
private void refreshQuanQuan(int positioin) {
int count = linQuanQuan.getChildCount();
for (int i = 0; i < count; i++) {
if (i == positioin) {
linQuanQuan.getChildAt(i).setBackgroundResource(
android.R.color.white);
} else {
linQuanQuan.getChildAt(i).setBackgroundResource(
android.R.color.darker_gray);
}
}
}
private void animZoomBig(){
int screenW=srcImage.getContext().getResources().getDisplayMetrics().widthPixels;
int screenH=srcImage.getContext().getResources().getDisplayMetrics().heightPixels;
int viewW=srcImage.getWidth();
int viewH=srcImage.getHeight();
float scaleW=((float)screenW)/viewW;
float scaleH=((float)screenH)/viewH;
float scale=scaleW<=scaleH?scaleW:scaleH; //选择小的
int[] new_LeftTop=new int[2];
new_LeftTop[0]=(int) (screenW-viewW*scale)/2;
new_LeftTop[1]=(int) (screenH-viewH*scale)/2;
//放大动画
AnimationSet animSet=new AnimationSet(true);
ScaleAnimation scaleAnim=new ScaleAnimation(1.0f, scale, 1.0f, scale, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
TranslateAnimation tranAnim=new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.ABSOLUTE, new_LeftTop[0]-old_LeftTop[0], Animation.RELATIVE_TO_SELF, 0f, Animation.ABSOLUTE, new_LeftTop[1]-old_LeftTop[1]);
animSet.addAnimation(scaleAnim);
animSet.addAnimation(tranAnim);
animSet.setInterpolator(new DecelerateInterpolator());
animSet.setDuration(ANIM_DURATION);
animSet.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
oldView.setVisibility(View.GONE);
newView.setVisibility(View.VISIBLE);
linQuanQuan.setVisibility(View.VISIBLE);
newView.setCurrentItem(photo_index);
if(photo_index==0){
refreshQuanQuan(0);
}
}
});
oldView.startAnimation(animSet);
}
class PhotoAdapter extends PagerAdapter {
@Override
public int getCount() {
return imageUrls==null ? 0:imageUrls.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View)object);
}
@Override
public Object instantiateItem(View container, int position) {
PhotoView photoView = new PhotoView(srcImage.getContext());
FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
params.gravity=Gravity.CENTER;
photoView.setLayoutParams(params);
if(position==photo_index){
photoView.setImageDrawable(srcImage.getDrawable());
}else{
//通过url获取图片
photoView.setImageUrl(imageUrls.get(position));
}
photoView.setOnPhotoTapListener(new OnPhotoTapListener() {
@Override
public void onPhotoTap(View view, float x, float y) {
window.dismiss();
}
});
((ViewPager) container).addView(photoView);
return photoView;
}
}
class HackyViewPager extends ViewPager{
public HackyViewPager(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
try {
return super.dispatchTouchEvent(ev);
} catch (Exception e) {
return false;
}
}
}
}
上面代码,用到的PhotoView是github上面的。并且只是简单实现了 放大移动效果, 而没有实现 缩小返回效果。当然具体还有许多细节没有做好。大家多多指教~~~~~