精华内容
下载资源
问答
  • html图片加载不出来

    2021-01-20 19:27:13
    <p>html为什么我这个图片加载不出来? 是因为我用的记事本吗?其他语法是没有问题的。 <p><img alt="" height="101" src="https://img-ask.csdnimg.cn/upload/1611141881405.jpg" width="287" /></p> ...
  • 为什么我的背景图片加载不出来

    千次阅读 2018-04-17 11:13:38
    曾经在html中编写网页的时候, 将外部的css样式表链接到网页中,其它像:background-color ....就可以显示了,但是我们非常提倡这种绝对路径的写法,那么出现这个现象的原因到底是什么呢? ** ...

    曾经在html中编写网页的时候, 将外部的css样式表链接到网页中,其它像:background-color . padding , margin 等都可以正常起作用,但就是background-image不起作用,而且有时一气之下将background-image:url(“”绝对路径“”) ;就可以显示了,但是我们非常不提倡这种绝对路径的写法,那么出现这个现象的原因到底是什么呢?
    **

    注意:在css样式表中写的background-image:url(图片的路径为相对本css文件的路径,而不是我们通常认为的相对加入css样式的网页的路径);

    **
    例如:在当前目录下有 index.html 和 css文件夹(里面包含:css.css) 和 images文件夹(里面包含top.jpg)
    **错误的认为和写法:**background-image:url(“images/top.jpg”); ———————————–>>错误的认为图片的路径应该是针对index.html网页来说的。
    **正确的认为和写法:**background-image:url(“../images/top.jpg”);———————————–>图片的路径应该写的是相对css.css文件的路径
    其中 ../ 表示的是上一级目录,不要写成 ./ 这是表示当前目录。
    这个问题困扰我很长时间,今天总结一下,提醒自己吧!!希望还没弄清的朋友弄懂!

    展开全文
  • DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset="UTF-8"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-...
  • 当窗口加载完毕 --%> window.onload = function (ev) { document.getElementById("img").onclick = function (ev1) { this.src = "./checkCodeServlet?time="+new Date().getTime(); } } ...
  • html中img标签为什么显示不出来

    万次阅读 2017-12-11 09:50:46
    html中img标签为什么显示不出来 此文针对的是动态图片加载时候的方法 有一次做项目后台取出图片名称,获取服务器根路径,拼接字符串发现图片无法加载出来 后上网找方法,解决办法是你这里需要的是http路径,而不是...

    此文针对的是动态图片加载时候的方法

    有一次做项目后台取出图片名称,获取服务器根路径,拼接字符串发现图片无法加载出来

    后上网找方法,解决办法是你这里需要的是http路径,而不是服务器根路径

    D:\mrchengprojects\chenThree\.metadata\.me_tcat\webapps\chenThree\upload\images   //这是服务器上的图片路径输入这个图片无法显示

    后通过javascript获取程序的http路径后图片显示正确

    http://localhost:8080/chenThree/upload/images/link.jpg

    通过javascript获取根路径带工程名请看另一篇博客

    点击打开链接

    展开全文
  • ![图片说明](https://img-ask.csdn.net/upload/202003/10/1583850627_983457.jpg) 这是项目结构 ...[图片说明]...这是运行结果,css加载不出来。希望大神帮忙
  • 比如在html代码中我们会使用img标签来插入图片,而加载图片需要时间,一旦图片过多过大,就需要用户等待很长时间才能将页面加载出来。因此我们可以用体积较小的占位图来代替暂时需要展示的图片,以此来减少加载...

    为什么要做性能优化?

    1、加快页面展示和运行速度(增强用户体验)
    2、节约服务器带宽流量
    3、减少服务器压力

    什么是按需加载

    按需加载是前端性能优化的一大措施。顾名思义,按需加载就是根据需要去加载资源。比如在html代码中我们会使用img标签来插入图片,而加载图片需要时间,一旦图片过多过大,就需要用户等待很长时间才能将页面加载出来。因此我们可以用体积较小的占位图来代替暂时不需要展示的图片,以此来减少加载时间。
    在这里插入图片描述在这里插入图片描述很明显占位图比正常图片小很多,这样就可以减少加载时间

    按需加载思路

    思路: 在鼠标滚动时,计算图片距浏览器顶部的距离, 再与页面可视区高度与滚动条滚动距离之和作比较, 如果大于,就说明还不需要被加载, 如果小于或等于就说明用户即将看到图片,这个时候就需要加载正常图片.

    document.documentElement.scrollTop || document.body.scrollTop用于获取滚动距离
    document.documentElement.clientHeight用于获取可视区高度
    imgs[i].offsetTop用于获取图片距浏览器顶部的距离

    代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        img{
          display: inline-block;
          width: 300px;
          height: 200px;
        }
      </style>
    </head>
    <body>
      <div>
        <ul id="test">
          <li> <img _src="1.jpg" src="2.png"></li>
          <li> <img _src="2.jpg" src="2.png"></li>
          <li> <img _src="3.jpg" src="2.png"></li>
          <li> <img _src="4.jpg" src="2.png"></li>
          <li> <img _src="5.jpg" src="2.png"></li>
          <li> <img _src="6.jpg" src="2.png"></li>
          <li> <img _src="7.jpg" src="2.png"></li>
          <li> <img _src="8.jpg" src="2.png"></li>
          <li> <img _src="9.jpg" src="2.png"></li>
          <li> <img _src="10.jpg" src="2.png"></li>
          <li> <img _src="11.jpg" src="2.png"></li>
          <li> <img _src="12.jpg" src="2.png"></li>
          <li> <img _src="13.jpg" src="2.png"></li>
          <li> <img _src="14.jpg" src="2.png"></li>
        </ul>
      </div>
      <script>
        var imgs = document.getElementsByTagName('img')
        window.onscroll = lazyload;		//防止刚加载完成,未触发滚动事件时,显示占位图
        window.onload  = lazyload
        function lazyload(){
          var iScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
          var clientHeight = document.documentElement.clientHeight;
          for(let i = 0;i<=imgs.length;i++){
            if(imgs[i].offsetTop<=iScrollTop+clientHeight){
              imgs[i].src = imgs[i].getAttribute('_src')
            }else{
              return
            }
          }
        }
      </script>
    </body>
    </html>
    

    我们将正常图片的加载路径存放在 _src中,当需要时将src中的内容替换为 _src中的正常路径

    在这里插入图片描述
    可以看到随着滚轮滚动,才开始加载后面的图片

    展开全文
  • 为什么发布这篇文章呢 上一篇也说过了 单纯的是想让刚进android的小白走那么多弯路,毕竟android迭代太快,我的进步还很小,感觉自己要被大时代淘汰,趁现在还没淘汰,努力帮一帮刚进这个行业的程序猿们,凑巧我也...

    老规矩先来诉诉苦,为什么发布这篇文章呢 上一篇也说过了 单纯的是不想让刚进android的小白走那么多弯路,毕竟android迭代太快,我的进步还很小,感觉自己要被大时代淘汰,趁现在还没淘汰,努力帮一帮刚进这个行业的程序猿们,凑巧我也有这个需求,就发出来了!
    不要觉得文章多 全部都是傻瓜式复制!!!
    我可以很负责人的告诉你们,市场需要的是资深人才,目前看来我们这一行小白居多,缺大佬,导致一些公司招工的时候 工资一压再压话不多说,加油吧看我文章的各位!!!
    没有运行时的效果 这个没办法 不能上传视频请谅解。

    WebView加载本地html

    private String html="<p>" +
                "<xmp style=\\\"font-size:20px;font-family: generic-font;white-space: normal;\\\">" +
                "\\t在Android应用程序中,如果组件的导出值在应用程序的清单文件中被明确标记为false,那么该组件将变为私有的。如果不指定组件的访问权限,那么,任何应用程序都可以访问该组件。</xmp></p><p><xmp style=" +
                "\\\"font-size:20px;font-family: generic-font;white-space: normal;\\\">" +
                "\\t只在应用程序内部使用的组件必须设置为非公开,以防受到其他应用程序的调用。若应用组件未设置exported属性:</xmp></p><p><xmp style=" +
                "\\\"font-size:20px;font-family: generic-font;white-space: normal;\\\">\\t若应用组件未设置<intent-filter>标签,exported属性默认值为false,否则默认值为true。" +
                "</xmp></p><p><xmp style=\\\"font-size:20px;font-family: generic-font;white-space: normal;\\\">" +
                "\\t因此,私有组件(不存在对外交互)应该在AndroidManifest.xml文件中显式设置该组件的android:exported属性值为false,否则,可能会对外暴露内部接口," +
                "若被恶意应用利用,则会造成组件信息泄露或发起拒绝服务攻击。</xmp></p><p><xmp style=\\\"font-size:20px;font-family: generic-font;white-space: normal;\\\">" +
                "\\t需要注意的是,私有组件如果声明了<intent-filter>标签,即使显式设置exported属性为false,也是存在组件信息泄露的风险。如图1-1所示,假设组件A-1是私有组件" +
                ",应用程序A的某一组件根据组件A-1声明的行为X给组件A-1发送消息;若恶意应用程序B定义了公开组件B-1,并声明了和组件A-1相同的行为X,当应用A通过行为X发送敏感信息给组件A-1时," +
                "会给用户弹出消息接收选择框,用户在不知情的情况下可能会选择组件B-1,导致恶意应用B接收到应用A发送的内部消息,造成信息泄露。" +"<img style='margin:10px' src='http://images.china-pub.com/ebook25001-30000/27518/zcover.jpg' width='100'/>"+"</xmp></p><p><xmp style=\\\"font-size:20px;font-family: generic-font;white-space: normal;\\\">";
    
    /*
    在这扩展一下WebView默认的是白色的如果跟背景不一样的话会很难看 这个是改变WebView的背景色
    如果单独设置一个的话不会起作用 还有最重要的一点就是 在WebView控件加上背景透明的属性 这样才可以生效。
     xml中加入android:background="@android:color/transparent"
    */
    mWebView.setBackgroundColor(0);//设置背景色
    mWebView.getBackground().setAlpha(0);
    /**
    如果是只加载html数据的话个人倾向用第二种 加载网址的话就需要第一种了
    当时我写这个的时候上网找了很多 第一个方法的话当时好像是图片或者表格加载不出来 
    然后我换了第二种加载的方式加载出来的。这个大家可以实验一下 我当时加载的时候确实碰到了这样的问题。
    */
    mWebView.loadData( html, "text/html", "utf-8");
    mWebView.loadDataWithBaseURL(null, html, "text/html", "utf-8", null)

    现在是拦截WebView中图片的点击事件

     mWebView.setWebViewClient(new WebViewClient() {
                            @Override
                            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                                return true;
                            }
                        });
                        //java回调js代码,不要忘了@JavascriptInterface这个注解,不然点击事件不起作用
                        mWebView.addJavascriptInterface(new JsCallJavaObj() {
                            @JavascriptInterface
                            @Override
                            public void showBigImg(String url) { //url是图片的url
                            /*这里我也没搞懂为什么加Handler 当时我写的时候 不加会崩溃掉
                            所以我在这里加上了handler 如果有的小伙伴加hanlder不行的话 那就去掉
                            我项目中很多地方都用到了这个东西 这有这一个地方加了,不加如果不报错的话那就不需要加*/
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        String imagePath;
                                        /**
                                        判断图片的url带不带http或者https
                                        如果获取的url没有http或者https
                                        就需要你自己使用自己的ip或者域名拼接上url
                                        ip就是你请求接口时最前面的一部分比如说172.22.222.189:80/
                                        域名也是你请求接口时最前面的一部分https:baidu.zxc/
                                        */
                                        if (url.contains("http")){
                                            imagePath = url;
                                        }else {
                                            imagePath = ip或者域名 + url;
                                        }
                                        //布局的话我会贴到最下面
                                        View inflate = getLayoutInflater().inflate(R.layout.range_click_image_dialog, null);
                                        //展示在dialog上面的大图PhotoView是自定义的手势放大缩小类
                                        PhotoView dialogImg = inflate.findViewById(R.id.range_click_img);
                                        Button xuanzhaun = inflate.findViewById(R.id.xuanzhuan);
                                        //ComponentDialog是我自定义的弹框
                                        mComponentDialog = new ComponentDialog(MainActivity.this, 0, 0, inflate, R.style.RangeFragment);
                                        Glide.with(dialogImg).load(imagePath).fitCenter().into(dialogImg);
                                        mComponentDialog.setCancelable(true);
                                        mComponentDialog.create();
                                        mComponentDialog.show();
                                        //自定义View放大缩小 自定义View唯一的方法 只要调用他就可以手势放大缩小===傻瓜式
                                        dialogImg.enable();
                                        dialogImg.setOnClickListener(new View.OnClickListener() {
                                            @Override
                                            public void onClick(View view) {
                                                mComponentDialog.cancel();
                                            }
                                        });
                                        //点击按钮进行旋转的数组 因为int类型不可以我用数组代替的
                                        final int[] rota = {90};
                                        xuanzhaun.setOnClickListener(new View.OnClickListener() {
                                            @Override
                                            public void onClick(View v) {
                                                dialogImg.setRotation(rota[0]);
                                                rota[0] += 90;
                                            }
                                        });
                                    }
                                });
                            }
                        },"jsCallJavaObj");
                        mWebView.setWebViewClient(new WebViewClient(){
                            @Override
                            public void onPageFinished(WebView view, String url) {
                                super.onPageFinished(view, url);
                                setWebImageClick(view);
                            }
                        });
    
    //截取webView图片点击
        private  void setWebImageClick(WebView view) {
            String jsCode="javascript:(function(){" +
                    "var imgs=document.getElementsByTagName(\"img\");" +
                    "for(var i=0;i<imgs.length;i++){" +
                    "imgs[i].οnclick=function(){" +
                    "window.jsCallJavaObj.showBigImg(this.src);" +
                    "}}})()";
            mWebView.loadUrl(jsCode);
        }
        //截取图片点击事件需要的回调接口
        private interface JsCallJavaObj{
            void showBigImg(String url);
        }
       
    
    //自定义弹框类
    public class ComponentDialog extends Dialog {
        public ComponentDialog(Context context, int width, int height, View layout, int style) {
    
            super(context, style);
    
            setContentView(layout);
    
            Window window = getWindow();
    
            WindowManager.LayoutParams params = window.getAttributes();
    
            params.gravity = Gravity.CENTER;
    
            window.setAttributes(params);
        }
    }
    
    //自定义手势缩放的类 看着有点多 直接傻瓜式复制 中途可能会爆红 这个时候你就要自己搞一下了 都不复杂
    @SuppressLint("AppCompatCustomView")
    public class PhotoView extends ImageView {
    
        private final static int MIN_ROTATE = 35;
        private final static int ANIMA_DURING = 340;
        private final static float MAX_SCALE = 2.5f;
    
        private int mMinRotate;
        private int mAnimaDuring;
        private float mMaxScale;
    
        private int MAX_OVER_SCROLL = 0;
        private int MAX_FLING_OVER_SCROLL = 0;
        private int MAX_OVER_RESISTANCE = 0;
        private int MAX_ANIM_FROM_WAITE = 500;
    
        private Matrix mBaseMatrix = new Matrix();
        private Matrix mAnimaMatrix = new Matrix();
        private Matrix mSynthesisMatrix = new Matrix();
        private Matrix mTmpMatrix = new Matrix();
    
        private RotateGestureDetector mRotateDetector;
        private GestureDetector mDetector;
        private ScaleGestureDetector mScaleDetector;
        private OnClickListener mClickListener;
    
        private ScaleType mScaleType;
    
        private boolean hasMultiTouch;
        private boolean hasDrawable;
        private boolean isKnowSize;
        private boolean hasOverTranslate;
        private boolean isEnable = false;
        private boolean isRotateEnable = false;
        private boolean isInit;
        private boolean mAdjustViewBounds;
        // 当前是否处于放大状态
        private boolean isZoonUp;
        private boolean canRotate;
    
        private boolean imgLargeWidth;
        private boolean imgLargeHeight;
    
        private float mRotateFlag;
        private float mDegrees;
        private float mScale = 1.0f;
        private int mTranslateX;
        private int mTranslateY;
    
        private float mHalfBaseRectWidth;
        private float mHalfBaseRectHeight;
    
        private RectF mWidgetRect = new RectF();
        private RectF mBaseRect = new RectF();
        private RectF mImgRect = new RectF();
        private RectF mTmpRect = new RectF();
        private RectF mCommonRect = new RectF();
    
        private PointF mScreenCenter = new PointF();
        private PointF mScaleCenter = new PointF();
        private PointF mRotateCenter = new PointF();
    
        private Transform mTranslate = new Transform();
    
        private RectF mClip;
        private Info mFromInfo;
        private long mInfoTime;
        private Runnable mCompleteCallBack;
    
        private OnLongClickListener mLongClick;
    
        public PhotoView(Context context) {
            super(context);
            init();
        }
    
        public PhotoView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public PhotoView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            super.setScaleType(ScaleType.MATRIX);
            if (mScaleType == null) mScaleType = ScaleType.CENTER_INSIDE;
            mRotateDetector = new RotateGestureDetector(mRotateListener);
            mDetector = new GestureDetector(getContext(), mGestureListener);
            mScaleDetector = new ScaleGestureDetector(getContext(), mScaleListener);
            float density = getResources().getDisplayMetrics().density;
            MAX_OVER_SCROLL = (int) (density * 30);
            MAX_FLING_OVER_SCROLL = (int) (density * 30);
            MAX_OVER_RESISTANCE = (int) (density * 140);
    
            mMinRotate = MIN_ROTATE;
            mAnimaDuring = ANIMA_DURING;
            mMaxScale = MAX_SCALE;
        }
    
        /**
         * 获取默认的动画持续时间
         */
        public int getDefaultAnimaDuring() {
            return ANIMA_DURING;
        }
    
        @Override
        public void setOnClickListener(OnClickListener l) {
            super.setOnClickListener(l);
            mClickListener = l;
        }
    
        @Override
        public void setScaleType(ScaleType scaleType) {
            if (scaleType == ScaleType.MATRIX) return;
    
            if (scaleType != mScaleType) {
                mScaleType = scaleType;
    
                if (isInit) {
                    initBase();
                }
            }
        }
    
        @Override
        public void setOnLongClickListener(OnLongClickListener l) {
            mLongClick = l;
        }
    
        /**
         * 设置动画的插入器
         */
        public void setInterpolator(DecelerateInterpolator interpolator) {
            mTranslate.setInterpolator(interpolator);
        }
    
        /**
         * 获取动画持续时间
         */
        public int getAnimaDuring() {
            return mAnimaDuring;
        }
    
        /**
         * 设置动画的持续时间
         */
        public void setAnimaDuring(int during) {
            mAnimaDuring = during;
        }
    
        /**
         * 设置最大可以缩放的倍数
         */
        public void setMaxScale(float maxScale) {
            mMaxScale = maxScale;
        }
    
        /**
         * 获取最大可以缩放的倍数
         */
        public float getMaxScale() {
            return mMaxScale;
        }
    
        /**
         * 启用缩放功能
         */
        public void enable() {
            isEnable = true;
        }
    
        /**
         * 禁用缩放功能
         */
        public void disenable() {
            isEnable = false;
        }
    
        /**
         * 启用旋转功能
         */
        public void enableRotate() {
            isRotateEnable = true;
        }
    
        /**
         * 禁用旋转功能
         */
        public void disableRotate() {
            isRotateEnable = false;
        }
    
        /**
         */
        public void setMaxAnimFromWaiteTime(int wait) {
            MAX_ANIM_FROM_WAITE = wait;
        }
    
        @Override
        public void setImageResource(int resId) {
            Drawable drawable = null;
            try {
                drawable = getResources().getDrawable(resId);
            } catch (Exception e) {
            }
    
            setImageDrawable(drawable);
        }
    
        @Override
        public void setImageDrawable(Drawable drawable) {
            super.setImageDrawable(drawable);
    
            if (drawable == null) {
                hasDrawable = false;
                return;
            }
    
            if (!hasSize(drawable))
                return;
    
            if (!hasDrawable) {
                hasDrawable = true;
            }
    
            initBase();
        }
    
        private boolean hasSize(Drawable d) {
            if ((d.getIntrinsicHeight() <= 0 || d.getIntrinsicWidth() <= 0)
                    && (d.getMinimumWidth() <= 0 || d.getMinimumHeight() <= 0)
                    && (d.getBounds().width() <= 0 || d.getBounds().height() <= 0)) {
                return false;
            }
            return true;
        }
    
        private static int getDrawableWidth(Drawable d) {
            int width = d.getIntrinsicWidth();
            if (width <= 0) width = d.getMinimumWidth();
            if (width <= 0) width = d.getBounds().width();
            return width;
        }
    
        private static int getDrawableHeight(Drawable d) {
            int height = d.getIntrinsicHeight();
            if (height <= 0) height = d.getMinimumHeight();
            if (height <= 0) height = d.getBounds().height();
            return height;
        }
    
        private void initBase() {
            if (!hasDrawable) return;
            if (!isKnowSize) return;
    
            mBaseMatrix.reset();
            mAnimaMatrix.reset();
    
            isZoonUp = false;
    
            Drawable img = getDrawable();
    
            int w = getWidth();
            int h = getHeight();
            int imgw = getDrawableWidth(img);
            int imgh = getDrawableHeight(img);
    
            mBaseRect.set(0, 0, imgw, imgh);
    
            // 以图片中心点居中位移
            int tx = (w - imgw) / 2;
            int ty = (h - imgh) / 2;
    
            float sx = 1;
            float sy = 1;
    
            // 缩放,默认不超过屏幕大小
            if (imgw > w) {
                sx = (float) w / imgw;
            }
    
            if (imgh > h) {
                sy = (float) h / imgh;
            }
    
            float scale = sx < sy ? sx : sy;
    
            mBaseMatrix.reset();
            mBaseMatrix.postTranslate(tx, ty);
            mBaseMatrix.postScale(scale, scale, mScreenCenter.x, mScreenCenter.y);
            mBaseMatrix.mapRect(mBaseRect);
    
            mHalfBaseRectWidth = mBaseRect.width() / 2;
            mHalfBaseRectHeight = mBaseRect.height() / 2;
    
            mScaleCenter.set(mScreenCenter);
            mRotateCenter.set(mScaleCenter);
    
            executeTranslate();
    
            switch (mScaleType) {
                case CENTER:
                    initCenter();
                    break;
                case CENTER_CROP:
                    initCenterCrop();
                    break;
                case CENTER_INSIDE:
                    initCenterInside();
                    break;
                case FIT_CENTER:
                    initFitCenter();
                    break;
                case FIT_START:
                    initFitStart();
                    break;
                case FIT_END:
                    initFitEnd();
                    break;
                case FIT_XY:
                    initFitXY();
                    break;
            }
    
            isInit = true;
    
            if (mFromInfo != null && System.currentTimeMillis() - mInfoTime < MAX_ANIM_FROM_WAITE) {
                animaFrom(mFromInfo);
            }
    
            mFromInfo = null;
        }
    
        private void initCenter() {
            if (!hasDrawable) return;
            if (!isKnowSize) return;
    
            Drawable img = getDrawable();
    
            int imgw = getDrawableWidth(img);
            int imgh = getDrawableHeight(img);
    
            if (imgw > mWidgetRect.width() || imgh > mWidgetRect.height()) {
                float scaleX = imgw / mImgRect.width();
                float scaleY = imgh / mImgRect.height();
    
                mScale = scaleX > scaleY ? scaleX : scaleY;
    
                mAnimaMatrix.postScale(mScale, mScale, mScreenCenter.x, mScreenCenter.y);
    
                executeTranslate();
    
                resetBase();
            }
        }
    
        private void initCenterCrop() {
            if (mImgRect.width() < mWidgetRect.width() || mImgRect.height() < mWidgetRect.height()) {
                float scaleX = mWidgetRect.width() / mImgRect.width();
                float scaleY = mWidgetRect.height() / mImgRect.height();
    
                mScale = scaleX > scaleY ? scaleX : scaleY;
    
                mAnimaMatrix.postScale(mScale, mScale, mScreenCenter.x, mScreenCenter.y);
    
                executeTranslate();
                resetBase();
            }
        }
    
        private void initCenterInside() {
            if (mImgRect.width() > mWidgetRect.width() || mImgRect.height() > mWidgetRect.height()) {
                float scaleX = mWidgetRect.width() / mImgRect.width();
                float scaleY = mWidgetRect.height() / mImgRect.height();
    
                mScale = scaleX < scaleY ? scaleX : scaleY;
    
                mAnimaMatrix.postScale(mScale, mScale, mScreenCenter.x, mScreenCenter.y);
    
                executeTranslate();
                resetBase();
            }
        }
    
        private void initFitCenter() {
            if (mImgRect.width() < mWidgetRect.width()) {
                mScale = mWidgetRect.width() / mImgRect.width();
    
                mAnimaMatrix.postScale(mScale, mScale, mScreenCenter.x, mScreenCenter.y);
    
                executeTranslate();
                resetBase();
            }
        }
    
        private void initFitStart() {
            initFitCenter();
    
            float ty = -mImgRect.top;
            mAnimaMatrix.postTranslate(0, ty);
            executeTranslate();
            resetBase();
            mTranslateY += ty;
        }
    
        private void initFitEnd() {
            initFitCenter();
    
            float ty = (mWidgetRect.bottom - mImgRect.bottom);
            mTranslateY += ty;
            mAnimaMatrix.postTranslate(0, ty);
            executeTranslate();
            resetBase();
        }
    
        private void initFitXY() {
            float scaleX = mWidgetRect.width() / mImgRect.width();
            float scaleY = mWidgetRect.height() / mImgRect.height();
    
            mAnimaMatrix.postScale(scaleX, scaleY, mScreenCenter.x, mScreenCenter.y);
    
            executeTranslate();
            resetBase();
        }
    
        private void resetBase() {
            Drawable img = getDrawable();
            int imgw = getDrawableWidth(img);
            int imgh = getDrawableHeight(img);
            mBaseRect.set(0, 0, imgw, imgh);
            mBaseMatrix.set(mSynthesisMatrix);
            mBaseMatrix.mapRect(mBaseRect);
            mHalfBaseRectWidth = mBaseRect.width() / 2;
            mHalfBaseRectHeight = mBaseRect.height() / 2;
            mScale = 1;
            mTranslateX = 0;
            mTranslateY = 0;
            mAnimaMatrix.reset();
        }
    
        private void executeTranslate() {
            mSynthesisMatrix.set(mBaseMatrix);
            mSynthesisMatrix.postConcat(mAnimaMatrix);
            setImageMatrix(mSynthesisMatrix);
    
            mAnimaMatrix.mapRect(mImgRect, mBaseRect);
    
            imgLargeWidth = mImgRect.width() > mWidgetRect.width();
            imgLargeHeight = mImgRect.height() > mWidgetRect.height();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            if (!hasDrawable) {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                return;
            }
    
            Drawable d = getDrawable();
            int drawableW = getDrawableWidth(d);
            int drawableH = getDrawableHeight(d);
    
            int pWidth = MeasureSpec.getSize(widthMeasureSpec);
            int pHeight = MeasureSpec.getSize(heightMeasureSpec);
    
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    
            int width = 0;
            int height = 0;
    
            ViewGroup.LayoutParams p = getLayoutParams();
    
            if (p == null) {
                p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            }
    
            if (p.width == ViewGroup.LayoutParams.MATCH_PARENT) {
                if (widthMode == MeasureSpec.UNSPECIFIED) {
                    width = drawableW;
                } else {
                    width = pWidth;
                }
            } else {
                if (widthMode == MeasureSpec.EXACTLY) {
                    width = pWidth;
                } else if (widthMode == MeasureSpec.AT_MOST) {
                    width = drawableW > pWidth ? pWidth : drawableW;
                } else {
                    width = drawableW;
                }
            }
    
            if (p.height == ViewGroup.LayoutParams.MATCH_PARENT) {
                if (heightMode == MeasureSpec.UNSPECIFIED) {
                    height = drawableH;
                } else {
                    height = pHeight;
                }
            } else {
                if (heightMode == MeasureSpec.EXACTLY) {
                    height = pHeight;
                } else if (heightMode == MeasureSpec.AT_MOST) {
                    height = drawableH > pHeight ? pHeight : drawableH;
                } else {
                    height = drawableH;
                }
            }
    
            if (mAdjustViewBounds && (float) drawableW / drawableH != (float) width / height) {
    
                float hScale = (float) height / drawableH;
                float wScale = (float) width / drawableW;
    
                float scale = hScale < wScale ? hScale : wScale;
                width = p.width == ViewGroup.LayoutParams.MATCH_PARENT ? width : (int) (drawableW * scale);
                height = p.height == ViewGroup.LayoutParams.MATCH_PARENT ? height : (int) (drawableH * scale);
            }
    
            setMeasuredDimension(width, height);
        }
    
        @Override
        public void setAdjustViewBounds(boolean adjustViewBounds) {
            super.setAdjustViewBounds(adjustViewBounds);
            mAdjustViewBounds = adjustViewBounds;
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
    
            mWidgetRect.set(0, 0, w, h);
            mScreenCenter.set(w / 2, h / 2);
    
            if (!isKnowSize) {
                isKnowSize = true;
                initBase();
            }
        }
    
        @Override
        public void draw(Canvas canvas) {
            if (mClip != null) {
                canvas.clipRect(mClip);
                mClip = null;
            }
            super.draw(canvas);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            if (isEnable) {
                final int Action = event.getActionMasked();
                if (event.getPointerCount() >= 2) hasMultiTouch = true;
    
                mDetector.onTouchEvent(event);
                if (isRotateEnable) {
                    mRotateDetector.onTouchEvent(event);
                }
                mScaleDetector.onTouchEvent(event);
    
                if (Action == MotionEvent.ACTION_UP || Action == MotionEvent.ACTION_CANCEL) onUp();
    
                return true;
            } else {
                return super.dispatchTouchEvent(event);
            }
        }
    
        private void onUp() {
            if (mTranslate.isRuning) return;
    
            if (canRotate || mDegrees % 90 != 0) {
                float toDegrees = (int) (mDegrees / 90) * 90;
                float remainder = mDegrees % 90;
    
                if (remainder > 45)
                    toDegrees += 90;
                else if (remainder < -45)
                    toDegrees -= 90;
    
                mTranslate.withRotate((int) mDegrees, (int) toDegrees);
    
                mDegrees = toDegrees;
            }
    
            float scale = mScale;
    
            if (mScale < 1) {
                scale = 1;
                mTranslate.withScale(mScale, 1);
            } else if (mScale > mMaxScale) {
                scale = mMaxScale;
                mTranslate.withScale(mScale, mMaxScale);
            }
    
            float cx = mImgRect.left + mImgRect.width() / 2;
            float cy = mImgRect.top + mImgRect.height() / 2;
    
            mScaleCenter.set(cx, cy);
            mRotateCenter.set(cx, cy);
    
            mTranslateX = 0;
            mTranslateY = 0;
    
            mTmpMatrix.reset();
            mTmpMatrix.postTranslate(-mBaseRect.left, -mBaseRect.top);
            mTmpMatrix.postTranslate(cx - mHalfBaseRectWidth, cy - mHalfBaseRectHeight);
            mTmpMatrix.postScale(scale, scale, cx, cy);
            mTmpMatrix.postRotate(mDegrees, cx, cy);
            mTmpMatrix.mapRect(mTmpRect, mBaseRect);
    
            doTranslateReset(mTmpRect);
            mTranslate.start();
        }
    
        private void doTranslateReset(RectF imgRect) {
            int tx = 0;
            int ty = 0;
    
            if (imgRect.width() <= mWidgetRect.width()) {
                if (!isImageCenterWidth(imgRect))
                    tx = -(int) ((mWidgetRect.width() - imgRect.width()) / 2 - imgRect.left);
            } else {
                if (imgRect.left > mWidgetRect.left) {
                    tx = (int) (imgRect.left - mWidgetRect.left);
                } else if (imgRect.right < mWidgetRect.right) {
                    tx = (int) (imgRect.right - mWidgetRect.right);
                }
            }
    
            if (imgRect.height() <= mWidgetRect.height()) {
                if (!isImageCenterHeight(imgRect))
                    ty = -(int) ((mWidgetRect.height() - imgRect.height()) / 2 - imgRect.top);
            } else {
                if (imgRect.top > mWidgetRect.top) {
                    ty = (int) (imgRect.top - mWidgetRect.top);
                } else if (imgRect.bottom < mWidgetRect.bottom) {
                    ty = (int) (imgRect.bottom - mWidgetRect.bottom);
                }
            }
    
            if (tx != 0 || ty != 0) {
                if (!mTranslate.mFlingScroller.isFinished()) mTranslate.mFlingScroller.abortAnimation();
                mTranslate.withTranslate(mTranslateX, mTranslateY, -tx, -ty);
            }
        }
    
        private boolean isImageCenterHeight(RectF rect) {
            return Math.abs(Math.round(rect.top) - (mWidgetRect.height() - rect.height()) / 2) < 1;
        }
    
        private boolean isImageCenterWidth(RectF rect) {
            return Math.abs(Math.round(rect.left) - (mWidgetRect.width() - rect.width()) / 2) < 1;
        }
    
        private OnRotateListener mRotateListener = new OnRotateListener() {
    
            @Override
            public void onRotate(float degrees, float focusX, float focusY) {
                mRotateFlag += degrees;
                if (canRotate) {
                    mDegrees += degrees;
                    mAnimaMatrix.postRotate(degrees, focusX, focusY);
                } else {
                    if (Math.abs(mRotateFlag) >= mMinRotate) {
                        canRotate = true;
                        mRotateFlag = 0;
                    }
                }
            }
        };
    
        private ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() {
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                float scaleFactor = detector.getScaleFactor();
    
                if (Float.isNaN(scaleFactor) || Float.isInfinite(scaleFactor))
                    return false;
    
                mScale *= scaleFactor;
    //            mScaleCenter.set(detector.getFocusX(), detector.getFocusY());
                mAnimaMatrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
                executeTranslate();
                return true;
            }
    
            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                return true;
            }
            @Override
            public void onScaleEnd(ScaleGestureDetector detector) {
    
            }
        };
    
        private float resistanceScrollByX(float overScroll, float detalX) {
            float s = detalX * (Math.abs(Math.abs(overScroll) - MAX_OVER_RESISTANCE) / (float) MAX_OVER_RESISTANCE);
            return s;
        }
    
        private float resistanceScrollByY(float overScroll, float detalY) {
            float s = detalY * (Math.abs(Math.abs(overScroll) - MAX_OVER_RESISTANCE) / (float) MAX_OVER_RESISTANCE);
            return s;
        }
    
        /**
         * 匹配两个Rect的共同部分输出到out,若无共同部分则输出0,0,0,0
         */
        private void mapRect(RectF r1, RectF r2, RectF out) {
    
            float l, r, t, b;
    
            l = r1.left > r2.left ? r1.left : r2.left;
            r = r1.right < r2.right ? r1.right : r2.right;
    
            if (l > r) {
                out.set(0, 0, 0, 0);
                return;
            }
    
            t = r1.top > r2.top ? r1.top : r2.top;
            b = r1.bottom < r2.bottom ? r1.bottom : r2.bottom;
    
            if (t > b) {
                out.set(0, 0, 0, 0);
                return;
            }
    
            out.set(l, t, r, b);
        }
    
        private void checkRect() {
            if (!hasOverTranslate) {
                mapRect(mWidgetRect, mImgRect, mCommonRect);
            }
        }
    
        private Runnable mClickRunnable = new Runnable() {
            @Override
            public void run() {
                if (mClickListener != null) {
                    mClickListener.onClick(PhotoView.this);
                }
            }
        };
    
        private GestureDetector.OnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() {
    
            @Override
            public void onLongPress(MotionEvent e) {
                if (mLongClick != null) {
                    mLongClick.onLongClick(PhotoView.this);
                }
            }
    
            @Override
            public boolean onDown(MotionEvent e) {
                hasOverTranslate = false;
                hasMultiTouch = false;
                canRotate = false;
                removeCallbacks(mClickRunnable);
                return false;
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                if (hasMultiTouch) return false;
                if (!imgLargeWidth && !imgLargeHeight) return false;
                if (mTranslate.isRuning) return false;
    
                float vx = velocityX;
                float vy = velocityY;
    
                if (Math.round(mImgRect.left) >= mWidgetRect.left || Math.round(mImgRect.right) <= mWidgetRect.right) {
                    vx = 0;
                }
    
                if (Math.round(mImgRect.top) >= mWidgetRect.top || Math.round(mImgRect.bottom) <= mWidgetRect.bottom) {
                    vy = 0;
                }
    
                if (canRotate || mDegrees % 90 != 0) {
                    float toDegrees = (int) (mDegrees / 90) * 90;
                    float remainder = mDegrees % 90;
    
                    if (remainder > 45)
                        toDegrees += 90;
                    else if (remainder < -45)
                        toDegrees -= 90;
    
                    mTranslate.withRotate((int) mDegrees, (int) toDegrees);
    
                    mDegrees = toDegrees;
                }
    
                doTranslateReset(mImgRect);
    
                mTranslate.withFling(vx, vy);
    
                mTranslate.start();
                // onUp(e2);
                return super.onFling(e1, e2, velocityX, velocityY);
            }
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                if (mTranslate.isRuning) {
                    mTranslate.stop();
                }
    
                if (canScrollHorizontallySelf(distanceX)) {
                    if (distanceX < 0 && mImgRect.left - distanceX > mWidgetRect.left)
                        distanceX = mImgRect.left;
                    if (distanceX > 0 && mImgRect.right - distanceX < mWidgetRect.right)
                        distanceX = mImgRect.right - mWidgetRect.right;
    
                    mAnimaMatrix.postTranslate(-distanceX, 0);
                    mTranslateX -= distanceX;
                } else if (imgLargeWidth || hasMultiTouch || hasOverTranslate) {
                    checkRect();
                    if (!hasMultiTouch) {
                        if (distanceX < 0 && mImgRect.left - distanceX > mCommonRect.left)
                            distanceX = resistanceScrollByX(mImgRect.left - mCommonRect.left, distanceX);
                        if (distanceX > 0 && mImgRect.right - distanceX < mCommonRect.right)
                            distanceX = resistanceScrollByX(mImgRect.right - mCommonRect.right, distanceX);
                    }
    
                    mTranslateX -= distanceX;
                    mAnimaMatrix.postTranslate(-distanceX, 0);
                    hasOverTranslate = true;
                }
    
                if (canScrollVerticallySelf(distanceY)) {
                    if (distanceY < 0 && mImgRect.top - distanceY > mWidgetRect.top)
                        distanceY = mImgRect.top;
                    if (distanceY > 0 && mImgRect.bottom - distanceY < mWidgetRect.bottom)
                        distanceY = mImgRect.bottom - mWidgetRect.bottom;
    
                    mAnimaMatrix.postTranslate(0, -distanceY);
                    mTranslateY -= distanceY;
                } else if (imgLargeHeight || hasOverTranslate || hasMultiTouch) {
                    checkRect();
                    if (!hasMultiTouch) {
                        if (distanceY < 0 && mImgRect.top - distanceY > mCommonRect.top)
                            distanceY = resistanceScrollByY(mImgRect.top - mCommonRect.top, distanceY);
                        if (distanceY > 0 && mImgRect.bottom - distanceY < mCommonRect.bottom)
                            distanceY = resistanceScrollByY(mImgRect.bottom - mCommonRect.bottom, distanceY);
                    }
    
                    mAnimaMatrix.postTranslate(0, -distanceY);
                    mTranslateY -= distanceY;
                    hasOverTranslate = true;
                }
    
                executeTranslate();
                return true;
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                postDelayed(mClickRunnable, 250);
                return false;
            }
    
            @Override
            public boolean onDoubleTap(MotionEvent e) {
    
                mTranslate.stop();
    
                float from = 1;
                float to = 1;
    
                float imgcx = mImgRect.left + mImgRect.width() / 2;
                float imgcy = mImgRect.top + mImgRect.height() / 2;
    
                mScaleCenter.set(imgcx, imgcy);
                mRotateCenter.set(imgcx, imgcy);
                mTranslateX = 0;
                mTranslateY = 0;
    
                if (isZoonUp) {
                    from = mScale;
                    to = 1;
                } else {
                    from = mScale;
                    to = mMaxScale;
    
                    mScaleCenter.set(e.getX(), e.getY());
                }
    
                mTmpMatrix.reset();
                mTmpMatrix.postTranslate(-mBaseRect.left, -mBaseRect.top);
                mTmpMatrix.postTranslate(mRotateCenter.x, mRotateCenter.y);
                mTmpMatrix.postTranslate(-mHalfBaseRectWidth, -mHalfBaseRectHeight);
                mTmpMatrix.postRotate(mDegrees, mRotateCenter.x, mRotateCenter.y);
                mTmpMatrix.postScale(to, to, mScaleCenter.x, mScaleCenter.y);
                mTmpMatrix.postTranslate(mTranslateX, mTranslateY);
                mTmpMatrix.mapRect(mTmpRect, mBaseRect);
                doTranslateReset(mTmpRect);
    
                isZoonUp = !isZoonUp;
                mTranslate.withScale(from, to);
                mTranslate.start();
    
                return false;
            }
        };
    
        public boolean canScrollHorizontallySelf(float direction) {
            if (mImgRect.width() <= mWidgetRect.width()) return false;
            if (direction < 0 && Math.round(mImgRect.left) - direction >= mWidgetRect.left)
                return false;
            if (direction > 0 && Math.round(mImgRect.right) - direction <= mWidgetRect.right)
                return false;
            return true;
        }
    
        public boolean canScrollVerticallySelf(float direction) {
            if (mImgRect.height() <= mWidgetRect.height()) return false;
            if (direction < 0 && Math.round(mImgRect.top) - direction >= mWidgetRect.top)
                return false;
            if (direction > 0 && Math.round(mImgRect.bottom) - direction <= mWidgetRect.bottom)
                return false;
            return true;
        }
    
        @Override
        public boolean canScrollHorizontally(int direction) {
            if (hasMultiTouch) return true;
            return canScrollHorizontallySelf(direction);
        }
    
        @Override
        public boolean canScrollVertically(int direction) {
            if (hasMultiTouch) return true;
            return canScrollVerticallySelf(direction);
        }
    
        private class InterpolatorProxy extends Interpolator implements com.seclab.assistant.util.photoutil.InterpolatorProxy, android.view.animation.Interpolator {
    
            private DecelerateInterpolator mTarget;
    
    
    
            public InterpolatorProxy() {
                super(10);
                mTarget = new DecelerateInterpolator();
    
            }
    
            public void setTargetInterpolator(DecelerateInterpolator interpolator) {
                mTarget = interpolator;
            }
    
            @Override
            public float getInterpolation(float input) {
                if (mTarget != null) {
                    return mTarget.getInterpolation(input);
                }
                return input;
            }
        }
    
        private class Transform implements Runnable {
    
            boolean isRuning;
    
            OverScroller mTranslateScroller;
            OverScroller mFlingScroller;
            Scroller mScaleScroller;
            Scroller mClipScroller;
            Scroller mRotateScroller;
    
            ClipCalculate C;
    
            int mLastFlingX;
            int mLastFlingY;
    
            int mLastTranslateX;
            int mLastTranslateY;
    
            RectF mClipRect = new RectF();
    
            InterpolatorProxy mInterpolatorProxy = new InterpolatorProxy();
    
            Transform() {
                Context ctx = getContext();
                mTranslateScroller = new OverScroller(ctx, mInterpolatorProxy);
                mScaleScroller = new Scroller(ctx, mInterpolatorProxy);
                mFlingScroller = new OverScroller(ctx, mInterpolatorProxy);
                mClipScroller = new Scroller(ctx, mInterpolatorProxy);
                mRotateScroller = new Scroller(ctx, mInterpolatorProxy);
            }
    
            public void setInterpolator(DecelerateInterpolator interpolator) {
                mInterpolatorProxy.setTargetInterpolator(interpolator);
            }
    
            void withTranslate(int startX, int startY, int deltaX, int deltaY) {
                mLastTranslateX = 0;
                mLastTranslateY = 0;
                mTranslateScroller.startScroll(0, 0, deltaX, deltaY, mAnimaDuring);
            }
    
            void withScale(float form, float to) {
                mScaleScroller.startScroll((int) (form * 10000), 0, (int) ((to - form) * 10000), 0, mAnimaDuring);
            }
    
            void withClip(float fromX, float fromY, float deltaX, float deltaY, int d, ClipCalculate c) {
                mClipScroller.startScroll((int) (fromX * 10000), (int) (fromY * 10000), (int) (deltaX * 10000), (int) (deltaY * 10000), d);
                C = c;
            }
    
            void withRotate(int fromDegrees, int toDegrees) {
                mRotateScroller.startScroll(fromDegrees, 0, toDegrees - fromDegrees, 0, mAnimaDuring);
            }
    
            void withRotate(int fromDegrees, int toDegrees, int during) {
                mRotateScroller.startScroll(fromDegrees, 0, toDegrees - fromDegrees, 0, during);
            }
    
            void withFling(float velocityX, float velocityY) {
                mLastFlingX = velocityX < 0 ? Integer.MAX_VALUE : 0;
                int distanceX = (int) (velocityX > 0 ? Math.abs(mImgRect.left) : mImgRect.right - mWidgetRect.right);
                distanceX = velocityX < 0 ? Integer.MAX_VALUE - distanceX : distanceX;
                int minX = velocityX < 0 ? distanceX : 0;
                int maxX = velocityX < 0 ? Integer.MAX_VALUE : distanceX;
                int overX = velocityX < 0 ? Integer.MAX_VALUE - minX : distanceX;
    
                mLastFlingY = velocityY < 0 ? Integer.MAX_VALUE : 0;
                int distanceY = (int) (velocityY > 0 ? Math.abs(mImgRect.top) : mImgRect.bottom - mWidgetRect.bottom);
                distanceY = velocityY < 0 ? Integer.MAX_VALUE - distanceY : distanceY;
                int minY = velocityY < 0 ? distanceY : 0;
                int maxY = velocityY < 0 ? Integer.MAX_VALUE : distanceY;
                int overY = velocityY < 0 ? Integer.MAX_VALUE - minY : distanceY;
    
                if (velocityX == 0) {
                    maxX = 0;
                    minX = 0;
                }
    
                if (velocityY == 0) {
                    maxY = 0;
                    minY = 0;
                }
    
                mFlingScroller.fling(mLastFlingX, mLastFlingY, (int) velocityX, (int) velocityY, minX, maxX, minY, maxY, Math.abs(overX) < MAX_FLING_OVER_SCROLL * 2 ? 0 : MAX_FLING_OVER_SCROLL, Math.abs(overY) < MAX_FLING_OVER_SCROLL * 2 ? 0 : MAX_FLING_OVER_SCROLL);
            }
    
            void start() {
                isRuning = true;
                postExecute();
            }
    
            void stop() {
                removeCallbacks(this);
                mTranslateScroller.abortAnimation();
                mScaleScroller.abortAnimation();
                mFlingScroller.abortAnimation();
                mRotateScroller.abortAnimation();
                isRuning = false;
            }
    
            @Override
            public void run() {
    
                // if (!isRuning) return;
    
                boolean endAnima = true;
    
                if (mScaleScroller.computeScrollOffset()) {
                    mScale = mScaleScroller.getCurrX() / 10000f;
                    endAnima = false;
                }
    
                if (mTranslateScroller.computeScrollOffset()) {
                    int tx = mTranslateScroller.getCurrX() - mLastTranslateX;
                    int ty = mTranslateScroller.getCurrY() - mLastTranslateY;
                    mTranslateX += tx;
                    mTranslateY += ty;
                    mLastTranslateX = mTranslateScroller.getCurrX();
                    mLastTranslateY = mTranslateScroller.getCurrY();
                    endAnima = false;
                }
    
                if (mFlingScroller.computeScrollOffset()) {
                    int x = mFlingScroller.getCurrX() - mLastFlingX;
                    int y = mFlingScroller.getCurrY() - mLastFlingY;
    
                    mLastFlingX = mFlingScroller.getCurrX();
                    mLastFlingY = mFlingScroller.getCurrY();
    
                    mTranslateX += x;
                    mTranslateY += y;
                    endAnima = false;
                }
    
                if (mRotateScroller.computeScrollOffset()) {
                    mDegrees = mRotateScroller.getCurrX();
                    endAnima = false;
                }
    
                if (mClipScroller.computeScrollOffset() || mClip != null) {
                    float sx = mClipScroller.getCurrX() / 10000f;
                    float sy = mClipScroller.getCurrY() / 10000f;
                    mTmpMatrix.setScale(sx, sy, (mImgRect.left + mImgRect.right) / 2, C.calculateTop());
                    mTmpMatrix.mapRect(mClipRect, mImgRect);
    
                    if (sx == 1) {
                        mClipRect.left = mWidgetRect.left;
                        mClipRect.right = mWidgetRect.right;
                    }
    
                    if (sy == 1) {
                        mClipRect.top = mWidgetRect.top;
                        mClipRect.bottom = mWidgetRect.bottom;
                    }
    
                    mClip = mClipRect;
                }
    
                if (!endAnima) {
                    applyAnima();
                    postExecute();
                } else {
                    isRuning = false;
    
                    // 修复动画结束后边距有些空隙,
                    boolean needFix = false;
    
                    if (imgLargeWidth) {
                        if (mImgRect.left > 0) {
                            mTranslateX -= mImgRect.left;
                        } else if (mImgRect.right < mWidgetRect.width()) {
                            mTranslateX -= (int) (mWidgetRect.width() - mImgRect.right);
                        }
                        needFix = true;
                    }
    
                    if (imgLargeHeight) {
                        if (mImgRect.top > 0) {
                            mTranslateY -= mImgRect.top;
                        } else if (mImgRect.bottom < mWidgetRect.height()) {
                            mTranslateY -= (int) (mWidgetRect.height() - mImgRect.bottom);
                        }
                        needFix = true;
                    }
    
                    if (needFix) {
                        applyAnima();
                    }
    
                    invalidate();
    
                    if (mCompleteCallBack != null) {
                        mCompleteCallBack.run();
                        mCompleteCallBack = null;
                    }
                }
            }
    
            private void applyAnima() {
                mAnimaMatrix.reset();
                mAnimaMatrix.postTranslate(-mBaseRect.left, -mBaseRect.top);
                mAnimaMatrix.postTranslate(mRotateCenter.x, mRotateCenter.y);
                mAnimaMatrix.postTranslate(-mHalfBaseRectWidth, -mHalfBaseRectHeight);
                mAnimaMatrix.postRotate(mDegrees, mRotateCenter.x, mRotateCenter.y);
                mAnimaMatrix.postScale(mScale, mScale, mScaleCenter.x, mScaleCenter.y);
                mAnimaMatrix.postTranslate(mTranslateX, mTranslateY);
                executeTranslate();
            }
    
    
            private void postExecute() {
                if (isRuning) post(this);
            }
        }
    
        public Info getInfo() {
            RectF rect = new RectF();
            int[] p = new int[2];
            getLocation(this, p);
            rect.set(p[0] + mImgRect.left, p[1] + mImgRect.top, p[0] + mImgRect.right, p[1] + mImgRect.bottom);
            return new Info(rect, mImgRect, mWidgetRect, mBaseRect, mScreenCenter, mScale, mDegrees, mScaleType);
        }
    
        public static Info getImageViewInfo(ImageView imgView) {
            int[] p = new int[2];
            getLocation(imgView, p);
    
            Drawable drawable = imgView.getDrawable();
    
            Matrix matrix = imgView.getImageMatrix();
    
            int width = getDrawableWidth(drawable);
            int height = getDrawableHeight(drawable);
    
            RectF imgRect = new RectF(0, 0, width, height);
            matrix.mapRect(imgRect);
    
            RectF rect = new RectF(p[0] + imgRect.left, p[1] + imgRect.top, p[0] + imgRect.right, p[1] + imgRect.bottom);
            RectF widgetRect = new RectF(0, 0, imgView.getWidth(), imgView.getHeight());
            RectF baseRect = new RectF(widgetRect);
            PointF screenCenter = new PointF(widgetRect.width() / 2, widgetRect.height() / 2);
    
            return new Info(rect, imgRect, widgetRect, baseRect, screenCenter, 1, 0, imgView.getScaleType());
        }
    
        private static void getLocation(View target, int[] position) {
    
            position[0] += target.getLeft();
            position[1] += target.getTop();
    
            ViewParent viewParent = target.getParent();
            while (viewParent instanceof View) {
                final View view = (View) viewParent;
    
                if (view.getId() == android.R.id.content) return;
    
                position[0] -= view.getScrollX();
                position[1] -= view.getScrollY();
    
                position[0] += view.getLeft();
                position[1] += view.getTop();
    
                viewParent = view.getParent();
            }
    
            position[0] = (int) (position[0] + 0.5f);
            position[1] = (int) (position[1] + 0.5f);
        }
    
        private void reset() {
            mAnimaMatrix.reset();
            executeTranslate();
            mScale = 1;
            mTranslateX = 0;
            mTranslateY = 0;
        }
    
        public interface ClipCalculate {
            float calculateTop();
        }
    
        public class START implements ClipCalculate {
            @Override
            public float calculateTop() {
                return mImgRect.top;
            }
        }
    
        public class END implements ClipCalculate {
            @Override
            public float calculateTop() {
                return mImgRect.bottom;
            }
        }
    
        public class OTHER implements ClipCalculate {
            @Override
            public float calculateTop() {
                return (mImgRect.top + mImgRect.bottom) / 2;
            }
        }
    
        /**
         * 在PhotoView内部还没有图片的时候同样可以调用该方法
         * <p></p>
         * 此时并不会播放动画,当给PhotoView设置图片后会自动播放动画。
         * <p></p>
         * 若等待时间过长也没有给控件设置图片,则会忽略该动画,若要再次播放动画则需要重新调用该方法
         * (等待的时间默认500毫秒,可以通过setMaxAnimFromWaiteTime(int)设置最大等待时间)
         */
        public void animaFrom(Info info) {
            if (isInit) {
                reset();
    
                Info mine = getInfo();
    
                float scaleX = info.mImgRect.width() / mine.mImgRect.width();
                float scaleY = info.mImgRect.height() / mine.mImgRect.height();
                float scale = scaleX < scaleY ? scaleX : scaleY;
    
                float ocx = info.mRect.left + info.mRect.width() / 2;
                float ocy = info.mRect.top + info.mRect.height() / 2;
    
                float mcx = mine.mRect.left + mine.mRect.width() / 2;
                float mcy = mine.mRect.top + mine.mRect.height() / 2;
    
                mAnimaMatrix.reset();
                // mAnimaMatrix.postTranslate(-mBaseRect.left, -mBaseRect.top);
                mAnimaMatrix.postTranslate(ocx - mcx, ocy - mcy);
                mAnimaMatrix.postScale(scale, scale, ocx, ocy);
                mAnimaMatrix.postRotate(info.mDegrees, ocx, ocy);
                executeTranslate();
    
                mScaleCenter.set(ocx, ocy);
                mRotateCenter.set(ocx, ocy);
    
                mTranslate.withTranslate(0, 0, (int) -(ocx - mcx), (int) -(ocy - mcy));
                mTranslate.withScale(scale, 1);
                mTranslate.withRotate((int) info.mDegrees, 0);
    
                if (info.mWidgetRect.width() < info.mImgRect.width() || info.mWidgetRect.height() < info.mImgRect.height()) {
                    float clipX = info.mWidgetRect.width() / info.mImgRect.width();
                    float clipY = info.mWidgetRect.height() / info.mImgRect.height();
                    clipX = clipX > 1 ? 1 : clipX;
                    clipY = clipY > 1 ? 1 : clipY;
    
                    ClipCalculate c = info.mScaleType == ScaleType.FIT_START ? new START() : info.mScaleType == ScaleType.FIT_END ? new END() : new OTHER();
    
                    mTranslate.withClip(clipX, clipY, 1 - clipX, 1 - clipY, mAnimaDuring / 3, c);
    
                    mTmpMatrix.setScale(clipX, clipY, (mImgRect.left + mImgRect.right) / 2, c.calculateTop());
                    mTmpMatrix.mapRect(mTranslate.mClipRect, mImgRect);
                    mClip = mTranslate.mClipRect;
                }
    
                mTranslate.start();
            } else {
                mFromInfo = info;
                mInfoTime = System.currentTimeMillis();
            }
        }
    
        public void animaTo(Info info, Runnable completeCallBack) {
            if (isInit) {
                mTranslate.stop();
    
                mTranslateX = 0;
                mTranslateY = 0;
    
                float tcx = info.mRect.left + info.mRect.width() / 2;
                float tcy = info.mRect.top + info.mRect.height() / 2;
    
                mScaleCenter.set(mImgRect.left + mImgRect.width() / 2, mImgRect.top + mImgRect.height() / 2);
                mRotateCenter.set(mScaleCenter);
    
                // 将图片旋转回正常位置,用以计算
                mAnimaMatrix.postRotate(-mDegrees, mScaleCenter.x, mScaleCenter.y);
                mAnimaMatrix.mapRect(mImgRect, mBaseRect);
    
                // 缩放
                float scaleX = info.mImgRect.width() / mBaseRect.width();
                float scaleY = info.mImgRect.height() / mBaseRect.height();
                float scale = scaleX > scaleY ? scaleX : scaleY;
    
                mAnimaMatrix.postRotate(mDegrees, mScaleCenter.x, mScaleCenter.y);
                mAnimaMatrix.mapRect(mImgRect, mBaseRect);
    
                mDegrees = mDegrees % 360;
    
                mTranslate.withTranslate(0, 0, (int) (tcx - mScaleCenter.x), (int) (tcy - mScaleCenter.y));
                mTranslate.withScale(mScale, scale);
                mTranslate.withRotate((int) mDegrees, (int) info.mDegrees, mAnimaDuring * 2 / 3);
    
                if (info.mWidgetRect.width() < info.mRect.width() || info.mWidgetRect.height() < info.mRect.height()) {
                    float clipX = info.mWidgetRect.width() / info.mRect.width();
                    float clipY = info.mWidgetRect.height() / info.mRect.height();
                    clipX = clipX > 1 ? 1 : clipX;
                    clipY = clipY > 1 ? 1 : clipY;
    
                    final float cx = clipX;
                    final float cy = clipY;
                    final ClipCalculate c = info.mScaleType == ScaleType.FIT_START ? new START() : info.mScaleType == ScaleType.FIT_END ? new END() : new OTHER();
    
                    postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            mTranslate.withClip(1, 1, -1 + cx, -1 + cy, mAnimaDuring / 2, c);
                        }
                    }, mAnimaDuring / 2);
                }
    
                mCompleteCallBack = completeCallBack;
                mTranslate.start();
            }
        }
    
        public void rotate(float degrees) {
            mDegrees += degrees;
            int centerX = (int) (mWidgetRect.left + mWidgetRect.width() / 2);
            int centerY = (int) (mWidgetRect.top + mWidgetRect.height() / 2);
    
            mAnimaMatrix.postRotate(degrees, centerX, centerY);
            executeTranslate();
        }
    }
    
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.seclab.assistant.util.photoutil.PhotoView
            android:id="@+id/range_click_img"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerInside"/>
        <Button
            android:text="旋转"
            android:id="@+id/xuanzhuan"
            android:layout_width="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:layout_height="wrap_content"></Button>
    </RelativeLayout>
    
    //别忘了哦  dialog也需要释放的 我这里就不贴了
     @Override
        protected void onPause() {
            super.onPause();
            if (mHandler != null) {
                mHandler.removeCallbacksAndMessages(null);
            }
        }
    
    //这里有两个style都可以使用
     <!--   自定义对话框-->
        <style name="DialogTheme" parent="@android:style/Theme.Dialog">
            <!-- 边框 -->
            <item name="android:windowFrame">@null</item>
            <!-- 是否浮现在activity之上 -->
            <item name="android:windowIsFloating">true</item>
            <!-- 半透明 -->
            <item name="android:windowIsTranslucent">true</item>
            <!-- 无标题 -->
            <item name="android:windowNoTitle">true</item>
            <item name="android:background">@android:color/transparent</item>
            <!-- 背景透明 -->
            <item name="android:windowBackground">@android:color/transparent</item>
            <!-- 模糊 -->
            <item name="android:backgroundDimEnabled">true</item>
            <!-- 遮罩层 -->
            <item name="android:backgroundDimAmount">0.5</item>
        </style>
        <style name="FeedBackActivity" parent="AppTheme">
            <item name="windowNoTitle">true</item>
            <item name="android:windowFullscreen">true</item>
        </style>
        <style name="RangeFragment" parent="AppTheme">
            <item name="windowNoTitle">true</item>
            <!-- 背景透明 -->
            <item name="android:windowBackground">@android:color/transparent</item>
            <!-- 模糊 -->
            <item name="android:backgroundDimEnabled">true</item>
            <item name="android:windowFullscreen">true</item>
        </style>
    

    在这里说明一下

    在这里给你们打个包票 肯定可以 如果不可以的话我是不会写这篇文章的 毕竟这个是我写的东西啊,我来口述一下效果吧 加载一个WebView点击图片出现一个dialog点击的图片显示到dialog上 可以根据手势放大缩小,点击旋转的时候图片进行旋转。如果想要炫酷的界面可以自己制定把我的界面换下来。
    我一直都在的,因为我也一直因为需求找解决办法,如果有解决不了的可以来找我。也可以随时私信我,毕竟我还有很长的路要走,希望能收获到自己的第一个粉丝,嘿嘿~
    如果帮助到你的话可以点点小心心和评论,不要质疑我代码的正确性 这些都是我自己的需求
    只有我写出来才会发出来。
    在这里还有个问题没解决 WebView加载图片在手机上会模糊,所以需要放大,放大我就忍了还要我旋转,旋转出来了还说旋转的时候把图片的高变成宽,宽变成高,我心态裂开 我就是在这个心态中写的这篇文章,我从来没见过app可以图片旋转,毕竟QQ微信都没有这个功能的,我还要继续去找,如果有做过的大佬,记得照顾一下小弟互相交流一下*.*。加油吧,同行们!!
    这个是结合了两个项目写的,历经了两个小时,如需转载的话就标注本人谢谢!

    展开全文
  • 假设我们有一个多图文的新闻资讯类的网站,在网络请求的时候,想要一次性获取所有的图片加载展示出来,那体验肯定是非常糟糕的。为什么?首先我们来看看一个图片HTML 中是如何表现的:<img src=...
  • views.py中的代码如下: ``` def index(request): # 必须有参数 # return HttpResponse("乱于心,困于情, 不畏将来,念过往。 如此。...list能正常打印,for循环执行,为什么? 求解决。
  • webview 加载本地html

    2013-11-01 16:19:41
    很有可能加载不出来.webview将显示一片空白,这个时就需要把它们分开,css 一个目录,图片一个上当,index文件放在最,外面,这样html中引用就没有问题了,但在4.0可以不用这样,不知道为什么,如果谁知道请at 我.谢谢
  • 这是为什么呢?这是网站对图片的一种处理,只有当图片在可视化区域的时候才被加载进来。 伪属性:一般图片html中是这样的。 显示出来的时候用src2,而不是src,这就是伪属性。一般当页面进入到可视化区域的...
  • 牛腩新闻发布--页内图片不显示

    热门讨论 2018-06-05 21:48:36
    当我在敲击牛腩Web的时候,使用Web母版页建立categorymanager模块,同时引用了m_common母版页,引用之后我使用Ctrl+F5运行,发现图片加载不出来,如下所示: 我就感觉很纳闷,为什么会这样,于是我再从新运行其他...
  • 本组件提供了 before-init 钩子,它会在 UEditor 的 scripts 加载完毕之后、编辑器初始化之前触发,你可以在此时机,通过操作 window.UE 对象,来进行诸如添加自定义按钮、弹窗等的二次开发。before-init 的触发函数...
  • alt : 当网速不佳,或者因其他原因图片加载不出来,代替图片解释的信息 002.、有什么区别?、有什么区别em? 有区别,但区别不明显,浏览器显示不出来。 003.请写出至少5个html5新增的标签,并说明其语义和应用...
  • 我用上面的代码爬取一个百度知道的答案,把抓取到的信息打印出来为什么有的地方跟网页审查元素所显示的代码一样? 网页原来的段落为:![图片说明]...
  • ![图片说明](https://img-ask.csdn.net/upload/201912/06/1575616882_971828.png) ++++++++++++++++++++++++++++++++ ![图片说明]...为什么main.jsp会加载不出来呢?是被拦截器拦截了吗?
  • ![图片说明]...大佬们第一张图片是我html页面,第二张是打印的daKuaijizhangpo是有数据的,第三张图片是前端显示的,试了好久,不知道为什么v-for就是没用,加载不出来数据,求帮助啊
  • ## 为了方便大神们的在线阅读,我把截图贴出来,再为了方便大神们帮我测试,我把代码也贴在截图下面,谢谢! ## 好了,开始贴截图+代码: ## 1,控制器 ![图片说明]...
  • 先在上边的代码中封装一楼中的数据: CMS系统中数据如何在首页显示出来: Jsonp跨域请求脚本,script处理的是静态数据,如下: 根据提供的json数据的格式,...思考:为什么不是页面加载完,去通过ajax异步请求加载
  • 现在我在列表页锁屏解锁待其加载完成后切换到图表页,页面显示异常,如果我解锁后等待其加载完成,直接切换到图表页,等图表页加载出来后,显示又是正常的,真的是不知是何原因。还有一点,这个情况只在加载图表的...
  • js 'getContext' of null

    2018-04-04 04:25:46
    才接触js,网上搜了很久没找到有用的,为什么我这个图片加载不出来 ``` <!DOCTYPE html> <html lang="en" dir="ltr"> 哈哈哈哈哈 ;"> var canvas = document.getElementById('...
  • 既然 CacheWebView 是继承于原生的 WebView 为什么会有差别呢,是否做了其他处理? 我只是将 CacheWebView 放在 xml,然后调用 loadDataWithBaseURL,没有其他配置。</p><p>该提问来源于...
  • 我对之前的endebug函数进行了JS反混淆,但是仍看不出反混淆后的代码是如何识别到chromedriver的,或者它和2.1有什么共性因素而被识别出来确定是否是这样做,初学者多多包涵)。 如果对网站的JS加载进行停用,...
  • 图片加载完毕后再使用完整版图片替换它。</li></ul> 延迟加载所有体积较大的组件、字体、JS、视频或Iframe是一个好主意 <h3>4.3 优先加载关键的CSS <p>CSS资源的加载对浏览器渲染的影响很大,默认情况下...
  • 【基础】String为什么是final 20 【基础】java中String、StringBuffer、StringBuilder的区别 21 【基础】运行时异常和非运行时异常 参见 21 运行时异常 21 非运行时异常 22 【基础】java引用类型 23 强引用(Strong...
  • Android UI组件实例集合

    热门讨论 2012-09-11 11:31:29
    为了实现异步的网络图片加载,支持多线程异步加载。 17、Android的开发框架 mobilelite Android应用开发提供一个轻量级开发框架,让开发者可以基于HTML/CSS/JAVASCRIPT快速开发android应用界面,同时也能够利用...
  • 既然用 Chrome, 为什么不让 Chrome extensions/apps 让你的 Chrome 更加强大呢? 推荐给开发者的 Chrome extensions/apps HTMLHTML 基础知识 这部分主要汇总一些比较零碎同时也比较基础的 HTML 知识,对于...
  • 为什么做持久化缓存?</li><li>webpack 如何做持久化缓存?</li><li>webpack 做缓存的一些注意点。</li></ol> 持久化缓存 首先我们需要去解释一下,什么是持久化缓存,在现在前后端分离的应用大行...
  • JAVA面试题最全集

    2010-03-13 13:09:10
    如何加载图片? 66.什么是模态对话框? 67.阐述MVC的概念 68.GUI布局管理器的使用,FlowLayout,BorderLayout,GridBagLayout 69.如何构造一棵树?选择树的一个节点时,如何得到这个节点? 70.向编辑框中输入字符...

空空如也

空空如也

1 2 3 4
收藏数 68
精华内容 27
关键字:

为什么html图片加载不出来