美文网首页我爱编程
安卓用户更换头像配合PopupWindow底部弹出选择

安卓用户更换头像配合PopupWindow底部弹出选择

作者: wcdd | 来源:发表于2018-07-26 13:17 被阅读0次

    简单记录,代码可直接用为网上搜集整理

    效果图.gif

    定义变量

        private final int LOCAL = 1;
        private final int CAMERA = 2;
        private final int CUT = 3;
        public static final String IMAGE_FILE_NAME = "clip_temp.jpg";
        public static final String RESULT_PATH = "result_path";
        public static final String PASS_PATH = "pass_path";
    

    PopupWindow代码,在需要用到的地方调用showUpPop()方法即可,没有进行封装有需要的可自行封装

    public void showUpPop() {
            if (popupWindow == null) {
                popupView = View.inflate(this, R.layout.popwindow_avatar, null);
                // 参数2,3:指明popupwindow的宽度和高度
                popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT,
                        WindowManager.LayoutParams.WRAP_CONTENT);
    
                popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
                    @Override
                    public void onDismiss() {
                        //隐藏遮罩
                        v_mask.setVisibility(View.GONE);
                    }
                });
    
                // 设置背景图片, 必须设置,不然动画没作用
                popupWindow.setBackgroundDrawable(new BitmapDrawable());
                popupWindow.setFocusable(true);
                // 设置点击popupwindow外屏幕其它地方消失
                popupWindow.setOutsideTouchable(true);
                // 平移动画相对于手机屏幕的底部开始,X轴不变,Y轴从1变0
                animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0,
                        Animation.RELATIVE_TO_PARENT, 1, Animation.RELATIVE_TO_PARENT, 0);
                animation.setInterpolator(new AccelerateInterpolator());
                animation.setDuration(200);
            }
    
            //设置按钮点击监听
            popupView.findViewById(R.id.close_popup).setOnClickListener(this);
            popupView.findViewById(R.id.open_photos).setOnClickListener(this);
            popupView.findViewById(R.id.open_camera).setOnClickListener(this);
    
            // 设置popupWindow的显示位置,此处是在手机屏幕底部且水平居中的位置
            popupWindow.showAtLocation(ModifyInfoActivity.this.findViewById(R.id.mo_info_layout), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
            popupView.startAnimation(animation);
            //显示遮罩
            v_mask.setVisibility(View.VISIBLE);
        }
    

    PopupWindow按钮被点击执行打开相册或拍照的操作

    switch (view.getId()){
                case R.id.mo_avatar:
                case R.id.add_avatar:
                    showUpPop();//调用PopupWindow
                    break;
                case R.id.close_popup:
                    //关闭popup
                    popupWindow.dismiss();
                    break;
                case R.id.open_photos: //打开相册操作
                    Intent intentFromGallery;
                    if (android.os.Build.VERSION.SDK_INT >= 19) { // 判断是不是4.4
                        intentFromGallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    } else {
                        intentFromGallery = new Intent(Intent.ACTION_GET_CONTENT);
                    }
                    intentFromGallery.setType("image/*"); // 设置文件类型
                    startActivityForResult(intentFromGallery,LOCAL);
                    // 在点击之后设置pop的销毁
                    if (popupWindow.isShowing()) {
                        popupWindow.dismiss();
                    }
                    break;
                case R.id.open_camera://打开相机操作
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getFile()));
                    startActivityForResult(intent, CAMERA);
                    // 在点击之后设置pop的销毁
                    if (popupWindow.isShowing()) {
                        popupWindow.dismiss();
                    }
                    break;
            }
    

    getFile()方法代码

    /**
         * 获取file的时候如果没有路径就重新创建
         * @return
         */
        private File getFile() {
            File file = new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME);
            if (!file.exists()) {
                file.getParentFile().mkdirs();
            }
            return file;
        }
    

    设置回调,接收处理好的图片数据

    //回调数据处理
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode != RESULT_OK) {
                return;
            }
    
            switch (requestCode) {
                case CUT:
                    String path = data.getStringExtra(RESULT_PATH);
                    Bitmap photo = BitmapFactory.decodeFile(path);
                    add_avatar.setImageBitmap(photo);
                    //在此处来做图片的上传处理
    
                    break;
                case LOCAL:
                    startCropImageActivity(getFilePath(data.getData()));
                    break;
                case CAMERA:
                    // 照相机程序返回的,再次调用图片剪辑程序去修剪图片
                    startCropImageActivity(Environment.getExternalStorageDirectory()+ "/" + IMAGE_FILE_NAME);
                    break;
            }
        }
    

    用到的方法

    private void startCropImageActivity(String path){
            Intent intent = new Intent(ModifyInfoActivity.this, ClipImageActivity.class);
            intent.putExtra(PASS_PATH, path);
            startActivityForResult(intent, CUT);
        }
    
        /**
         * 通过uri获取文件路径
         *
         * @param mUri
         * @return
         */
        public String getFilePath(Uri mUri) {
            try {
                if (mUri.getScheme().equals("file")) {
                    return mUri.getPath();
                } else {
                    return getFilePathByUri(mUri);
                }
            } catch (FileNotFoundException ex) {
                return null;
            }
        }
    
        // 获取文件路径通过url
        private String getFilePathByUri(Uri mUri) throws FileNotFoundException {
            @SuppressLint("Recycle") Cursor cursor = getContentResolver() .query(mUri, null, null, null, null);
            assert cursor != null;
            cursor.moveToFirst();
            return cursor.getString(1);
        }
    

    ClipImageActivity.java

    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.media.ExifInterface;
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    
    import com.tangzhuozhuan.mz.R;
    import com.tangzhuozhuan.mz.clippings.ClipImageLayout;
    import com.tangzhuozhuan.mz.view.MyToolBar;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    
    /**
     * 裁剪头像图片的Activity
     *@author lichun
     */
    public class ClipImageActivity extends AppCompatActivity{
        private ClipImageLayout mClipImageLayout = null;
        private Button complete;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_clip_image);
    
            MyToolBar my_tool = (MyToolBar) findViewById(R.id.my_tool);
            my_tool.setOnTitleClickListener(new MyToolBar.TitleOnClickListener() {
                @Override
                public void onBackClick() {
                    finish();
                }
            });
    
            complete = (Button) findViewById(R.id.complete);
    
            complete.setOnClickListener(listener);
            mClipImageLayout = (ClipImageLayout) findViewById(R.id.clipImageLayout);
            String path = getIntent().getStringExtra(ModifyInfoActivity.PASS_PATH);
            // 有的系统返回的图片是旋转了,有的没有旋转,所以处理
            int degreee = readBitmapDegree(path);
            Bitmap bitmap = createBitmap(path);
            if (bitmap != null) {
                if (degreee == 0) {
                    mClipImageLayout.setImageBitmap(bitmap);
                } else {
                    mClipImageLayout.setImageBitmap(rotateBitmap(degreee, bitmap));
                }
            } else {
                finish();
            }
        }
    
        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (v.getId()==R.id.complete){
                    Bitmap bitmap = mClipImageLayout.clip();
    
                    String path = Environment.getExternalStorageDirectory() + File.separator+ ModifyInfoActivity.IMAGE_FILE_NAME;
                    saveBitmap(bitmap, path);
    
                    Intent intent = new Intent();
                    intent.putExtra(ModifyInfoActivity.RESULT_PATH, path);
                    setResult(RESULT_OK, intent);
    
                    finish();
                }
            }
        };
    
    
        private void saveBitmap(Bitmap bitmap, String path) {
            File f = new File(path);
            if (f.exists()) {
                f.delete();
            }
    
            FileOutputStream fOut = null;
            try {
                f.createNewFile();
                fOut = new FileOutputStream(f);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                fOut.flush();
            } catch (IOException e1) {
                e1.printStackTrace();
            } finally {
                try {
                    if (fOut != null)
                        fOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        /**
         * 创建图片
         *
         * @param path
         * @return
         */
        private Bitmap createBitmap(String path) {
            if (path == null) {
                return null;
            }
    
            BitmapFactory.Options opts = new BitmapFactory.Options();
            //不在内存中读取图片的宽高
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, opts);
            int width = opts.outWidth;
    
            opts.inSampleSize = width > 1080 ? (int)(width / 1080) : 1 ;//注意此处为了解决1080p手机拍摄图片过大所以做了一定压缩,否则bitmap会不显示
    
            opts.inJustDecodeBounds = false;// 这里一定要将其设置回false,因为之前我们将其设置成了true
            opts.inPurgeable = true;
            opts.inInputShareable = true;
            opts.inDither = false;
            opts.inPurgeable = true;
            FileInputStream is = null;
            Bitmap bitmap = null;
            try {
                is = new FileInputStream(path);
                bitmap = BitmapFactory.decodeFileDescriptor(is.getFD(), null, opts);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (is != null) {
                        is.close();
                        is = null;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return bitmap;
        }
    
        // 读取图像的旋转度
        private int readBitmapDegree(String path) {
            int degree = 0;
            try {
                ExifInterface exifInterface = new ExifInterface(path);
                int orientation = exifInterface.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return degree;
        }
    
        // 旋转图片
        private Bitmap rotateBitmap(int angle, Bitmap bitmap) {
            // 旋转图片 动作
            Matrix matrix = new Matrix();
            matrix.postRotate(angle);
            // 创建新的图片
            Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                    bitmap.getWidth(), bitmap.getHeight(), matrix, false);
            return resizedBitmap;
        }
    
    }
    

    ClipImageBorderView.java

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Style;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.View;
    
    /**
     * @author lichun
     */
    public class ClipImageBorderView extends View {
        /**
         * 水平方向与View的边距
         */
        private int mHorizontalPadding;
        /**
         * 垂直方向与View的边距
         */
        private int mVerticalPadding;
        /**
         * 绘制的矩形的宽度
         */
        private int mWidth;
        /**
         * 边框的颜色,默认为白色
         */
        private int mBorderColor = Color.parseColor("#4D4D4D");
        /**
         * 边框的宽度单位dp
         */
        private int mBorderWidth = 1;
    
        private Paint mPaint;
    
        public ClipImageBorderView(Context context) {
            this(context, null);
        }
    
        public ClipImageBorderView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public ClipImageBorderView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
    
            mBorderWidth = (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, mBorderWidth, getResources()
                            .getDisplayMetrics());
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            // 计算矩形区域的宽度
            mWidth = getWidth() - 2 * mHorizontalPadding;
            // 计算距离屏幕垂直边界 的边距
            mVerticalPadding = (getHeight() - mWidth) / 2;
            mPaint.setColor(Color.parseColor("#aa000000"));
            mPaint.setStyle(Style.FILL);
            // 绘制左边1
            canvas.drawRect(0, 0, mHorizontalPadding, getHeight(), mPaint);
            // 绘制右边2
            canvas.drawRect(getWidth() - mHorizontalPadding, 0, getWidth(),
                    getHeight(), mPaint);
            // 绘制上边3
            canvas.drawRect(mHorizontalPadding, 0, getWidth() - mHorizontalPadding,
                    mVerticalPadding, mPaint);
            // 绘制下边4
            canvas.drawRect(mHorizontalPadding, getHeight() - mVerticalPadding,
                    getWidth() - mHorizontalPadding, getHeight(), mPaint);
            // 绘制外边�?
            mPaint.setColor(mBorderColor);
            mPaint.setStrokeWidth(mBorderWidth);
            mPaint.setStyle(Style.STROKE);
            canvas.drawRect(mHorizontalPadding, mVerticalPadding, getWidth()
                    - mHorizontalPadding, getHeight() - mVerticalPadding, mPaint);
    
        }
    
        public void setHorizontalPadding(int mHorizontalPadding) {
            this.mHorizontalPadding = mHorizontalPadding;
        }
    }
    

    ClipImageLayout.java

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.widget.RelativeLayout;
    
    /**
     * @author lichun 2018/7/26
     */
    public class ClipImageLayout extends RelativeLayout {
        private ClipZoomImageView mZoomImageView;
        private ClipImageBorderView mClipImageView;
        private int mHorizontalPadding = 20;// 框左右的边距,这里左右边距为0,为屏幕宽度的正方形
    
        public ClipImageLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            mZoomImageView = new ClipZoomImageView(context);
            mClipImageView = new ClipImageBorderView(context);
    
            android.view.ViewGroup.LayoutParams lp = new LayoutParams(
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT);
    
            this.addView(mZoomImageView, lp);
            this.addView(mClipImageView, lp);
    
            // 计算padding的px
            mHorizontalPadding = (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, mHorizontalPadding, getResources()
                            .getDisplayMetrics());
            mZoomImageView.setHorizontalPadding(mHorizontalPadding);
            mClipImageView.setHorizontalPadding(mHorizontalPadding);
        }
    
        public void setImageDrawable(Drawable drawable) {
            mZoomImageView.setImageDrawable(drawable);
        }
    
        public void setImageBitmap(Bitmap bitmap) {
            mZoomImageView.setImageBitmap(bitmap);
        }
    
        /**
         * 对外公布设置边距的单位为dp
         *
         * @param mHorizontalPadding
         */
        public void setHorizontalPadding(int mHorizontalPadding) {
            this.mHorizontalPadding = mHorizontalPadding;
        }
    
        /**
         * 裁切图片
         *
         * @return
         */
        public Bitmap clip() {
            return mZoomImageView.clip();
        }
    }
    

    ClipZoomImageView.java

    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.RectF;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.GestureDetector;
    import android.view.GestureDetector.SimpleOnGestureListener;
    import android.view.MotionEvent;
    import android.view.ScaleGestureDetector;
    import android.view.ScaleGestureDetector.OnScaleGestureListener;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.ViewTreeObserver;
    import android.widget.ImageView;
    
    import java.io.ByteArrayOutputStream;
    
    /**
     * 缩放图片的View
     * @author lichun
     */
    @SuppressLint("AppCompatCustomView")
    public class ClipZoomImageView extends ImageView implements
            OnScaleGestureListener, OnTouchListener,
            ViewTreeObserver.OnGlobalLayoutListener {
        public static float SCALE_MAX = 4.0f;
        private static float SCALE_MID = 2.0f;
    
        /**
         * 初始化时的缩放比例,如果图片宽或高大于屏幕,此�?将小�?
         */
        private float initScale = 1.0f;
        private boolean once = true;
    
        /**
         * 用于存放矩阵
         */
        private final float[] matrixValues = new float[9];
    
        /**
         * 缩放的手势检�?
         */
        private ScaleGestureDetector mScaleGestureDetector = null;
        private final Matrix mScaleMatrix = new Matrix();
    
        /**
         * 用于双击�?��
         */
        private GestureDetector mGestureDetector;
        private boolean isAutoScale;
    
        private int mTouchSlop;
    
        private float mLastX;
        private float mLastY;
    
        private boolean isCanDrag;
        private int lastPointerCount;
        /**
         * 水平方向与View的边
         */
        private int mHorizontalPadding;
    
        public ClipZoomImageView(Context context) {
            this(context, null);
        }
    
        public ClipZoomImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            setScaleType(ScaleType.MATRIX);
            mGestureDetector = new GestureDetector(context,
                    new SimpleOnGestureListener() {
                        @Override
                        public boolean onDoubleTap(MotionEvent e) {
                            if (isAutoScale == true)
                                return true;
    
                            float x = e.getX();
                            float y = e.getY();
                            if (getScale() < SCALE_MID) {
                                ClipZoomImageView.this.postDelayed(
                                        new AutoScaleRunnable(SCALE_MID, x, y), 16);
                                isAutoScale = true;
                            } else {
                                ClipZoomImageView.this.postDelayed(
                                        new AutoScaleRunnable(initScale, x, y), 16);
                                isAutoScale = true;
                            }
    
                            return true;
                        }
                    });
            mScaleGestureDetector = new ScaleGestureDetector(context, this);
            this.setOnTouchListener(this);
        }
    
        /**
         * 自动缩放的任�?
         *
         */
        private class AutoScaleRunnable implements Runnable {
            static final float BIGGER = 1.07f;
            static final float SMALLER = 0.93f;
            private float mTargetScale;
            private float tmpScale;
    
            /**
             * 缩放的中�?
             */
            private float x;
            private float y;
    
            /**
             * 传入目标缩放值,根据目标值与当前值,判断应该放大还是缩小
             *
             * @param targetScale
             */
            public AutoScaleRunnable(float targetScale, float x, float y) {
                this.mTargetScale = targetScale;
                this.x = x;
                this.y = y;
                if (getScale() < mTargetScale) {
                    tmpScale = BIGGER;
                } else {
                    tmpScale = SMALLER;
                }
    
            }
    
            @Override
            public void run() {
                // 进行缩放
                mScaleMatrix.postScale(tmpScale, tmpScale, x, y);
                checkBorder();
                setImageMatrix(mScaleMatrix);
    
                final float currentScale = getScale();
                // 如果值在合法范围内,继续缩放
                if (((tmpScale > 1f) && (currentScale < mTargetScale))
                        || ((tmpScale < 1f) && (mTargetScale < currentScale))) {
                    ClipZoomImageView.this.postDelayed(this, 16);
                } else
                // 设置为目标的缩放比例
                {
                    final float deltaScale = mTargetScale / currentScale;
                    mScaleMatrix.postScale(deltaScale, deltaScale, x, y);
                    checkBorder();
                    setImageMatrix(mScaleMatrix);
                    isAutoScale = false;
                }
    
            }
        }
    
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float scale = getScale();
            float scaleFactor = detector.getScaleFactor();
    
            if (getDrawable() == null)
                return true;
    
            /**
             * 缩放的范围控�?
             */
            if ((scale < SCALE_MAX && scaleFactor > 1.0f)
                    || (scale > initScale && scaleFactor < 1.0f)) {
                /**
                 * �?��值最小�?判断
                 */
                if (scaleFactor * scale < initScale) {
                    scaleFactor = initScale / scale;
                }
                if (scaleFactor * scale > SCALE_MAX) {
                    scaleFactor = SCALE_MAX / scale;
                }
                /**
                 * 设置缩放比例
                 */
                mScaleMatrix.postScale(scaleFactor, scaleFactor,
                        detector.getFocusX(), detector.getFocusY());
                checkBorder();
                setImageMatrix(mScaleMatrix);
            }
            return true;
        }
    
        /**
         * 根据当前图片的Matrix获得图片的范�?
         *
         * @return
         */
        private RectF getMatrixRectF() {
            Matrix matrix = mScaleMatrix;
            RectF rect = new RectF();
            Drawable d = getDrawable();
            if (null != d) {
                rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
                matrix.mapRect(rect);
            }
            return rect;
        }
    
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }
    
        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (mGestureDetector.onTouchEvent(event))
                return true;
            mScaleGestureDetector.onTouchEvent(event);
    
            float x = 0, y = 0;
            // 拿到触摸点的个数
            final int pointerCount = event.getPointerCount();
            // 得到多个触摸点的x与y均�?
            for (int i = 0; i < pointerCount; i++) {
                x += event.getX(i);
                y += event.getY(i);
            }
            x = x / pointerCount;
            y = y / pointerCount;
    
            /**
             * 每当触摸点发生变化时,重置mLasX , mLastY
             */
            if (pointerCount != lastPointerCount) {
                isCanDrag = false;
                mLastX = x;
                mLastY = y;
            }
    
            lastPointerCount = pointerCount;
            switch (event.getAction()) {
                case MotionEvent.ACTION_MOVE:
                    float dx = x - mLastX;
                    float dy = y - mLastY;
    
                    if (!isCanDrag) {
                        isCanDrag = isCanDrag(dx, dy);
                    }
                    if (isCanDrag) {
                        if (getDrawable() != null) {
    
                            RectF rectF = getMatrixRectF();
                            // 如果宽度小于屏幕宽度,则禁止左右移动
                            if (rectF.width() <= getWidth() - mHorizontalPadding * 2) {
                                dx = 0;
                            }
    
                            // 如果高度小雨屏幕高度,则禁止上下移动
                            if (rectF.height() <= getHeight() - getHVerticalPadding()
                                    * 2) {
                                dy = 0;
                            }
                            mScaleMatrix.postTranslate(dx, dy);
                            checkBorder();
                            setImageMatrix(mScaleMatrix);
                        }
                    }
                    mLastX = x;
                    mLastY = y;
                    break;
    
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    lastPointerCount = 0;
                    break;
            }
    
            return true;
        }
    
        /**
         * 获得当前的缩放比�?
         *
         * @return
         */
        public final float getScale() {
            mScaleMatrix.getValues(matrixValues);
            return matrixValues[Matrix.MSCALE_X];
        }
    
        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            getViewTreeObserver().addOnGlobalLayoutListener(this);
        }
    
        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    
        /**
         * 垂直方向与View的边�?
         */
        // private int getHVerticalPadding();
    
        @Override
        public void onGlobalLayout() {
            if (once) {
                Drawable d = getDrawable();
                if (d == null)
                    return;
                // 垂直方向的边�?
                // getHVerticalPadding() = (getHeight() - (getWidth() - 2 *
                // mHorizontalPadding)) / 2;
    
                int width = getWidth();
                int height = getHeight();
                // 拿到图片的宽和高
                int drawableW = d.getIntrinsicWidth();
                int drawableH = d.getIntrinsicHeight();
                float scale = 1.0f;
    
                int frameSize = getWidth() - mHorizontalPadding * 2;
    
                // 大图
                if (drawableW > frameSize && drawableH < frameSize) {
                    scale = 1.0f * frameSize / drawableH;
                } else if (drawableH > frameSize && drawableW < frameSize) {
                    scale = 1.0f * frameSize / drawableW;
                } else if (drawableW > frameSize && drawableH > frameSize) {
                    float scaleW = frameSize * 1.0f / drawableW;
                    float scaleH = frameSize * 1.0f / drawableH;
                    scale = Math.max(scaleW, scaleH);
                }
    
                // 太小的图片放大处�?
                if (drawableW < frameSize && drawableH > frameSize) {
                    scale = 1.0f * frameSize / drawableW;
                } else if (drawableH < frameSize && drawableW > frameSize) {
                    scale = 1.0f * frameSize / drawableH;
                } else if (drawableW < frameSize && drawableH < frameSize) {
                    float scaleW = 1.0f * frameSize / drawableW;
                    float scaleH = 1.0f * frameSize / drawableH;
                    scale = Math.max(scaleW, scaleH);
                }
    
                initScale = scale;
                SCALE_MID = initScale * 2;
                SCALE_MAX = initScale * 4;
                mScaleMatrix.postTranslate((width - drawableW) / 2,
                        (height - drawableH) / 2);
                mScaleMatrix.postScale(scale, scale, getWidth() / 2,
                        getHeight() / 2);
    
                // 图片移动至屏幕中�?
                setImageMatrix(mScaleMatrix);
                once = false;
            }
        }
    
        /**
         * 剪切图片,返回剪切后的bitmap对象
         *
         * @return
         */
        public Bitmap clip() {
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),Bitmap.Config.ARGB_8888);
            //将剪裁的图片压缩到500k以下,如果没需求就注释该段代码
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int options = 100;//保存的图片自动压缩低于500k
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
            while (baos.toByteArray().length / 1024 > 500) {
                baos.reset();
                options -= 10;
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
            }
    
            Canvas canvas = new Canvas(bitmap);
            draw(canvas);
            return Bitmap.createBitmap(bitmap, mHorizontalPadding,
                    getHVerticalPadding(), getWidth() - 2 * mHorizontalPadding,
                    getWidth() - 2 * mHorizontalPadding);
        }
    
        /**
         * 边界�?��
         */
        private void checkBorder() {
            RectF rect = getMatrixRectF();
            float deltaX = 0;
            float deltaY = 0;
    
            int width = getWidth();
            int height = getHeight();
    
            // 如果宽或高大于屏幕,则控制范�?; 这里�?.001是因为精度丢失会产生问题,但是误差一般很小,�?��我们直接加了�?��0.01
            if (rect.width() + 0.01 >= width - 2 * mHorizontalPadding) {
                if (rect.left > mHorizontalPadding) {
                    deltaX = -rect.left + mHorizontalPadding;
                }
    
                if (rect.right < width - mHorizontalPadding) {
                    deltaX = width - mHorizontalPadding - rect.right;
                }
            }
    
            if (rect.height() + 0.01 >= height - 2 * getHVerticalPadding()) {
                if (rect.top > getHVerticalPadding()) {
                    deltaY = -rect.top + getHVerticalPadding();
                }
    
                if (rect.bottom < height - getHVerticalPadding()) {
                    deltaY = height - getHVerticalPadding() - rect.bottom;
                }
            }
    
            mScaleMatrix.postTranslate(deltaX, deltaY);
        }
    
        /**
         * 是否是拖动行�?
         *
         * @param dx
         * @param dy
         * @return
         */
        private boolean isCanDrag(float dx, float dy) {
            return Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
        }
    
        public void setHorizontalPadding(int mHorizontalPadding) {
            this.mHorizontalPadding = mHorizontalPadding;
        }
    
        private int getHVerticalPadding() {
            return (getHeight() - (getWidth() - 2 * mHorizontalPadding)) / 2;
        }
    }
    

    相关文章

      网友评论

        本文标题:安卓用户更换头像配合PopupWindow底部弹出选择

        本文链接:https://www.haomeiwen.com/subject/djqbmftx.html