All Projects → iielse → Imageviewer

iielse / Imageviewer

Licence: mit
A simple and customizable Android full-screen image viewer 一个简单且可自定义的Android全屏图像浏览器

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Imageviewer

Transferee
一个帮助您完成从缩略视图到原视图无缝过渡转变的神奇框架
Stars: ✭ 2,697 (+42.77%)
Mutual labels:  gif, wechat, gesture, viewpager, draggable, transferee
Stfalconimageviewer
A simple and customizable Android full-screen image viewer with shared image transition support, "pinch to zoom" and "swipe to dismiss" gestures
Stars: ✭ 1,734 (-8.21%)
Mutual labels:  image, gallery, viewer, zoom, imageviewer
V Viewer
Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js
Stars: ✭ 1,776 (-5.98%)
Mutual labels:  image, gallery, viewer
Xzoom
jQuery Zoom Gallery plugin
Stars: ✭ 120 (-93.65%)
Mutual labels:  image, gallery, zoom
React Viewer
react image viewer, supports rotation, scale, zoom and so on
Stars: ✭ 502 (-73.43%)
Mutual labels:  image, gallery, viewer
Photo view
📸 Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interacive images and other stuff such as SVG.
Stars: ✭ 1,280 (-32.24%)
Mutual labels:  gallery, zoom
Banner
Android Viewpager rotation control, application guide page controls, support vertical, horizontal cycle scrolling, extended from view support animation, indicator extension and so on;Android viewpager轮播图控件、app引导页控件,支持垂直、水平循环滚动,扩展自viewpager 支持动画,指示器扩展等。
Stars: ✭ 96 (-94.92%)
Mutual labels:  gallery, viewpager
Zooming
🔍 Image zoom that makes sense.
Stars: ✭ 1,538 (-18.58%)
Mutual labels:  image, zoom
Zoompreviewpicture
拓展性极高类似微信图片和视频浏览,常见应用场景如微信朋友圈照片九宫格和微信聊天图片图片,视频,gif预览
Stars: ✭ 1,576 (-16.57%)
Mutual labels:  image, gif
React Magnifier
🔍 React image zoom component
Stars: ✭ 116 (-93.86%)
Mutual labels:  image, zoom
Sketch
Sketch 是 Android 上一个强大且全面的图片加载器,支持 GIF,手势缩放以及分块显示超大图片。Sketch is a powerful and comprehensive image loader on Android, with support for GIF, gesture zooming, block display super large image
Stars: ✭ 1,557 (-17.58%)
Mutual labels:  image, gif
Lilliput
Resize images and animated GIFs in Go
Stars: ✭ 1,690 (-10.53%)
Mutual labels:  image, gif
Night
Weekly Go Online Meetup via Bilibili|Go 夜读|通过 bilibili 在线直播的方式分享 Go 相关的技术话题,每天大家在微信/telegram/Slack 上及时沟通交流编程技术话题。
Stars: ✭ 10,058 (+432.45%)
Mutual labels:  wechat, zoom
Abmediaview
Media view which subclasses UIImageView, and can display & load images, videos, GIFs, and audio and from the web, and has functionality to minimize from fullscreen, as well as show GIF previews for videos.
Stars: ✭ 79 (-95.82%)
Mutual labels:  image, gif
React Image Zoom
React component for desktop browsers for image zoom on mouse hover
Stars: ✭ 97 (-94.87%)
Mutual labels:  image, zoom
Imageviewer.swift
An easy to use Image Viewer that is inspired by Facebook
Stars: ✭ 1,071 (-43.3%)
Mutual labels:  image, gallery
Imgviewer
jQuery plugin to zoom and pan images, even those with a size that is a percentage of their container
Stars: ✭ 50 (-97.35%)
Mutual labels:  image, viewer
Bbwebimage
A high performance Swift library for downloading, caching and editing web images asynchronously.
Stars: ✭ 128 (-93.22%)
Mutual labels:  image, gif
Aimage
An animated gif & apng engine for iOS in Swift. Have a great performance on memory and cpu usage.
Stars: ✭ 1,014 (-46.32%)
Mutual labels:  image, gif
Extended image
A powerful official extension library of image, which support placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide out page, editor(crop,rotate,flip), paint custom etc.
Stars: ✭ 1,021 (-45.95%)
Mutual labels:  image, zoom

Imageviewer

提供查看缩略视图到原视图的无缝过渡转变的视觉效果,优雅的浏览普通图、长图、动图.

主要特征

  • 过渡动画 缩略图到大图或大图到缩略图时提供无缝衔接动画
  • 浏览手势 浏览大图时可使用常势操用手.如缩放图片等.(PhotoView
  • 超大图 图片区块加载 (SubsamplingScaleImageView
  • Video 支持Video加载 (ExoPlayer)
  • 拖拽关闭 对大图进行上/下滑操作退出浏览.
  • 数据分页加载 在浏览大图的情况下异步加载数据.
  • 数据删除
  • 自定义UI 对预览页的UI元素自定义追加
  • 已适配RTL

引入

implementation 'com.github.iielse:imageviewer:x.y.z'

最简单的调用代码

fun show() { //
    val dataList: List<Photo> = // 将要展示的图片集合列表
    val clickedData: Photo = // 被点击的其中的那个图片元素信息
    val builder = ImageViewerBuilder(
        context = view.context,
        initKey = clickedData.id, // photoId
        dataProvider = SimpleDataProvider(dataList), // 一次性全量加载 // 实现DataProvider接口支持分页加载
        imageLoader = SimpleImageLoader(), // 可使用demo固定写法 // 实现对数据源的加载.支持自定义加载数据类型,加载方案
        transformer = SimpleTransformer(), // 可使用demo固定写法 // 以photoId为标示,设置过渡动画的'配对'.
    )
    builder.show()
}
// 基本是固定写法. Glide 可以换成别的. demo代码中有video的写法.
class SimpleImageLoader : ImageLoader {
    /** 根据自身photo数据加载图片.可以使用其它图片加载框架. */
    override fun load(view: ImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {
        val it = (data as? MyData?)?.url ?: return
        Glide.with(view).load(it)
                .placeholder(view.drawable)
                .into(view)
    }

    /**
     * 根据自身photo数据加载超大图.subsamplingView数据源需要先将内容完整下载到本地.
     */
    override fun load(subsamplingView: SubsamplingScaleImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {
        val it = (data as? MyData?)?.url ?: return
        subsamplingDownloadRequest(it)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe { findLoadingView(viewHolder)?.visibility = View.VISIBLE }
                .doFinally { findLoadingView(viewHolder)?.visibility = View.GONE }
                .doOnNext { subsamplingView.setImage(ImageSource.uri(Uri.fromFile(it))) }
                .doOnError { toast(it.message) }
                .subscribe().bindLifecycle(subsamplingView)
    }

    private fun subsamplingDownloadRequest(url: String): Observable<File> {
        return Observable.create {
            try {
                it.onNext(Glide.with(appContext).downloadOnly().load(url).submit().get())
                it.onComplete()
            } catch (e: java.lang.Exception) {
                if (!it.isDisposed) it.onError(e)
            }
        }
    }

    private fun findLoadingView(viewHolder: RecyclerView.ViewHolder): View? {
        return viewHolder.itemView.findViewById<ProgressBar>(R.id.loadingView)
    }

    ......
}
// 基本是可以作为固定写法.
class SimpleTransformer : Transformer {
    override fun getView(key: Long): ImageView? = ViewerTransitionHelper.provide(key)
}

/**
 * 维护Transition过渡动画的缩略图和大图之间的映射关系.
 */
object ViewerTransitionHelper {
    private val transition = HashMap<ImageView, Long>()
    fun put(photoId: Long, imageView: ImageView) { // 将photoId和展示这个数据的ImageView'绑定'
        require(isMainThread())
        if (!imageView.isAttachedToWindow) return
        imageView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
            override fun onViewAttachedToWindow(p0: View?) = Unit
            override fun onViewDetachedFromWindow(p0: View?) {
                transition.remove(imageView)
                imageView.removeOnAttachStateChangeListener(this)
            }
        })
        transition[imageView] = photoId
    }

    fun provide(photoId: Long): ImageView? {
        transition.keys.forEach {
            if (transition[it] == photoId)
                return it
        }
        return null
    }
}

到此简单的集成已经完毕.


进阶使用.

(组合实现以下3个方法.可以追加自定义的展示和功能)

  • // 自定义'每一页'上的UI.比如可显示图片的更多信息.提供存储分享等更多功能等
  • builder.setVHCustomizer(MyCustomViewHolderUI())
  • // 自定义'覆盖(最上)层'上的UI.比如添加指示器等
  • builder.setOverlayCustomizer(MyCustomIndicatorUI())
  • // 监听viewer的各种状态变化.包括页面的切换(显示当前在第几页).;过渡动画的执行状态;维护video的播放状态等
  • builder.setViewerCallback(MyViewerStateChangedListener())
// 一般监听翻页onPageSelected可以控制 video播放的状态
// viewer 各状态监听回调
interface ViewerCallback : ImageViewerAdapterListener {
    // 当点击缩略图变化大图的瞬间
    override fun onInit(viewHolder: RecyclerView.ViewHolder) {}
    // 当图片被拖动时
    override fun onDrag(viewHolder: RecyclerView.ViewHolder, view: View, fraction: Float) {}
    // 当图片被拖动但不至于退出浏览
    override fun onRestore(viewHolder: RecyclerView.ViewHolder, view: View, fraction: Float) {}
    // 当图片被拖动执行退出浏览
    override fun onRelease(viewHolder: RecyclerView.ViewHolder, view: View) {}
    // 翻页中状态变化
    fun onPageScrollStateChanged(state: Int) {}
    // 翻页中
    fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
    // 当某大图页面被选中
    fun onPageSelected(position: Int, viewHolder: RecyclerView.ViewHolder) {}
}

参数配置. 一般不用调整

属性 作用说明
OFFSCREEN_PAGE_LIMIT viewer预加载条数
VIEWER_ORIENTATION viewer滑动方向
VIEWER_BACKGROUND_COLOR 大图预览时背景色(默认纯黑)
DURATION_TRANSITION 过渡动画时长
DURATION_BG 过渡动画背景变化时长
SUBSAMPLING_SCALE_TYPE 大图初始化加载模式
SWIPE_DISMISS 是否支持拖拽返回
SWIPE_TOUCH_SLOP 拖拽触摸感知阈值
DISMISS_FRACTION 拖拽返回边界阈值
TRANSITION_OFFSET_Y 修正透明状态栏下过渡动画的起始位置

数据源的定义

interface Photo {
    fun id(): Long // 每条图片数据的唯一标示. 主要用于分页数据加载. 定位过渡动画的对应关系
    fun itemType(): @ItemType.Type Int // 是否启用SubsamplingScaleImageView实现图片区块加载或ExoVideoView实现Video加载
}

FAQ

  • 如何手动关闭退出整个页面?
  • 如何删除一条数据?

通过 ViewModelProvider(activity).get(ImageViewerActionViewModel::class.java)获取viewer 对象引用. 之后可使用 setCurrentItem(pos: Int)切换大图位置到指定位置; dismiss()退出浏览大图; remove(item: List<Photo>)删除其中的元素

  • 如何实现Video的展示? 可参考demo实现 demo代码位置 SimpleViewerCustomizer
  • 为什么没有过渡动画? 需要正确的配置 Transformer。需要保证getView 返回不为null.
  • 为什么动画的执行和原图有高度偏差? 注意状态栏的影响。配置Config.TRANSITION_OFFSET_Y

其它重要说明

demo可运行. demo可运行. demo可运行 .demo代码已重构.

都看到这里了,不点下Star吗 [旺柴]

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].