安卓图片(ImageView):展示大图、双击放大、触摸放大缩小、滑动切换、长按保存等

安卓图片(ImageView):展示大图、双击放大、触摸放大缩小、滑动切换、长按保存等

背景:由于项目中需要做一个图片展示功能,大概就是在一个页面中有一个listview或者recyclerview的布局,然后item中有图文混排,点击图片后能看大图,并且能触摸放大,双击放大,触摸缩小,多张图片的话还可以滑动切换,长按图片还可以保存到本地等操作,然后就开始按着需求设计功能,由于网上也有很多类似demo,简直满坑满谷,所以就不在介绍各种原理及实现方法,功能很简单,代码也很easy,主要就是依赖photoView开源代码完成,各位看官就将就一下吧:
- 1.怎样展示大图
- 2.自定义imageview
- 3.多张图片滑动
- 4.长按保存,取消


1.首先点击图片后要展示当前所点击的图片大图,用什么承载这张图片呢,这里我用的是dialog,下面po出代码,注释很详细,放心阅读:

/**
  * 点击图片后,调用该展示大图方法
  * @param mPosition
  */
public void showPictureDialog(final int mPosition) {
    //创建dialog
    mDialog = new Dialog(this, R.style.PictureDialog);
    final Window window1 = mDialog.getWindow() ;
    WindowManager m = getWindowManager();
    Display d = m.getDefaultDisplay(); // 获取屏幕宽、高用
    WindowManager.LayoutParams p = window1.getAttributes(); // 获取对话框当前的参数值
    p.height = (int) (d.getHeight() * 1.0); // 改变的是dialog框在屏幕中的位置而不是大小
    p.width = (int) (d.getWidth() * 1.0); // 宽度设置为屏幕
    window1.setAttributes(p);
    View inflate = View.inflate(QuestionDetailsActivity.this, R.layout.picture_dialog, null);//该layout在后面po出
    int screenWidth = getResources().getDisplayMetrics().widthPixels;
    ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(screenWidth, ViewGroup.LayoutParams.MATCH_PARENT);
    mDialog.setContentView(inflate, layoutParams);
    pager = (ViewPagerFixed) inflate.findViewById(R.id.gallery01);
    pager.setOnPageChangeListener(pageChangeListener);
    PicturePageAdapter adapter = new PicturePageAdapter((ArrayList<String>) mListPicPath, this);
    pager.setAdapter(adapter);
    pager.setPageMargin(0);
    pager.setCurrentItem(mPosition);        window1.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
    mDialog.setOnKeyListener(new DialogOnKeyListener());
    mDialog.show();
    adapter.setOnPictureClickListener(new PicturePageAdapter.OnPictureClickListener() {
        @Override
        public void OnClick() {                window1.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            mDialog.dismiss();
        }
    });
    //长按图片保存
    adapter.setOnPictureLongClickListener(new PicturePageAdapter.OnPictureLongClickListener() {
        @Override
        public void OnLongClick() {
            //展示保存取消dialog
            showPicDialog();
        }
    });
}
//展示保存取消dialog
    private void showPicDialog() {
        homeWorkDialog = new SavePicDialog(QuestionDetailsActivity.this);
        homeWorkDialog.setOnClickListener(new SavePicDialog.onClickListener() {
            @Override
            public void onConfirm() {
                //启动图片下载线程
                if (pager != null){
                    onDownLoad(mListPicPath.get(pager.getCurrentItem()));
                }
              Toast.makeText(QuestionDetailsActivity.this,"保存成功!",Toast.LENGTH_SHORT).show();
                homeWorkDialog.dismiss();
            }
            @Override
            public void onCancle() {
                homeWorkDialog.dismiss();
            }
        });
        Window dialogWindow = homeWorkDialog.getWindow();
        dialogWindow.setGravity( Gravity.BOTTOM);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        lp.y = 0;
        dialogWindow.setAttributes(lp);
        homeWorkDialog.show();
    }
//上面style
<style name="PictureDialog" parent="android:style/Theme.Translucent.NoTitleBar.Fullscreen">
        <item name="android:background">#00000000</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
    </style>

//上面picture_dialog布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.XXX.ViewPagerFixed
      android:id="@+id/gallery01" 
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    </com.XXX.ViewPagerFixed>
</RelativeLayout>
/**
 * Created by ml on 17/6/30.
 */

public class PicturePageAdapter extends PagerAdapter {
    private ArrayList<String> mListUrls;
    private SparseArray<View> mViews = new SparseArray<>();
    private Context mContext;
    private int size;
    private OnPictureClickListener mOnPictureClickListener;
    private OnPictureLongClickListener mOnPictureLongClickListener;

    public PicturePageAdapter(ArrayList<String> listUrls, Context context) {
        mContext = context;
        mListUrls = listUrls;
        size = mListUrls == null ? 0 : mListUrls.size();
    }

    public SparseArray<View> getData(){
        return this.mViews;
    }

    public int getCount() {
        return size;
    }

    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    public void destroyItem(ViewGroup arg0, int arg1, Object arg2) {
        arg0.removeView(mViews.get(arg1));
    }

    public void finishUpdate(View arg0) {
    }

    public Object instantiateItem(ViewGroup arg0, int arg1) {
        View view = mViews.get(arg1);
        if(view == null){
            //引入photoView
            PhotoView img = new PhotoView(mContext);
            try {
                img.setBackgroundColor(0xff000000);
                //Glide需要自己去引入了
                Glide
                        .with(mContext)
                        .load(mListUrls.get(arg1))
                        .into(img);

                img.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                img.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
                    @Override
                    public void onPhotoTap(View view, float x, float y) {
                        if (mOnPictureClickListener != null) {
                            mOnPictureClickListener.OnClick();
                        }
                    }
                });
                //设置长按图片监听
                img.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        if (mOnPictureLongClickListener != null) {
                            mOnPictureLongClickListener.OnLongClick();
                        }
                        return false;
                    }
                });
                mViews.put(arg1,img);
                view = img;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        ((ViewPagerFixed) arg0).addView(view);

        return view;
    }

    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }

    /**
     * 图片监听接口
     */
    public interface OnPictureClickListener{
        void OnClick();
    }

    /**
     * 设置图片监听
     * @param onPictureClickListener
     */
    public void setOnPictureClickListener(OnPictureClickListener onPictureClickListener){
        mOnPictureClickListener = onPictureClickListener;
    }

    /**
     * 长按图片监听接口
     */
    public interface OnPictureLongClickListener{
        void OnLongClick();
    }

    /**
     * 设置长按图片监听
     * @param onPictureLongClickListener
     */
    public void setOnPictureLongClickListener(OnPictureLongClickListener onPictureLongClickListener){
        mOnPictureLongClickListener = onPictureLongClickListener;
    }
}
//自定义viewpager类
public class ViewPagerFixed extends android.support.v4.view.ViewPager {
public ViewPagerFixed(Context context) {super(context);}
public ViewPagerFixed(Context context, AttributeSet attrs) {super(context, attrs);}
@Override
    public boolean onTouchEvent(MotionEvent ev) {
        try {
            return super.onTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }
@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        try {
            return super.onInterceptTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }
}
希望大家静下心来整理,也给自己增加理解,或者发现不好的地方,指出来,咱们一起进步,完善

好了,这样就结束了,谢谢大家浏览使用,也欢迎提出问题,一起进步!

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
实现双指滑动图片放大缩小,单指滑动图片移动,双击图片放大,再一次双击图片复原的效果,可以通过以下步骤实现: 1. 在布局文件中添加一个 ImageView,设置其初识状态为居中显示一张图片。 2. 在代码中获取该 ImageView,并设置其可缩放、可拖动。 3. 通过 GestureDetector 监听用户手势操作,判断用户是单指还是双指操作,并做出相应的处理。 4. 对于双指操作,可以通过 ScaleGestureDetector 监听缩放比例的变化,从而实现图片放大缩小。 5. 对于单指操作,可以通过手势监听器中的 onTouchEvent 方法来处理图片的移动。 6. 对于双击操作,可以通过 GestureDetector 中的 onDoubleTap 方法来实现图片放大和复原。 以下是一个简单的实现代码示例: ``` public class MainActivity extends AppCompatActivity { private ImageView mImageView; private float mScaleFactor = 1.0f; private float mLastTouchX, mLastTouchY; private int mActivePointerId = -1; private ScaleGestureDetector mScaleGestureDetector; private GestureDetector mGestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView = findViewById(R.id.imageView); mScaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener()); mGestureDetector = new GestureDetector(this, new GestureListener()); // 设置图片缩放、可拖动 mImageView.setScaleType(ImageView.ScaleType.MATRIX); mImageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mScaleGestureDetector.onTouchEvent(event); mGestureDetector.onTouchEvent(event); final int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = event.getX(); final float y = event.getY(); mLastTouchX = x; mLastTouchY = y; mActivePointerId = event.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = event.findPointerIndex(mActivePointerId); final float x = event.getX(pointerIndex); final float y = event.getY(pointerIndex); if (!mScaleGestureDetector.isInProgress()) { final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mImageView.postTranslate(dx, dy); } mLastTouchX = x; mLastTouchY = y; break; } case MotionEvent.ACTION_UP: { mActivePointerId = -1; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = -1; break; } case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = event.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = event.getX(newPointerIndex); mLastTouchY = event.getY(newPointerIndex); mActivePointerId = event.getPointerId(newPointerIndex); } break; } } mImageView.invalidate(); return true; } }); } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); mImageView.setScaleX(mScaleFactor); mImageView.setScaleY(mScaleFactor); return true; } } private class GestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { if (mScaleFactor == 1.0f) { mScaleFactor = 2.0f; } else { mScaleFactor = 1.0f; } mImageView.setScaleX(mScaleFactor); mImageView.setScaleY(mScaleFactor); return true; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值