improved media viewer

This commit is contained in:
Mariotaku Lee 2017-04-18 00:10:29 +08:00
parent bd0ea16b97
commit 7b2229f9a5
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
7 changed files with 88 additions and 18 deletions

View File

@ -1,5 +1,7 @@
package android.support.v7.app package android.support.v7.app
import android.support.v7.widget.ActionBarContainer import android.support.v7.widget.ActionBarContainer
import android.support.v7.widget.DecorToolbar
val WindowDecorActionBar.containerView: ActionBarContainer get() = mContainerView val WindowDecorActionBar.containerView: ActionBarContainer get() = mContainerView
val WindowDecorActionBar.decorToolbar: DecorToolbar get() = mDecorToolbar

View File

@ -26,6 +26,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.os.Parcelable import android.os.Parcelable
import android.support.annotation.RequiresApi
import android.support.v4.app.DialogFragment import android.support.v4.app.DialogFragment
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat import android.support.v4.content.ContextCompat
@ -33,14 +34,16 @@ import android.support.v4.graphics.ColorUtils
import android.support.v4.view.ViewPager import android.support.v4.view.ViewPager
import android.support.v4.widget.ViewDragHelper import android.support.v4.widget.ViewDragHelper
import android.support.v7.app.WindowDecorActionBar import android.support.v7.app.WindowDecorActionBar
import android.support.v7.app.containerView import android.support.v7.app.decorToolbar
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_media_viewer.* import kotlinx.android.synthetic.main.activity_media_viewer.*
import org.mariotaku.chameleon.Chameleon import org.mariotaku.chameleon.Chameleon
import org.mariotaku.ktextension.checkAllSelfPermissionsGranted import org.mariotaku.ktextension.checkAllSelfPermissionsGranted
import org.mariotaku.ktextension.contains
import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.ktextension.toTypedArray import org.mariotaku.ktextension.toTypedArray
import org.mariotaku.mediaviewer.library.* import org.mariotaku.mediaviewer.library.*
@ -50,6 +53,8 @@ import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.iface.IBaseActivity import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
import org.mariotaku.twidere.annotation.CacheFileType import org.mariotaku.twidere.annotation.CacheFileType
import org.mariotaku.twidere.extension.addSystemUiVisibility
import org.mariotaku.twidere.extension.removeSystemUiVisibility
import org.mariotaku.twidere.fragment.PermissionRequestDialog import org.mariotaku.twidere.fragment.PermissionRequestDialog
import org.mariotaku.twidere.fragment.ProgressDialogFragment import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment import org.mariotaku.twidere.fragment.iface.IBaseFragment
@ -95,6 +100,14 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
intent.getParcelableArrayExtra(EXTRA_MEDIA)?.toTypedArray(ParcelableMedia.CREATOR).orEmpty() intent.getParcelableArrayExtra(EXTRA_MEDIA)?.toTypedArray(ParcelableMedia.CREATOR).orEmpty()
} }
private val currentFragment: MediaViewerFragment? get() {
val viewPager = findViewPager()
val adapter = viewPager.adapter
val currentItem = viewPager.currentItem
if (currentItem < 0 || currentItem >= adapter.count) return null
return adapter.instantiateItem(viewPager, currentItem) as? MediaViewerFragment
}
override val shouldApplyWindowBackground: Boolean = false override val shouldApplyWindowBackground: Boolean = false
override val controlBarHeight: Int override val controlBarHeight: Int
@ -114,7 +127,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
val actionBar = supportActionBar val actionBar = supportActionBar
if (actionBar != null && !hideOffsetNotSupported) { if (actionBar != null && !hideOffsetNotSupported) {
if (actionBar is WindowDecorActionBar) { if (actionBar is WindowDecorActionBar) {
val toolbar = actionBar.containerView val toolbar = actionBar.decorToolbar.viewGroup
toolbar.alpha = offset toolbar.alpha = offset
} }
try { try {
@ -157,7 +170,6 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
} }
} }
override fun onContentChanged() { override fun onContentChanged() {
super.onContentChanged() super.onContentChanged()
mediaViewerHelper.onContentChanged() mediaViewerHelper.onContentChanged()
@ -171,11 +183,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
override fun onPrepareOptionsMenu(menu: Menu): Boolean { override fun onPrepareOptionsMenu(menu: Menu): Boolean {
super.onPrepareOptionsMenu(menu) super.onPrepareOptionsMenu(menu)
val viewPager = findViewPager() val obj = currentFragment ?: return false
val adapter = viewPager.adapter
val currentItem = viewPager.currentItem
if (currentItem < 0 || currentItem >= adapter.count) return false
val obj = adapter.instantiateItem(viewPager, currentItem) as? MediaViewerFragment ?: return false
if (obj.isDetached || obj.host == null) return false if (obj.isDetached || obj.host == null) return false
val running = obj.isMediaLoading val running = obj.isMediaLoading
val downloaded = obj.isMediaLoaded val downloaded = obj.isMediaLoaded
@ -277,12 +285,23 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
} }
override fun isBarShowing(): Boolean { override fun isBarShowing(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return FLAG_SYSTEM_UI_HIDE_BARS !in window.decorView.systemUiVisibility
}
return controlBarOffset >= 1 return controlBarOffset >= 1
} }
override fun setBarVisibility(visible: Boolean) { override fun setBarVisibility(visible: Boolean) {
if (isBarShowing == visible) return if (isBarShowing == visible) return
setControlBarVisibleAnimate(visible) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (visible) {
window.decorView.removeSystemUiVisibility(FLAG_SYSTEM_UI_HIDE_BARS)
} else {
window.decorView.addSystemUiVisibility(FLAG_SYSTEM_UI_HIDE_BARS)
}
} else {
setControlBarVisibleAnimate(visible)
}
} }
override fun getDownloader(): MediaDownloader { override fun getDownloader(): MediaDownloader {
@ -361,17 +380,18 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
override fun onSwipeStateChanged(state: Int) { override fun onSwipeStateChanged(state: Int) {
supportActionBar?.let { supportActionBar?.let {
val barShowing = controlBarOffset >= 1
if (state == ViewDragHelper.STATE_IDLE) { if (state == ViewDragHelper.STATE_IDLE) {
if (wasBarShowing == 1 && !isBarShowing) { if (wasBarShowing == 1 && !barShowing) {
setBarVisibility(true) setControlBarVisibleAnimate(true)
} }
wasBarShowing = 0 wasBarShowing = 0
} else { } else {
if (wasBarShowing == 0) { if (wasBarShowing == 0) {
wasBarShowing = if (isBarShowing) 1 else -1 wasBarShowing = if (barShowing) 1 else -1
} }
if (isBarShowing) { if (barShowing) {
setBarVisibility(false) setControlBarVisibleAnimate(false)
} }
} }
} }
@ -381,7 +401,6 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
controlBarShowHideHelper.setControlBarVisibleAnimate(visible, listener) controlBarShowHideHelper.setControlBarVisibleAnimate(visible, listener)
} }
override fun onFitSystemWindows(insets: Rect) { override fun onFitSystemWindows(insets: Rect) {
super.onFitSystemWindows(insets) super.onFitSystemWindows(insets)
val adapter = viewPager.adapter val adapter = viewPager.adapter
@ -531,6 +550,10 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
private val REQUEST_SHARE_MEDIA = 201 private val REQUEST_SHARE_MEDIA = 201
private val REQUEST_PERMISSION_SAVE_MEDIA = 202 private val REQUEST_PERMISSION_SAVE_MEDIA = 202
private val REQUEST_PERMISSION_SHARE_MEDIA = 203 private val REQUEST_PERMISSION_SHARE_MEDIA = 203
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
const val FLAG_SYSTEM_UI_HIDE_BARS = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_FULLSCREEN
} }
} }

View File

@ -49,7 +49,8 @@ interface IControlBarActivity {
} }
interface ControlBarAnimationListener { interface ControlBarAnimationListener {
fun onControlBarVisibleAnimationFinish(visible: Boolean) fun onControlBarVisibleAnimationStart(visible: Boolean) {}
fun onControlBarVisibleAnimationFinish(visible: Boolean) {}
} }
fun setControlBarVisibleAnimate(visible: Boolean, listener: ControlBarAnimationListener? = null) { fun setControlBarVisibleAnimate(visible: Boolean, listener: ControlBarAnimationListener? = null) {
@ -71,7 +72,9 @@ interface IControlBarActivity {
} }
animator.interpolator = DecelerateInterpolator() animator.interpolator = DecelerateInterpolator()
animator.addListener(object : AnimatorListener { animator.addListener(object : AnimatorListener {
override fun onAnimationStart(animation: Animator) {} override fun onAnimationStart(animation: Animator) {
listener?.onControlBarVisibleAnimationStart(visible)
}
override fun onAnimationEnd(animation: Animator) { override fun onAnimationEnd(animation: Animator) {
controlAnimationDirection = 0 controlAnimationDirection = 0

View File

@ -62,6 +62,14 @@ fun View.getLocationInWindow(rect: Rect) {
rect.set(tempLocation[0], tempLocation[1], tempLocation[0] + width, tempLocation[1] + height) rect.set(tempLocation[0], tempLocation[1], tempLocation[0] + width, tempLocation[1] + height)
} }
fun View.addSystemUiVisibility(systemUiVisibility: Int) {
this.systemUiVisibility = this.systemUiVisibility or systemUiVisibility
}
fun View.removeSystemUiVisibility(systemUiVisibility: Int) {
this.systemUiVisibility = this.systemUiVisibility and systemUiVisibility.inv()
}
private fun offsetToRoot(view: View, rect: Rect) { private fun offsetToRoot(view: View, rect: Rect) {
var parent = view.parent as? View var parent = view.parent as? View
while (parent != null) { while (parent != null) {

View File

@ -29,6 +29,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.google.android.exoplayer2.* import com.google.android.exoplayer2.*
@ -47,9 +48,11 @@ import kotlinx.android.synthetic.main.layout_media_viewer_video_overlay.*
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.mariotaku.ktextension.contains
import org.mariotaku.mediaviewer.library.MediaViewerFragment import org.mariotaku.mediaviewer.library.MediaViewerFragment
import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.MediaViewerActivity
import org.mariotaku.twidere.annotation.CacheFileType import org.mariotaku.twidere.annotation.CacheFileType
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_POSITION import org.mariotaku.twidere.constant.IntentConstants.EXTRA_POSITION
import org.mariotaku.twidere.extension.model.authorizationHeader import org.mariotaku.twidere.extension.model.authorizationHeader
@ -127,6 +130,8 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
} }
hideProgress() hideProgress()
val activity = activity as? MediaViewerActivity
activity?.setBarVisibility(true)
} }
ExoPlayer.STATE_READY -> { ExoPlayer.STATE_READY -> {
playbackCompleted = playWhenReady playbackCompleted = playWhenReady
@ -170,6 +175,29 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
updateVolume() updateVolume()
} }
playerView.useController = !isControlDisabled playerView.useController = !isControlDisabled
playerView.controllerShowTimeoutMs = 0
playerView.setOnSystemUiVisibilityChangeListener { visibility ->
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return@setOnSystemUiVisibilityChangeListener
val visible = MediaViewerActivity.FLAG_SYSTEM_UI_HIDE_BARS !in
activity.window.decorView.systemUiVisibility
if (visible) {
playerView.showController()
} else {
playerView.hideController()
}
}
playerView.setOnTouchListener { _, event ->
if (event.action != MotionEvent.ACTION_DOWN) return@setOnTouchListener false
val activity = activity as? MediaViewerActivity ?: return@setOnTouchListener false
val visible = !activity.isBarShowing
activity.setBarVisibility(visible)
if (visible) {
playerView.showController()
} else {
playerView.hideController()
}
return@setOnTouchListener true
}
updateVolume() updateVolume()
} }

View File

@ -31,6 +31,7 @@ import com.davemorrissey.labs.subscaleview.decoder.SkiaImageDecoder
import org.mariotaku.mediaviewer.library.CacheDownloadLoader import org.mariotaku.mediaviewer.library.CacheDownloadLoader
import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.MediaViewerActivity
import org.mariotaku.twidere.model.ParcelableMedia import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.TwidereMathUtils import org.mariotaku.twidere.util.TwidereMathUtils
@ -94,6 +95,10 @@ class ImagePageFragment : SubsampleImageViewerFragment() {
imageView.maxScale = resources.displayMetrics.density imageView.maxScale = resources.displayMetrics.density
imageView.setBitmapDecoderClass(PreviewBitmapDecoder::class.java) imageView.setBitmapDecoderClass(PreviewBitmapDecoder::class.java)
imageView.setParallelLoadingEnabled(true) imageView.setParallelLoadingEnabled(true)
imageView.setOnClickListener {
val activity = activity as? MediaViewerActivity ?: return@setOnClickListener
activity.toggleBar()
}
} }
override fun getImageSource(data: CacheDownloadLoader.Result): ImageSource { override fun getImageSource(data: CacheDownloadLoader.Result): ImageSource {

View File

@ -24,6 +24,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:layout_height="?actionBarSize" android:layout_height="?actionBarSize"
android:background="@drawable/bg_viewer_actionbar"
android:clickable="true"> android:clickable="true">
<FrameLayout <FrameLayout