当前位置: 代码迷 >> 综合 >> Banner 点击图片放大(可以滑动)
  详细解决方案

Banner 点击图片放大(可以滑动)

热度:111   发布时间:2023-11-15 19:12:56.0

在Banner页面:

 final ArrayList<String> list = new ArrayList<>();

  banner.setOnBannerListener(new OnBannerListener() {@Overridepublic void OnBannerClick(int position) {Intent intent = new Intent(MainActivity.this, Main2Activity.class);intent.putStringArrayListExtra("imageUrls", list);intent.putExtra("position", position);startActivity(intent);}});

activity_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v4.view.ViewPagerandroid:id="@+id/iamge_scale_pager"android:layout_width="match_parent"android:layout_height="match_parent"></android.support.v4.view.ViewPager><TextViewandroid:id="@+id/image_scale_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_margin="10dp"android:text="2/5"android:textColor="#66000000"android:textSize="30sp" />
</RelativeLayout>

Main2Activity

public class Main2Activity extends AppCompatActivity {private ViewPager iamge_scale_pager;private TextView image_scale_text;private ArrayList<String> imageUrls;private int position;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);initView();}private void initView() {iamge_scale_pager = (ViewPager) findViewById(R.id.iamge_scale_pager);image_scale_text = (TextView) findViewById(R.id.image_scale_text);//接收数据Intent intent = getIntent();imageUrls = intent.getStringArrayListExtra("imageUrls");position = intent.getIntExtra("position", -1);//判断 集合不为空null 集合的长度大于0 position不是-1//给viewPager设置适配器if (imageUrls != null && imageUrls.size()>0 && position != -1) {//1.textView展示第几张图片image_scale_text.setText((position+1)+"/"+imageUrls.size());//2.设置适配器ImageScaleAdapter imageScaleAdapter = new ImageScaleAdapter();iamge_scale_pager.setAdapter(imageScaleAdapter);//3.设置显示的是点击的那张图片..setCurrentItem()//boolean smoothScroll...是否滚动iamge_scale_pager.setCurrentItem(position,false);//设置监听iamge_scale_pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {//设置文本显示image_scale_text.setText((position+1)+"/"+imageUrls.size());}@Overridepublic void onPageScrollStateChanged(int state) {}});}}private class ImageScaleAdapter extends PagerAdapter {@Overridepublic int getCount() {return imageUrls.size();}@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object object) {return view == object;}@NonNull@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {//创建imageView(可以放大缩小的iamgeView...自定义的)ZoomImageView zoomImageView = new ZoomImageView(Main2Activity.this);//使用glide加载图片Glide.with(Main2Activity.this).load(imageUrls.get(position)).into(zoomImageView);//添加到容器containercontainer.addView(zoomImageView);//返回这个viewreturn zoomImageView;}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {//从容器中移除这个viewcontainer.removeView((View) object);}}
}


import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver;
import android.widget.ImageView;@SuppressLint("AppCompatCustomView")
public class ZoomImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener, ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener {private boolean mOnce;/*** 初始化时缩放的值*/private float mInitScale;/*** 双击放大值到达的值*/private float mMidScale;/*** 放大的最大值*/private float mMaxScale;private Matrix mScaleMatrix;/*** 捕获用户多指触控时缩放的比例*/private ScaleGestureDetector mScaleGestureDetector;// **********自由移动的变量***********/*** 记录上一次多点触控的数量*/private int mLastPointerCount;private float mLastX;private float mLastY;private int mTouchSlop;private boolean isCanDrag;private boolean isCheckLeftAndRight;private boolean isCheckTopAndBottom;// *********双击放大与缩小*********private GestureDetector mGestureDetector;private boolean isAutoScale;public ZoomImageView(Context context) {this(context, null);}public ZoomImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ZoomImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// initmScaleMatrix = new Matrix();setScaleType(ScaleType.MATRIX);setOnTouchListener(this);mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();mScaleGestureDetector = new ScaleGestureDetector(context, this);mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onDoubleTap(MotionEvent e) {if (isAutoScale) {return true;}float x = e.getX();float y = e.getY();if (getScale() < mMidScale) {postDelayed(new AutoScaleRunnable(mMidScale, x, y), 16);isAutoScale = true;} else {postDelayed(new AutoScaleRunnable(mInitScale, x, y), 16);isAutoScale = true;}return true;}});}/*** 自动放大与缩小** @author zhangyan@lzt.com.cn**/private class AutoScaleRunnable implements Runnable {/*** 缩放的目标值*/private float mTargetScale;// 缩放的中心点private float x;private float y;private final float BIGGER = 1.07f;private final float SMALL = 0.93f;private float tmpScale;/*** @param mTargetScale* @param x* @param y*/public AutoScaleRunnable(float mTargetScale, float x, float y) {this.mTargetScale = mTargetScale;this.x = x;this.y = y;if (getScale() < mTargetScale) {tmpScale = BIGGER;}if (getScale() > mTargetScale) {tmpScale = SMALL;}}@Overridepublic void run() {//进行缩放mScaleMatrix.postScale(tmpScale, tmpScale, x, y);checkBorderAndCenterWhenScale();setImageMatrix(mScaleMatrix);float currentScale = getScale();if ((tmpScale >1.0f && currentScale <mTargetScale) ||(tmpScale<1.0f &currentScale>mTargetScale)) {//这个方法是重新调用run()方法postDelayed(this, 16);}else{//设置为我们的目标值float scale = mTargetScale/currentScale;mScaleMatrix.postScale(scale, scale, x, y);checkBorderAndCenterWhenScale();setImageMatrix(mScaleMatrix);isAutoScale = false;}}}/*** 获取ImageView加载完成的图片*/@Overridepublic void onGlobalLayout() {if (!mOnce) {// 得到控件的宽和高int width = getWidth();int height = getHeight();// 得到我们的图片,以及宽和高Drawable drawable = getDrawable();if (drawable == null) {return;}int dh = drawable.getIntrinsicHeight();int dw = drawable.getIntrinsicWidth();float scale = 0.6f;// 图片的宽度大于控件的宽度,图片的高度小于空间的高度,我们将其缩小if (dw > width && dh < height) {scale = width * 1.0f / dw;}// 图片的宽度小于控件的宽度,图片的高度大于空间的高度,我们将其缩小if (dh > height && dw < width) {scale = height * 1.0f / dh;}// 缩小值if (dw > width && dh > height) {scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);}// 放大值if (dw < width && dh < height) {scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);}/*** 得到了初始化时缩放的比例*/mInitScale = scale;mMaxScale = mInitScale * 4;mMidScale = mInitScale * 2;// 将图片移动至控件的中间int dx = getWidth() / 2 - dw / 2;int dy = getHeight() / 2 - dh / 2;mScaleMatrix.postTranslate(dx, dy);mScaleMatrix.postScale(mInitScale, mInitScale, width / 2,height / 2);setImageMatrix(mScaleMatrix);mOnce = true;}}/*** 注册OnGlobalLayoutListener这个接口*/@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();getViewTreeObserver().addOnGlobalLayoutListener(this);}/*** 取消OnGlobalLayoutListener这个接口*/@SuppressWarnings("deprecation")@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();getViewTreeObserver().removeGlobalOnLayoutListener(this);}/*** 获取当前图片的缩放值** @return*/public float getScale() {float[] values = new float[9];mScaleMatrix.getValues(values);return values[Matrix.MSCALE_X];}// 缩放区间时initScale maxScale@Overridepublic boolean onScale(ScaleGestureDetector detector) {float scale = getScale();float scaleFactor = detector.getScaleFactor();if (getDrawable() == null) {return true;}// 缩放范围的控制if ((scale < mMaxScale && scaleFactor > 1.0f)|| (scale > mInitScale && scaleFactor < 1.0f)) {if (scale * scaleFactor < mInitScale) {scaleFactor = mInitScale / scale;}if (scale * scaleFactor > mMaxScale) {scale = mMaxScale / scale;}// 缩放mScaleMatrix.postScale(scaleFactor, scaleFactor,detector.getFocusX(), detector.getFocusY());checkBorderAndCenterWhenScale();setImageMatrix(mScaleMatrix);}return true;}/*** 获得图片放大缩小以后的宽和高,以及left,right,top,bottom** @return*/private RectF getMatrixRectF() {Matrix matrix = mScaleMatrix;RectF rectF = new RectF();Drawable d = getDrawable();if (d != null) {rectF.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());matrix.mapRect(rectF);}return rectF;}/*** 在缩放的时候进行边界以及我们的位置的控制*/private void checkBorderAndCenterWhenScale() {RectF rectF = getMatrixRectF();float deltaX = 0;float deltaY = 0;int width = getWidth();int height = getHeight();// 缩放时进行边界检测,防止出现白边if (rectF.width() >= width) {if (rectF.left > 0) {deltaX = -rectF.left;}if (rectF.right < width) {deltaX = width - rectF.right;}}if (rectF.height() >= height) {if (rectF.top > 0) {deltaY = -rectF.top;}if (rectF.bottom < height) {deltaY = height - rectF.bottom;}}/*** 如果宽度或高度小于空间的宽或者高,则让其居中*/if (rectF.width() < width) {deltaX = width / 2f - rectF.right + rectF.width() / 2f;}if (rectF.height() < height) {deltaY = height / 2f - rectF.bottom + rectF.height() / 2f;}mScaleMatrix.postTranslate(deltaX, deltaY);}@Overridepublic boolean onScaleBegin(ScaleGestureDetector detector) {return true;}@Overridepublic void onScaleEnd(ScaleGestureDetector detector) {}@Overridepublic boolean onTouch(View v, MotionEvent event) {if (mGestureDetector.onTouchEvent(event)) {return true;}mScaleGestureDetector.onTouchEvent(event);float x = 0;float y = 0;// 拿到多点触控的数量int pointerCount = event.getPointerCount();for (int i = 0; i < pointerCount; i++) {x += event.getX(i);y += event.getY(i);}x /= pointerCount;y /= pointerCount;if (mLastPointerCount != pointerCount) {isCanDrag = false;mLastX = x;mLastY = y;}mLastPointerCount = pointerCount;RectF rectF = getMatrixRectF();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (rectF.width()>getWidth() +0.01|| rectF.height()>getHeight()+0.01) {if(getParent() instanceof ViewPager)getParent().requestDisallowInterceptTouchEvent(true);}break;case MotionEvent.ACTION_MOVE:if (rectF.width()>getWidth()+0.01 || rectF.height()>getHeight()+0.01) {if(getParent() instanceof ViewPager)getParent().requestDisallowInterceptTouchEvent(true);}float dx = x - mLastX;float dy = y - mLastY;if (!isCanDrag) {isCanDrag = isMoveAction(dx, dy);}if (isCanDrag) {if (getDrawable() != null) {isCheckLeftAndRight = isCheckTopAndBottom = true;// 如果宽度小于控件宽度,不允许横向移动if (rectF.width() < getWidth()) {isCheckLeftAndRight = false;dx = 0;}// 如果高度小于控件高度,不允许纵向移动if (rectF.height() < getHeight()) {isCheckTopAndBottom = false;dy = 0;}mScaleMatrix.postTranslate(dx, dy);checkBorderWhenTranslate();setImageMatrix(mScaleMatrix);}}mLastX = x;mLastY = y;break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:mLastPointerCount = 0;break;default:break;}return true;}/*** 当移动时进行边界检查*/private void checkBorderWhenTranslate() {RectF rectF = getMatrixRectF();float deltaX = 0;float deltaY = 0;int width = getWidth();int heigth = getHeight();if (rectF.top > 0 && isCheckTopAndBottom) {deltaY = -rectF.top;}if (rectF.bottom < heigth && isCheckTopAndBottom) {deltaY = heigth - rectF.bottom;}if (rectF.left > 0 && isCheckLeftAndRight) {deltaX = -rectF.left;}if (rectF.right < width && isCheckLeftAndRight) {deltaX = width - rectF.right;}mScaleMatrix.postTranslate(deltaX, deltaY);}/*** 判断是否是move** @param dx* @param dy* @return*/private boolean isMoveAction(float dx, float dy) {return Math.sqrt(dx * dx + dy * dy) > mTouchSlop;}
}

依赖     

 
 
//图片compile 'com.squareup.picasso:picasso:2.5.2'compile 'com.github.bumptech.glide:glide:3.6.1'compile 'com.facebook.fresco:fresco:1.8.1'
//Imageloadercompile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'compile 'com.youth.banner:banner:1.4.9'
权限:联网
<uses-permission android:name="android.permission.INTERNET"/>