rewrite the way fullscreen images are loaded, for better quality, close #90, #84

This commit is contained in:
tibbi 2017-01-06 14:15:05 +01:00
parent 7d1e08ea19
commit 7b9503229f
9 changed files with 119 additions and 137 deletions

View file

@ -93,6 +93,7 @@
<activity
android:name=".activities.PhotoVideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/FullScreenTheme"/>
<activity

View file

@ -3,9 +3,11 @@ package com.simplemobiletools.gallery.activities
import android.os.Bundle
class PhotoActivity : PhotoVideoActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
PhotoVideoActivity.mIsVideo = false
super.onCreate(savedInstanceState)
}
override fun systemUiVisibilityChanged(visibility: Int) {
}
}

View file

@ -1,12 +1,12 @@
package com.simplemobiletools.gallery.activities
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.Menu
import android.view.MenuItem
import android.view.View
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.fragments.PhotoFragment
@ -16,7 +16,7 @@ import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
import java.io.File
open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentClickListener {
open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentListener {
private var mMedium: Medium? = null
private var mIsFullScreen = false
@ -46,6 +46,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentClic
}
}
showSystemUI()
val bundle = Bundle()
val file = File(mUri.toString())
mMedium = Medium(file.name, mUri.toString(), mIsVideo, 0, 0, file.length())
@ -80,11 +81,6 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentClic
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
mFragment.updateItem()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.photo_video_menu, menu)
@ -113,4 +109,13 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentClic
showSystemUI()
}
}
override fun systemUiVisibilityChanged(visibility: Int) {
if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
mIsFullScreen = false
showSystemUI()
} else {
mIsFullScreen = true
}
}
}

View file

@ -2,7 +2,6 @@ package com.simplemobiletools.gallery.activities
import android.app.Activity
import android.content.Intent
import android.content.res.Configuration
import android.database.Cursor
import android.os.Bundle
import android.provider.MediaStore
@ -29,7 +28,7 @@ import kotlinx.android.synthetic.main.activity_medium.*
import java.io.File
import java.util.*
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View.OnSystemUiVisibilityChangeListener, ViewPagerFragment.FragmentClickListener {
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
private var mMedia = ArrayList<Medium>()
private var mPath = ""
private var mDirectory = ""
@ -77,7 +76,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
mDirectory = File(mPath).parent
title = mPath.getFilenameFromPath()
window.decorView.setOnSystemUiVisibilityChangeListener(this)
reloadViewPager()
scanPath(mPath) {}
}
@ -114,12 +112,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
return true
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val adapter = view_pager.adapter as MyPagerAdapter
adapter.updateItems(mPos)
}
private fun updatePagerItems() {
val pagerAdapter = MyPagerAdapter(this, supportFragmentManager, mMedia)
view_pager.apply {
@ -260,6 +252,15 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
}
override fun systemUiVisibilityChanged(visibility: Int) {
if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
mIsFullScreen = false
showSystemUI()
} else {
mIsFullScreen = true
}
}
private fun updateActionbarTitle() {
runOnUiThread {
title = mMedia[mPos].path.getFilenameFromPath()
@ -286,20 +287,5 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
override fun onPageScrollStateChanged(state: Int) {
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
val adapter = view_pager.adapter as MyPagerAdapter
adapter.itemDragged(mPos)
}
}
override fun onSystemUiVisibilityChange(visibility: Int) {
view_pager.adapter?.apply {
if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
mIsFullScreen = false
showSystemUI()
}
(this as MyPagerAdapter).updateUiVisibility(mIsFullScreen, mPos)
}
}
}

View file

@ -5,7 +5,6 @@ import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentStatePagerAdapter
import android.support.v4.view.PagerAdapter
import android.util.SparseArray
import com.simplemobiletools.gallery.activities.ViewPagerActivity
import com.simplemobiletools.gallery.fragments.PhotoFragment
import com.simplemobiletools.gallery.fragments.VideoFragment
@ -14,8 +13,6 @@ import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
class MyPagerAdapter(val activity: ViewPagerActivity, fm: FragmentManager, val media: MutableList<Medium>) : FragmentStatePagerAdapter(fm) {
private val mFragments: SparseArray<ViewPagerFragment> = SparseArray<ViewPagerFragment>()
override fun getCount() = media.size
override fun getItem(position: Int): Fragment {
@ -30,25 +27,10 @@ class MyPagerAdapter(val activity: ViewPagerActivity, fm: FragmentManager, val m
fragment = PhotoFragment()
}
mFragments.put(position, fragment)
fragment.arguments = bundle
fragment.listener = activity
return fragment
}
override fun getItemPosition(item: Any?) = PagerAdapter.POSITION_NONE
fun itemDragged(pos: Int) {
mFragments[pos]?.itemDragged()
}
fun updateUiVisibility(isFullscreen: Boolean, pos: Int) {
(-1..1).map { mFragments[pos + it] }
.forEach { it?.systemUiVisibilityChanged(isFullscreen) }
}
fun updateItems(pos: Int) {
(-1..1).map { mFragments[pos + it] }
.forEach { it?.updateItem() }
}
}

View file

@ -1,12 +1,17 @@
package com.simplemobiletools.gallery.fragments
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.simplemobiletools.gallery.R
@ -15,38 +20,62 @@ import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.pager_photo_item.view.*
class PhotoFragment : ViewPagerFragment(), View.OnClickListener {
lateinit var subsamplingView: SubsamplingScaleImageView
class PhotoFragment : ViewPagerFragment() {
lateinit var medium: Medium
lateinit var mView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.pager_photo_item, container, false)
mView = inflater.inflate(R.layout.pager_photo_item, container, false)
medium = arguments.getSerializable(MEDIUM) as Medium
if (medium.path.startsWith("content://"))
medium.path = context.getRealPathFromURI(Uri.parse(medium.path)) ?: ""
subsamplingView = view.photo_view
if (medium.isGif()) {
subsamplingView.visibility = View.GONE
view.glide_view.apply {
visibility = View.VISIBLE
Glide.with(context).load(medium.path).asGif().diskCacheStrategy(DiskCacheStrategy.NONE).into(this)
setOnClickListener(this@PhotoFragment)
loadImage(medium)
activity.window.decorView.setOnSystemUiVisibilityChangeListener { visibility ->
listener?.systemUiVisibilityChanged(visibility)
}
return mView
}
private fun loadImage(medium: Medium) {
val subsamplingView = mView.photo_view.apply { setOnClickListener({ photoClicked() }) }
val glideView = mView.glide_view.apply { setOnClickListener({ photoClicked() }) }
if (medium.isGif()) {
Glide.with(this)
.load(medium.path)
.asGif()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(glideView)
} else {
Glide.with(this)
.load(medium.path)
.asBitmap()
.format(if (medium.isPng()) DecodeFormat.PREFER_ARGB_8888 else DecodeFormat.PREFER_RGB_565)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.listener(object : RequestListener<String, Bitmap> {
override fun onException(e: Exception?, model: String?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
return false
}
override fun onResourceReady(resource: Bitmap?, model: String?, target: Target<Bitmap>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean {
if (!medium.isPng()) {
subsamplingView.visibility = View.VISIBLE
subsamplingView.apply {
setDoubleTapZoomScale(1.2f)
orientation = SubsamplingScaleImageView.ORIENTATION_USE_EXIF
setImage(ImageSource.uri(medium.path))
maxScale = 4f
setMinimumTileDpi(100)
setOnClickListener(this@PhotoFragment)
orientation = SubsamplingScaleImageView.ORIENTATION_USE_EXIF
maxScale = 5f
setOnImageEventListener(object : SubsamplingScaleImageView.OnImageEventListener {
override fun onImageLoaded() {
}
override fun onReady() {
glideView.visibility = View.GONE
subsamplingView.visibility = View.VISIBLE
}
override fun onTileLoadError(p0: Exception?) {
@ -56,12 +85,6 @@ class PhotoFragment : ViewPagerFragment(), View.OnClickListener {
}
override fun onImageLoadError(p0: Exception?) {
subsamplingView.visibility = View.GONE
view.glide_view.apply {
visibility = View.VISIBLE
Glide.with(context).load(medium.path).diskCacheStrategy(DiskCacheStrategy.NONE).into(this)
setOnClickListener(this@PhotoFragment)
}
}
override fun onPreviewLoadError(p0: Exception?) {
@ -69,28 +92,18 @@ class PhotoFragment : ViewPagerFragment(), View.OnClickListener {
})
}
}
return view
return false
}
}).into(glideView)
}
}
override fun itemDragged() {
}
override fun systemUiVisibilityChanged(toFullscreen: Boolean) {
}
override fun updateItem() {
subsamplingView.setImage(ImageSource.uri(medium.path))
}
override fun onClick(v: View) {
photoClicked()
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
loadImage(medium)
}
private fun photoClicked() {
if (listener == null)
listener = activity as ViewPagerFragment.FragmentClickListener
listener?.fragmentClicked()
}
}

View file

@ -5,6 +5,7 @@ import android.media.AudioManager
import android.media.MediaPlayer
import android.media.MediaPlayer.OnPreparedListener
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.util.DisplayMetrics
@ -61,6 +62,13 @@ class VideoFragment : ViewPagerFragment(), View.OnClickListener, SurfaceHolder.C
setupPlayer()
mView.setOnClickListener(this)
activity.window.decorView.setOnSystemUiVisibilityChangeListener { visibility ->
val fullscreen = visibility and View.SYSTEM_UI_FLAG_FULLSCREEN != 0
mIsFullscreen = fullscreen
checkFullscreen()
listener?.systemUiVisibilityChanged(visibility)
}
return mView
}
@ -85,21 +93,14 @@ class VideoFragment : ViewPagerFragment(), View.OnClickListener, SurfaceHolder.C
if (context != null && Config.newInstance(context).autoplayVideos) {
playVideo()
}
}
}
override fun itemDragged() {
} else {
if (mIsPlaying)
pauseVideo()
}
override fun systemUiVisibilityChanged(toFullscreen: Boolean) {
if (mIsFullscreen != toFullscreen) {
mIsFullscreen = toFullscreen
checkFullscreen()
}
}
override fun updateItem() {
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
setVideoSize()
initTimeHolder()
}
@ -162,10 +163,6 @@ class VideoFragment : ViewPagerFragment(), View.OnClickListener, SurfaceHolder.C
else -> {
mIsFullscreen = !mIsFullscreen
checkFullscreen()
if (listener == null)
listener = activity as ViewPagerFragment.FragmentClickListener
listener?.fragmentClicked()
}
}
@ -302,7 +299,7 @@ class VideoFragment : ViewPagerFragment(), View.OnClickListener, SurfaceHolder.C
val screenWidth: Int
val screenHeight: Int
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val realMetrics = DisplayMetrics()
display.getRealMetrics(realMetrics)
screenWidth = realMetrics.widthPixels

View file

@ -3,15 +3,11 @@ package com.simplemobiletools.gallery.fragments
import android.support.v4.app.Fragment
abstract class ViewPagerFragment : Fragment() {
var listener: FragmentClickListener? = null
var listener: FragmentListener? = null
abstract fun itemDragged()
abstract fun systemUiVisibilityChanged(toFullscreen: Boolean)
abstract fun updateItem()
interface FragmentClickListener {
interface FragmentListener {
fun fragmentClicked()
fun systemUiVisibilityChanged(visibility: Int)
}
}

View file

@ -5,13 +5,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
android:id="@+id/photo_view"
<ImageView
android:id="@+id/glide_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/glide_view"
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
android:id="@+id/photo_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>