Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow apps to provide customized ViewHolders #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

svank
Copy link
Contributor

@svank svank commented Mar 25, 2019

Hi! This is a great library you've made---and it's the only one I could find with this type of functionality, which surprised me.

I'm using StfalconImageViewer with the camera function in my app to let users view the images they've taken. I'm expanding to include video recording, so I'd like users to be able to view both photos and videos in the same pop-up viewer. After a few attempts, I made what I think are useful, generally-applicable changes to StfalconImageViewer to enable my use case and many others. These changes do not affect existing users of the library or significantly increase the library's scope, which I think makes them a candidate for merging.

In short, the image viewer currently uses a ViewHolder, holding a PhotoView, along with the ImagesPagerAdapter and MultiTouchViewPager. My changes add a ViewHolderLoader interface and an optional additional argument to the Builder, allowing apps to pass in a ViewHolderLoader. This loader, or a default loader if none is passed, provides ViewHolders to ImagesPagerAdapter. Apps that choose to implement a ViewHolderLoader can then have their implementation return a subclass of the default ViewHolder which customizes the paging views as desired. A few additional details are described in the commit message.

In my video use case, my custom ViewHolder puts the usual PhotoView in a FrameLayout along with a VideoView, and then in bind() it displays one view or the other as appropriate.

Other use cases might want to customize each Pager page with additional views (e.g. a caption or a "new image!" icon) which scroll with the images---as opposed to placing that extra content in an overlay view, where the content would be statically positioned.

I created a repo demonstrating the use of these changes. It replicates my mixed photos/videos use case and shows how additional views (in the demo, a TextView) can add content alongside the image on each page.

This was my first time working with Kotlin, so I'm very open to suggested revisions.

@svank svank changed the title Custom viewholders Allow apps to provide customized ViewHolders Mar 25, 2019
@mrkazansky
Copy link

nice work bro

@svank svank force-pushed the custom-viewholders branch from 3a037ab to 88b8569 Compare November 24, 2019 19:49
svank added 2 commits March 28, 2020 20:43
The Overlay View feature is excellent for items like Share buttons which
can remain in one place as the images scroll, but customizations cannot
be added that scroll with the images being viewed. Additionally, the
scrolling images themselves cannot be customized beyond what can be done
in the ImageLoader and the background/padding/etc. options provided in
StfalconImageViewer.Builder.

To enable additional use cases, this commit allows applications to
subclass the ViewHolders used internally, providing full control over
the scrolling views. Subclasses are passed the PhotoView used in the
default ViewHolder.  Subclasses might simply adjust the style or layout
parameters of the PhotoView. Subclasses might incorporate the PhotoView
within a Layout and include other Views (e.g. a "New Image!" icon
overlaid in the corner, or a caption). Subclasses might include other,
alternative Views (e.g. a VideoView) and display one or the other
depending on the item bound to the ViewHolder. Subclasses might ignore
the PhotoView altogether and insert their own Views.

This is achieved without affecting the existing use cases or requiring
existing apps to modify their usage.

A new constructor is added to StfalconImageViewer.Builder allowing
applications a pass an additional argument, an implementation of
ViewHolderLoader. This contains a single function, accepting a PhotoView
and returning a subclass of DefaultViewHolder.  When this new
constructor is not used, a DefaultViewHolderLoader is used, which
returns a DefaultViewHolder (which is the ViewHolder that was used
before, extracted to its own file and enhanced for extensibility).
Through a custom ViewHolderLoader and the DefaultViewHolder constructor
and bind() methods overridden in the subclass, applications have
complete control of the Views presented in the ViewPager.

My use cases involves displaying both photos and videos taken with the
camera function in my app, so my ViewHolderLoader creates a FrameLayout
containing the default PhotoView and a VideoView, and my ViewHolder
switches between these two views depending on the Uri it receives in
bind(). To allow applications such as my own to play/pause videos as
they come on or off the screen, I added two methods to
DefaultViewHolder, onDialogClosed() and setIsVisible(), to allow videos
to be paused when scrolled off-screen, resumed when scrolled on-screen,
and stopped entirely when the dialog begins to close.

A demo of custom ViewHolders will be posted at
https://github.com/svank/Custom-ViewHolders-Demo
@svank svank force-pushed the custom-viewholders branch from 88b8569 to dc46fa6 Compare March 29, 2020 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants