Giter VIP home page Giter VIP logo

albert-lii / imageviewer Goto Github PK

View Code? Open in Web Editor NEW
447.0 6.0 52.0 77.73 MB

:crystal_ball:图片浏览器,支持图片手势缩放、拖拽等操作,`自定义View`的模式显示,自定义图片加载方式,更加灵活,易于扩展,同时也适用于RecyclerView、ListView的横向和纵向列表模式,最低支持版本为Android 3.0及以上...

Home Page: https://github.com/albert-lii/ImageViewer

Java 100.00%
android imageviewer imagebrowser dragphoto photoview imageview listview gridview recyclerview

imageviewer's People

Contributors

albert-lii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

imageviewer's Issues

首次打开会稍微抖动一下,第二次打开就不抖动了

场景:

原图尺寸:W=600px, H=800px
缩略图尺寸:W=600px, H=600px (缩略图为原图的中间部分)

列表上的使用的是缩略图,点击缩略图打开imageViewer(传入的是原图的URL),就会出现第一次会稍微有点抖动,不自然,但是第二次就好了。第二次好的原因是:

override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
    view.setImageDrawable(resource)

    // 把下面2行注释了后,第二次也会抖动。
    frames.get(position).setImageWidth(resource.intrinsicWidth.toFloat())
    frames.get(position).setImageHeight(resource.intrinsicHeight.toFloat())
}

异常问题好多

目前发现的问题,未考虑有head和foot的情况,导致数组越界
未考虑同一个页面两个列表的情况,如果第一个列表为1条数据,先点击第一个列表的图片,再点击第二个列表的第二条,会出异常,只能通过重写indexui的handleItemChanged来解决,因为这里没有判断getIndexView为null。
在绑定Imageloader的时候,回调里的object直接用数据源里面的model数据不就行了吗?非得写死用viewdata的src,这样不同的model传递进去首先要继承viewdata,还得把数据格式一遍,一点扩展性都没有

recyclerview

recyclerview使用的时候应该注意哪些问题呢,总是报空指针异常,求助 @albert-lii

关于状态的建议

当用户使用返回键时,如果图片预览器为打开,或者准备打开等状态,那么返回动作为关闭预览画面,否则就根据业务执行其他操作,其实现代码如下

    @Override
    public void onBackPressed() {
        int viewState = mDetailImagePreview.getViewState();
        if (viewState == ImageViewerState.STATE_READY_OPEN
                || viewState == ImageViewerState.STATE_OPENING
                || viewState == ImageViewerState.STATE_COMPLETE_OPEN
                || viewState == ImageViewerState.STATE_WATCHING) {
            mDetailImagePreview.close();
            mFlowLayout.setVisibility(View.VISIBLE);
        } else {
            finish();
        }
    }

上述,对于状态的判断有些繁琐。所以希望提供一个方法,能够简化判断,即如下:

    @Override
    public void onBackPressed() {
        if (mDetailImagePreview.readyWatch()) { // 名字瞎起的
            mDetailImagePreview.close();
            mFlowLayout.setVisibility(View.VISIBLE);
        } else {
            finish();
        }
    }

或者

    @Override
    public void onBackPressed() {
        int viewState = mDetailImagePreview.getViewState();
        if (viewState <= ImageViewerState.STATE_WATCHING) {
            mDetailImagePreview.close();
            mFlowLayout.setVisibility(View.VISIBLE);
        } else {
            finish();
        }
    }

对于后一种方法,鉴于从 2.0.2 升级到 2.1.2 的过程中,许多方法以及状态遭废弃,不可用的行为,希望大神在代码里注释一下,以后版本更新,该形式不会受到影响,^_^///

同理,希望对预览器不在浏览中也提供类似的方法(目前版本,关闭之后的状态为拖拽,这个顺序不妨改一改)

滑动出现异常(必现)

点开预览或者横向列表 ,点开第一张图片,先正着滑动到最后,然后关闭大图,再点开,然后倒着滑动某张图片后,再关闭大图预览,再点开,滑动就会出现崩溃了,也就是上面所抛出的异常。
06-19 09:12:43.856 277-369/? E/SurfaceFlinger: Failed to find layer (indi.liyi.example/indi.liyi.example.ui.VerticalListActivity#0) in layer parent (no-parent).
06-19 09:13:03.884 13083-13083/indi.liyi.example E/AndroidRuntime: FATAL EXCEPTION:
mainProcess: indi.liyi.example, PID: 13083java.lang.RuntimeException:
Canvas: trying to use a recycled bitmap android.graphics.Bitmap@ff78def
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:55)
at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:226)
at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529)
at android.widget.ImageView.onDraw(ImageView.java:1367)
at android.view.View.draw(View.java:19315)
at android.view.View.updateDisplayListIfDirty(View.java:18232)
at android.view.View.draw(View.java:19030)
at android.view.ViewGroup.drawChild(ViewGroup.java:4297)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4083)
at android.view.View.updateDisplayListIfDirty(View.java:18223)
at android.view.View.draw(View.java:19030)
at android.view.ViewGroup.drawChild(ViewGroup.java:4297)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4083)
at android.view.View.draw(View.java:19323)
at android.support.v4.view.ViewPager.draw(ViewPager.java:2426)
at android.view.View.updateDisplayListIfDirty(View.java:18232)
at android.view.View.draw(View.java:19030)
at android.view.ViewGroup.drawChild(ViewGroup.java:4297)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4083)
at android.view.View.draw(View.java:19323)
at android.view.View.updateDisplayListIfDirty(View.java:18232)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4281)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4261)
at android.view.View.updateDisplayListIfDirty(View.java:18181)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4281)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4261)
at android.view.View.updateDisplayListIfDirty(View.java:18181)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4281)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4261)
at android.view.View.updateDisplayListIfDirty(View.java:18181)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4281)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4261)
at android.view.View.updateDisplayListIfDirty(View.java:18181)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:669)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:675)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:783)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3117)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2926)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2464)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1446)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7014)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:916)
at android.view.Choreographer.doCallbacks(Choreographer.java:728)
at android.view.Choreographer.doFrame(Choreographer.java:660)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:902)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)

简单预览界面,点开第二张图然后滑动到第三张图 拖拽关闭预览时崩溃

Process: com.liyi.example, PID: 22874
java.lang.NullPointerException: Attempt to invoke virtual method 'float com.liyi.viewer.ViewData.getTargetX()' on a null object reference
at com.liyi.viewer.dragger.WxImageDragger.exit(WxImageDragger.java:179)
at com.liyi.viewer.dragger.WxImageDragger.onRelease(WxImageDragger.java:108)
at com.liyi.viewer.widget.ScaleImageView.onActionUp(ScaleImageView.java:212)
at com.liyi.viewer.widget.ScaleImageView.onTouchEvent(ScaleImageView.java:189)
at android.view.View.dispatchTouchEvent(View.java:9302)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2590)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2257)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2596)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2271)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2596)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2271)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2596)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2271)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2596)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2271)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2596)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2271)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2596)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2271)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2408)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1742)
at android.app.Activity.dispatchTouchEvent(Activity.java:2805)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2369)
at android.view.View.dispatchPointerEvent(View.java:9522)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4729)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4593)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4137)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4190)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4156)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4282)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4164)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4339)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4137)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4190)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4156)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4164)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4137)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6461)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6427)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6388)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6571)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5441)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

图片模糊问题

还有一个小bug就是
Glide.with(this).load(source).into(imageView)这种加载图片的方式,第一张图片会模糊

如果通过imageview的imageBitmap属性添加图片没问题。
你的demo也是这样的。

加载动态图的时候遇到的问题

Eoor

Unable to start activity ComponentInfo{com.nijigenlink.gb/com.liyi.viewer.view.ImagePreviewActivity}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class uk.co.senab.photoview.PhotoView

pointerIndex out of range

在 2.0.2 版本报一下错误,可以看看最新版本是否已经修复该BUG:

pointerIndex out of range
com.liyi.viewer.widget.ImagePager.onInterceptTouchEvent(ImagePager.java:68)

这是Bugly提供的解决方案,可以参考一下
参数不匹配异常,通常由于传递了不正确的参数导致。
常见于:

  1. Activity、Service状态异常;
  2. 非法URL;
  3. UI线程操作。
    4.Fragment中嵌套了子Fragment,Fragment被销毁,而内部Fragment未被销毁,所以导致再次加载时重复,在onDestroyView() 中将内部Fragment销毁即可
    5.在请求网络的回调中使用了glide.into(view),view已经被销毁会导致该错误

图片模糊

第一次加载图片时图片模糊,因为有开场动画的原因,如何修改这个问题

demo随便打开一张图,然后一直双指合并缩小,崩溃

java.lang.IllegalArgumentException: pointerIndex out of range
at android.view.MotionEvent.nativeGetAxisValue(Native Method)
at android.view.MotionEvent.getX(MotionEvent.java:2201)
at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:2066)
at com.liyi.viewer.widget.viewpager.ImagePager.onInterceptTouchEvent(ImagePager.java:68)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2511)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829)
at android.app.Activity.dispatchTouchEvent(Activity.java:3307)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
at android.view.View.dispatchPointerEvent(View.java:12015)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

关于内存及时回收

因为展示的图片都是比较高清的,比如说demo中的6张图片,这个时候,打开自定义控件imageviewer后,内存会从100M飙升到180M,是不是应该在viewpager切换的过程中及时回收,这是第一个问题。第二个问题是退出imageviewer后,能否做到及时回收图片的内存呢?

技术探讨,可能和框架本身无关,也可能有关,让框架更完善,盼复,辛苦了,感谢你的分享,祝好。

动画不流畅

Recyclerview + AutoGridView + Imageviewer 显示的动画不流畅, 有时候还有错位,这个viewdata 让使用更复杂

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.