From f7b547b9c792407ccec950871f8f8a4ef3d938ca Mon Sep 17 00:00:00 2001
From: vkay94
Date: Mon, 18 Nov 2019 17:42:02 +0100
Subject: [PATCH 01/11] Huge additions
* Added new YT-Overlay option which is more like official YouTube app
* Updated Demo app for customization tests and comparision between both
options
---
app/build.gradle | 21 +-
app/proguard-rules.pro | 29 +-
app/src/main/AndroidManifest.xml | 18 +-
.../{MainActivity.kt => BaseVideoActivity.kt} | 111 ++----
.../DataAndUtils.kt | 20 +
.../VideoActivityCircle.kt | 94 +++++
.../VideoActivityRipple.kt | 54 +++
.../dialogs/ConfigDialogColors.kt | 87 +++++
.../dialogs/ConfigDialogVarious.kt | 183 ++++++++++
app/src/main/res/anim/in_from_right.xml | 5 +
app/src/main/res/anim/out_to_right.xml | 5 +
.../main/res/layout/activity_video_circle.xml | 35 ++
...ity_main.xml => activity_video_ripple.xml} | 19 +-
app/src/main/res/layout/dialog_colors.xml | 90 +++++
app/src/main/res/layout/dialog_various.xml | 124 +++++++
.../exo_playback_control_view_circle.xml | 126 +++++++
...l => exo_playback_control_view_ripple.xml} | 34 +-
app/src/main/res/values/configdialog.xml | 30 ++
app/src/main/res/values/styles.xml | 2 +-
build.gradle | 7 +-
doubletapplayerview/build.gradle | 21 +-
.../vkay94/dtpv/DoubleTapPlayerView.java | 10 +-
.../vkay94/dtpv/PlayerDoubleTapListener.java | 6 +-
.../dtpv/{ => youtube}/YouTubeDoubleTap.kt | 11 +-
.../vkay94/dtpv/youtube/YouTubeOverlay.kt | 343 ++++++++++++++++++
.../dtpv/youtube/views/CircleClipTapView.kt | 213 +++++++++++
.../src/main/res/layout/yt_overlay_circle.xml | 68 ++++
.../src/main/res/values/yt_overlay_circle.xml | 17 +
28 files changed, 1619 insertions(+), 164 deletions(-)
rename app/src/main/java/com/github/vkay94/doubletapplayerviewexample/{MainActivity.kt => BaseVideoActivity.kt} (55%)
create mode 100644 app/src/main/java/com/github/vkay94/doubletapplayerviewexample/DataAndUtils.kt
create mode 100644 app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt
create mode 100644 app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt
create mode 100644 app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogColors.kt
create mode 100644 app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogVarious.kt
create mode 100644 app/src/main/res/anim/in_from_right.xml
create mode 100644 app/src/main/res/anim/out_to_right.xml
create mode 100644 app/src/main/res/layout/activity_video_circle.xml
rename app/src/main/res/layout/{activity_main.xml => activity_video_ripple.xml} (56%)
create mode 100644 app/src/main/res/layout/dialog_colors.xml
create mode 100644 app/src/main/res/layout/dialog_various.xml
create mode 100644 app/src/main/res/layout/exo_playback_control_view_circle.xml
rename app/src/main/res/layout/{exo_playback_control_view.xml => exo_playback_control_view_ripple.xml} (87%)
create mode 100644 app/src/main/res/values/configdialog.xml
rename doubletapplayerview/src/main/java/com/github/vkay94/dtpv/{ => youtube}/YouTubeDoubleTap.kt (96%)
create mode 100644 doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
create mode 100644 doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/views/CircleClipTapView.kt
create mode 100644 doubletapplayerview/src/main/res/layout/yt_overlay_circle.xml
create mode 100644 doubletapplayerview/src/main/res/values/yt_overlay_circle.xml
diff --git a/app/build.gradle b/app/build.gradle
index 00c816f..324e876 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,18 +6,19 @@ apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
- buildToolsVersion "29.0.2"
+ buildToolsVersion '29.0.2'
defaultConfig {
applicationId "com.github.vkay94.doubletapplayerviewexample"
- minSdkVersion 16
+ minSdkVersion 21
targetSdkVersion 29
- versionCode 60
- versionName "0.6.0"
+ versionCode 70
+ versionName "0.7.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
+ shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
@@ -30,16 +31,18 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation 'androidx.core:core-ktx:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
-
- implementation "com.google.android.exoplayer:exoplayer-core:2.10.6"
- implementation "com.google.android.exoplayer:exoplayer-ui:2.10.6"
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
+ // ExoPlayer2
+ implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
+ implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version"
+
+ implementation 'com.github.QuadFlask:colorpicker:0.0.15'
implementation project(path: ':doubletapplayerview')
}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index f1b4245..831db07 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -1,21 +1,8 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
+-assumenosideeffects class android.util.Log {
+ public static boolean isLoggable(java.lang.String, int);
+ public static int v(...);
+ public static int i(...);
+ public static int w(...);
+ public static int d(...);
+ public static int e(...);
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f0ed6b6..6610253 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,16 +6,24 @@
-
+ tools:ignore="AllowBackup,GoogleAppIndexingWarning">
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/MainActivity.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt
similarity index 55%
rename from app/src/main/java/com/github/vkay94/doubletapplayerviewexample/MainActivity.kt
rename to app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt
index cc5bd20..64b9da0 100644
--- a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/MainActivity.kt
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt
@@ -1,13 +1,13 @@
package com.github.vkay94.doubletapplayerviewexample
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Intent
import android.net.Uri
import android.os.Bundle
-import android.util.Log
import android.view.WindowManager
-import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import com.github.vkay94.dtpv.PlayerDoubleTapListener
-import com.github.vkay94.dtpv.SeekListener
+import com.github.vkay94.dtpv.DoubleTapPlayerView
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.source.ExtractorMediaSource
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection
@@ -17,13 +17,14 @@ import com.google.android.exoplayer2.upstream.BandwidthMeter
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util
-import kotlinx.android.synthetic.main.activity_main.*
-import kotlinx.android.synthetic.main.exo_playback_control_view.*
+import kotlinx.android.synthetic.main.activity_video_circle.*
-class MainActivity : AppCompatActivity(), PlayerDoubleTapListener {
- private val TAG = ".MainActivity"
- private var player: SimpleExoPlayer? = null
+@SuppressLint("Registered")
+open class BaseVideoActivity : AppCompatActivity() {
+
+ var videoPlayer: DoubleTapPlayerView? = null
+ var player: SimpleExoPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -31,53 +32,24 @@ class MainActivity : AppCompatActivity(), PlayerDoubleTapListener {
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
- setContentView(R.layout.activity_main)
supportActionBar?.hide()
-
- initializePlayer()
-
- // Add DoubleTap behavior
- initializeDoubleTapPlayerView()
}
- private fun initializeDoubleTapPlayerView() {
- youtubeDoubleTap
- .setPlayer(playerView)
- .setForwardRewindIncrementMs(10000)
- .setSeekListener(object : SeekListener {
- override fun onVideoStartReached() {
- pausePlayer()
- Toast.makeText(this@MainActivity,
- "Video start reached", Toast.LENGTH_SHORT).show()
- }
-
- override fun onVideoEndReached() {
- Toast.makeText(this@MainActivity,
- "Video end reached", Toast.LENGTH_SHORT).show()
- }
- })
-
- playerView.activateDoubleTap(true)
- .setDoubleTapListener(youtubeDoubleTap)
-// .setDoubleTapListener(this)
- .setDoubleTapDelay(500)
-
- btn_ffwd.setOnClickListener {
- youtubeDoubleTap.forward()
- }
-
- btn_rew.setOnClickListener {
- youtubeDoubleTap.rewind()
- }
-
- // Start video
- // Found at: https://gist.github.com/jsturgis/3b19447b304616f18657
+ fun buildMediaSource(mUri: Uri) {
+ val bandwidthMeter = DefaultBandwidthMeter()
+ val dataSourceFactory = DefaultDataSourceFactory(
+ this@BaseVideoActivity,
+ Util.getUserAgent(this@BaseVideoActivity, resources.getString(R.string.app_name)),
+ bandwidthMeter
+ )
+ val videoSource = ExtractorMediaSource.Factory(dataSourceFactory)
+ .createMediaSource(mUri)
- val videoUrl = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
- buildMediaSource(Uri.parse(videoUrl))
+ player?.prepare(videoSource)
+ player?.playWhenReady = true
}
- private fun initializePlayer() {
+ fun initializePlayer() {
if (player == null) {
val loadControl: LoadControl = DefaultLoadControl.Builder()
.setBufferDurationsMs(
@@ -105,36 +77,22 @@ class MainActivity : AppCompatActivity(), PlayerDoubleTapListener {
}
}
- private fun buildMediaSource(mUri: Uri) {
- val bandwidthMeter = DefaultBandwidthMeter()
- val dataSourceFactory = DefaultDataSourceFactory(
- this@MainActivity,
- Util.getUserAgent(this@MainActivity, resources.getString(R.string.app_name)),
- bandwidthMeter
- )
- val videoSource = ExtractorMediaSource.Factory(dataSourceFactory)
- .createMediaSource(mUri)
-
- player?.prepare(videoSource)
- player?.playWhenReady = true
- }
-
// Player Lifecycle
- private fun releasePlayer() {
+ fun releasePlayer() {
if (player != null) {
player?.release()
player = null
}
}
- private fun pausePlayer() {
+ fun pausePlayer() {
if (player != null) {
player?.playWhenReady = false
player?.playbackState
}
}
- private fun resumePlayer() {
+ fun resumePlayer() {
if (player != null) {
player?.playWhenReady = true
player?.playbackState
@@ -161,21 +119,8 @@ class MainActivity : AppCompatActivity(), PlayerDoubleTapListener {
}
}
- // For debugging purposes
-
- override fun onDoubleTapStarted(posX: Float, posY: Float) {
- Log.d(TAG, "onDoubleTapStarted")
- }
-
- override fun onDoubleTapProgressDown(posX: Float, posY: Float) {
- Log.d(TAG, "onDoubleTapProgressDown")
- }
-
- override fun onDoubleTapProgressUp(posX: Float, posY: Float) {
- Log.d(TAG, "onDoubleTapProgressUp")
- }
-
- override fun onDoubleTapFinished() {
- Log.d(TAG, "onDoubleTapFinished")
+ companion object {
+ fun newIntent(context: Context, activity: Class): Intent =
+ Intent(context, activity)
}
}
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/DataAndUtils.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/DataAndUtils.kt
new file mode 100644
index 0000000..15560aa
--- /dev/null
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/DataAndUtils.kt
@@ -0,0 +1,20 @@
+package com.github.vkay94.doubletapplayerviewexample
+
+import android.content.Context
+
+object DataAndUtils {
+
+ /**
+ * This is a selected list of sample videos for demonstration
+ * Found at: https://gist.github.com/jsturgis/3b19447b304616f18657
+ */
+ val videoList = listOf(
+ "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
+ )
+
+ fun dpToPx(context: Context, dp: Float) =
+ dp * context.resources.displayMetrics.density
+
+ fun pxToDp(context: Context, px: Float) =
+ px / context.resources.displayMetrics.density
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt
new file mode 100644
index 0000000..b45d851
--- /dev/null
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt
@@ -0,0 +1,94 @@
+package com.github.vkay94.doubletapplayerviewexample
+
+import android.net.Uri
+import android.os.Bundle
+import android.widget.Toast
+import com.github.vkay94.doubletapplayerviewexample.dialogs.ConfigDialogColors
+import com.github.vkay94.doubletapplayerviewexample.dialogs.ConfigDialogVarious
+import com.github.vkay94.dtpv.SeekListener
+import kotlinx.android.synthetic.main.activity_video_circle.*
+import kotlinx.android.synthetic.main.exo_playback_control_view_circle.*
+
+
+class VideoActivityCircle : BaseVideoActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_video_circle)
+
+ this.videoPlayer = playerView
+ initializePlayer()
+
+ // Add DoubleTap behavior
+ initializeDoubleTapPlayerView()
+ initializeConfigButtons()
+
+ btn_switch_mode.setOnClickListener {
+ startActivity(newIntent(this@VideoActivityCircle, VideoActivityRipple::class.java))
+ finish()
+ }
+ }
+
+ private fun initializeDoubleTapPlayerView() {
+ youtubeDoubleTap
+ .setSeekListener(object : SeekListener {
+ override fun onVideoStartReached() {
+ pausePlayer()
+ Toast.makeText(this@VideoActivityCircle,
+ "Video start reached", Toast.LENGTH_SHORT
+ ).show()
+ }
+
+ override fun onVideoEndReached() {
+ Toast.makeText(this@VideoActivityCircle,
+ "Video end reached", Toast.LENGTH_SHORT
+ ).show()
+ }
+ })
+
+ playerView.activateDoubleTap(true)
+ .setDoubleTapDelay(650)
+ .setDoubleTapListener(youtubeDoubleTap)
+
+ val videoUrl = DataAndUtils.videoList.first()
+ buildMediaSource(Uri.parse(videoUrl))
+ }
+
+ private fun initializeConfigButtons() {
+ btn_colors.setOnClickListener {
+ ConfigDialogColors.newInstance(object : ConfigDialogColors.ColorChangedListener {
+ override fun onTapColorChanged(newColor: Int) {
+ youtubeDoubleTap.tapCircleColor = newColor
+ }
+
+ override fun onBackgroundColorChanged(newColor: Int) {
+ youtubeDoubleTap.circleBackgroundColor = newColor
+ }
+
+ }, youtubeDoubleTap.tapCircleColor, youtubeDoubleTap.circleBackgroundColor)
+ .show(supportFragmentManager, "COLORS DIALOG")
+ }
+
+ btn_various.setOnClickListener {
+ val arcSizeInDp = DataAndUtils.pxToDp(this, youtubeDoubleTap.arcSize)
+
+ ConfigDialogVarious.newInstance(object : ConfigDialogVarious.VariousChangedListener {
+ override fun onDoubleTapDurationChanged(newDuration: Long) {
+ playerView.setDoubleTapDelay(newDuration.toInt())
+ }
+
+ override fun onYoutubeAnimationDurationChanged(newDuration: Long) {
+ youtubeDoubleTap.animationDuration = newDuration
+ }
+
+ override fun onArcSizeChanged(newDimen: Int) {
+ youtubeDoubleTap.arcSize =
+ DataAndUtils.dpToPx(this@VideoActivityCircle, newDimen.toFloat())
+ }
+
+ }, playerView.doubleTapDelay.toInt(), youtubeDoubleTap.animationDuration.toInt(),
+ arcSizeInDp.toInt())
+ .show(supportFragmentManager, "VARIOUS DIALOG")
+ }
+ }
+}
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt
new file mode 100644
index 0000000..6da4f34
--- /dev/null
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt
@@ -0,0 +1,54 @@
+package com.github.vkay94.doubletapplayerviewexample
+
+import android.net.Uri
+import android.os.Bundle
+import android.widget.Toast
+import com.github.vkay94.dtpv.SeekListener
+import kotlinx.android.synthetic.main.activity_video_ripple.*
+import kotlinx.android.synthetic.main.exo_playback_control_view_ripple.*
+
+class VideoActivityRipple : BaseVideoActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_video_ripple)
+
+ this.videoPlayer = playerView
+ initializePlayer()
+
+ // Add DoubleTap behavior
+ initializeDoubleTapPlayerView()
+
+ btn_switch_mode.setOnClickListener {
+ startActivity(newIntent(this@VideoActivityRipple, VideoActivityCircle::class.java))
+ finish()
+ }
+ }
+
+ private fun initializeDoubleTapPlayerView() {
+ youtubeDoubleTap
+ .setPlayer(playerView)
+ .setForwardRewindIncrementMs(10000)
+ .setSeekListener(object : SeekListener {
+ override fun onVideoStartReached() {
+ pausePlayer()
+ Toast.makeText(this@VideoActivityRipple,
+ "Video start reached", Toast.LENGTH_SHORT
+ ).show()
+ }
+
+ override fun onVideoEndReached() {
+ Toast.makeText(this@VideoActivityRipple,
+ "Video end reached", Toast.LENGTH_SHORT
+ ).show()
+ }
+ })
+
+ playerView.activateDoubleTap(true)
+ .setDoubleTapDelay(700)
+ .setDoubleTapListener(youtubeDoubleTap)
+
+ val videoUrl = DataAndUtils.videoList.first()
+ buildMediaSource(Uri.parse(videoUrl))
+ }
+}
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogColors.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogColors.kt
new file mode 100644
index 0000000..87bb78f
--- /dev/null
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogColors.kt
@@ -0,0 +1,87 @@
+package com.github.vkay94.doubletapplayerviewexample.dialogs
+
+import android.os.Bundle
+import android.view.*
+import androidx.fragment.app.DialogFragment
+import com.github.vkay94.doubletapplayerviewexample.R
+import kotlinx.android.synthetic.main.dialog_colors.*
+
+class ConfigDialogColors : DialogFragment() {
+
+ lateinit var listener: ColorChangedListener
+ var tapColor: Int = -1
+ var backgroundColor: Int = -1
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setStyle(STYLE_NORMAL,
+ R.style.FullScreenPlayerSettingsDialogStyle
+ )
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.dialog_colors, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ activity?.let {
+ // Tap circle color
+ v_tap_alpha_slider.setColor(tapColor)
+
+ tap_color_picker_view.setInitialColor(tapColor, false)
+ tap_color_picker_view.addOnColorChangedListener {selectedColor ->
+ listener.onTapColorChanged(selectedColor)
+ }
+
+ // Background circle color
+ v_background_alpha_slider.setColor(backgroundColor)
+
+ background_color_picker_view.setInitialColor(backgroundColor, false)
+ background_color_picker_view.addOnColorChangedListener {selectedColor ->
+ listener.onBackgroundColorChanged(selectedColor)
+ }
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ val dialog = dialog
+ if (dialog != null) {
+
+ dialog.window?.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+ dialog.window?.setDimAmount(0.50f)
+
+ val metrics = context!!.resources.displayMetrics
+ val widthRatio =
+ resources.getInteger(R.integer.playersettings_dialog_width_ratio).toDouble() / 100
+ val width = (metrics.widthPixels * widthRatio).toInt()
+
+ // W, H
+ dialog.window?.setLayout(width, ViewGroup.LayoutParams.MATCH_PARENT)
+ dialog.window?.setGravity(Gravity.END)
+ }
+ }
+
+ interface ColorChangedListener {
+ fun onTapColorChanged(newColor: Int)
+ fun onBackgroundColorChanged(newColor: Int)
+ }
+
+ companion object {
+
+ val TAG = ConfigDialogColors::class.java.simpleName
+
+ fun newInstance(listener: ColorChangedListener, tapColor: Int, backgroundColor: Int): ConfigDialogColors {
+ return ConfigDialogColors().apply {
+ this.listener = listener
+ this.tapColor = tapColor
+ this.backgroundColor = backgroundColor
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogVarious.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogVarious.kt
new file mode 100644
index 0000000..aaa9dfd
--- /dev/null
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/dialogs/ConfigDialogVarious.kt
@@ -0,0 +1,183 @@
+package com.github.vkay94.doubletapplayerviewexample.dialogs
+
+import android.os.Bundle
+import android.view.*
+import android.widget.SeekBar
+import android.widget.TextView
+import androidx.appcompat.widget.AppCompatSeekBar
+import androidx.fragment.app.DialogFragment
+import com.github.vkay94.doubletapplayerviewexample.R
+import kotlinx.android.synthetic.main.dialog_various.*
+
+class ConfigDialogVarious : DialogFragment() {
+
+ lateinit var listener: VariousChangedListener
+ val minDoubleTapDuration = 500
+ val minAnimationDuration = 500
+ val minArcSize = 0
+
+ val maxDoubleTapDuration = 2000
+ val maxAnimationDuration = 2500
+ val maxArcSize = 200
+
+ val durationSteps = 25
+ val arcSteps = 5
+
+ var currentDoubleTapDuration: Int = 500
+ var currentYouTubeAnimationDuration: Int = 650
+ var currentArcSize = 50
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setStyle(STYLE_NORMAL,
+ R.style.FullScreenPlayerSettingsDialogStyle
+ )
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.dialog_various, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ activity?.let {
+ initializeDurationSeekBar(
+ seekbar_double_tap_duration,
+ tv_double_tap_duration,
+ maxDoubleTapDuration,
+ minDoubleTapDuration,
+ currentDoubleTapDuration
+ ) {
+ listener.onDoubleTapDurationChanged(it.toLong())
+ }
+
+ initializeDurationSeekBar(
+ seekbar_youtube_animation_duration,
+ tv_youtube_animation_duration,
+ maxAnimationDuration,
+ minAnimationDuration,
+ currentYouTubeAnimationDuration
+ ) {
+ listener.onYoutubeAnimationDurationChanged(it.toLong())
+ }
+
+ initializeDimensSeekBar(
+ seekbar_arc_size,
+ tv_arc_size,
+ maxArcSize,
+ minArcSize,
+ currentArcSize
+ ) {
+ listener.onArcSizeChanged(it)
+ }
+ }
+ }
+
+ private fun initializeDurationSeekBar(seekBar: AppCompatSeekBar? = null, textView: TextView? = null,
+ maxValue: Int = 0, minValue: Int = 0, currentValue: Int = 0,
+ progressChanged: (progress: Int) -> Unit) {
+
+ val textInitial = "$currentValue ms"
+ textView?.text = textInitial
+
+ seekBar?.apply {
+ max = (maxValue - minValue) / durationSteps
+ progress = (currentValue - minValue) / durationSteps
+ setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+ val value = minValue + (progress * durationSteps)
+ val text = "$value ms"
+ textView?.text = text
+
+ progressChanged(value)
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {
+ // Do nothing
+ }
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ // Do nothing
+ }
+
+ })
+ }
+ }
+
+ private fun initializeDimensSeekBar(seekBar: AppCompatSeekBar? = null, textView: TextView? = null,
+ maxValue: Int = 0, minValue: Int = 0, currentValue: Int = 0,
+ progressChanged: (progress: Int) -> Unit) {
+
+ val textInitial = "$currentValue dp"
+ textView?.text = textInitial
+
+ seekBar?.apply {
+ max = (maxValue - minValue) / arcSteps
+ progress = (currentValue - minValue) / arcSteps
+ setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+ val value = minValue + (progress * arcSteps)
+ val text = "$value dp"
+ textView?.text = text
+
+ progressChanged(value)
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {
+ // Do nothing
+ }
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ // Do nothing
+ }
+
+ })
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ val dialog = dialog
+ if (dialog != null) {
+
+ dialog.window?.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+ dialog.window?.setDimAmount(0.50f)
+
+ val metrics = context!!.resources.displayMetrics
+ val widthRatio =
+ resources.getInteger(R.integer.playersettings_dialog_width_ratio).toDouble() / 100
+ val width = (metrics.widthPixels * widthRatio).toInt()
+
+ // W, H
+ dialog.window?.setLayout(width, ViewGroup.LayoutParams.MATCH_PARENT)
+ dialog.window?.setGravity(Gravity.END)
+ }
+ }
+
+ interface VariousChangedListener {
+ fun onDoubleTapDurationChanged(newDuration: Long)
+ fun onYoutubeAnimationDurationChanged(newDuration: Long)
+ fun onArcSizeChanged(newDimen: Int)
+ }
+
+ companion object {
+
+ val TAG = ConfigDialogVarious::class.java.simpleName
+
+ fun newInstance(listener: VariousChangedListener,
+ dtDuration: Int, ytDuration: Int, arcSize: Int
+ ): ConfigDialogVarious {
+ return ConfigDialogVarious().apply {
+ this.listener = listener
+ this.currentDoubleTapDuration = dtDuration
+ this.currentYouTubeAnimationDuration = ytDuration
+ this.currentArcSize = arcSize
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/in_from_right.xml b/app/src/main/res/anim/in_from_right.xml
new file mode 100644
index 0000000..3df112c
--- /dev/null
+++ b/app/src/main/res/anim/in_from_right.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/out_to_right.xml b/app/src/main/res/anim/out_to_right.xml
new file mode 100644
index 0000000..90fb416
--- /dev/null
+++ b/app/src/main/res/anim/out_to_right.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_video_circle.xml b/app/src/main/res/layout/activity_video_circle.xml
new file mode 100644
index 0000000..76f1192
--- /dev/null
+++ b/app/src/main/res/layout/activity_video_circle.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_video_ripple.xml
similarity index 56%
rename from app/src/main/res/layout/activity_main.xml
rename to app/src/main/res/layout/activity_video_ripple.xml
index 6f56c7d..f412acd 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_video_ripple.xml
@@ -1,6 +1,7 @@
@@ -14,12 +15,20 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:use_controller="true" />
+ app:use_controller="true"
+ app:controller_layout_id="@layout/exo_playback_control_view_ripple"
+ tools:visibility="visible" />
-
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:background="@color/dtp_overlay_dim"
+ android:visibility="gone"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:visibility="visible" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_colors.xml b/app/src/main/res/layout/dialog_colors.xml
new file mode 100644
index 0000000..8c2e9e4
--- /dev/null
+++ b/app/src/main/res/layout/dialog_colors.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_various.xml b/app/src/main/res/layout/dialog_various.xml
new file mode 100644
index 0000000..980a9dc
--- /dev/null
+++ b/app/src/main/res/layout/dialog_various.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/exo_playback_control_view_circle.xml b/app/src/main/res/layout/exo_playback_control_view_circle.xml
new file mode 100644
index 0000000..3da44c1
--- /dev/null
+++ b/app/src/main/res/layout/exo_playback_control_view_circle.xml
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/exo_playback_control_view.xml b/app/src/main/res/layout/exo_playback_control_view_ripple.xml
similarity index 87%
rename from app/src/main/res/layout/exo_playback_control_view.xml
rename to app/src/main/res/layout/exo_playback_control_view_ripple.xml
index 249e7d9..31e272a 100644
--- a/app/src/main/res/layout/exo_playback_control_view.xml
+++ b/app/src/main/res/layout/exo_playback_control_view_ripple.xml
@@ -17,14 +17,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/configdialog.xml b/app/src/main/res/values/configdialog.xml
new file mode 100644
index 0000000..6cc442a
--- /dev/null
+++ b/app/src/main/res/values/configdialog.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+ 45
+ 20
+
+ #A8000000
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 5885930..5e404d9 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,7 +1,7 @@
-
diff --git a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeDoubleTap.kt b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeDoubleTap.kt
index 0c121e8..6de8351 100644
--- a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeDoubleTap.kt
+++ b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeDoubleTap.kt
@@ -63,7 +63,7 @@ class YouTubeDoubleTap(context: Context?, attrs: AttributeSet?) : ConstraintLayo
rewindContainer.setOnClickListener {
currentRewindForward += FAST_FORWARD_REWIND_SKIP / 1000
tvRewind.text =
- resources.getQuantityString(R.plurals.dtp_rf_seconds, currentRewindForward, currentRewindForward)
+ resources.getQuantityString(R.plurals.quick_seek_x_second, currentRewindForward, currentRewindForward)
seekToPosition(player?.currentPosition!!.minus(FAST_FORWARD_REWIND_SKIP))
}
@@ -71,7 +71,7 @@ class YouTubeDoubleTap(context: Context?, attrs: AttributeSet?) : ConstraintLayo
forwardContainer.setOnClickListener {
currentRewindForward += FAST_FORWARD_REWIND_SKIP / 1000
tvForward.text =
- resources.getQuantityString(R.plurals.dtp_rf_seconds, currentRewindForward, currentRewindForward)
+ resources.getQuantityString(R.plurals.quick_seek_x_second, currentRewindForward, currentRewindForward)
seekToPosition(player?.currentPosition!!.plus(FAST_FORWARD_REWIND_SKIP))
}
@@ -164,7 +164,7 @@ class YouTubeDoubleTap(context: Context?, attrs: AttributeSet?) : ConstraintLayo
forwardContainer.visibility = View.INVISIBLE
tvRewind.text =
- resources.getQuantityString(R.plurals.dtp_rf_seconds, currentRewindForward, currentRewindForward)
+ resources.getQuantityString(R.plurals.quick_seek_x_second, currentRewindForward, currentRewindForward)
rewindContainer.visibility = View.VISIBLE
rewindAnimation.start()
@@ -177,7 +177,7 @@ class YouTubeDoubleTap(context: Context?, attrs: AttributeSet?) : ConstraintLayo
rewindContainer.visibility = View.INVISIBLE
tvForward.text =
- resources.getQuantityString(R.plurals.dtp_rf_seconds, currentRewindForward, currentRewindForward)
+ resources.getQuantityString(R.plurals.quick_seek_x_second, currentRewindForward, currentRewindForward)
forwardContainer.visibility = View.VISIBLE
forwardAnimation.start()
diff --git a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
index c855c97..b35cf48 100644
--- a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
+++ b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
@@ -20,11 +20,6 @@ import kotlinx.android.synthetic.main.yt_overlay_circle.view.*
* In comparison to [YouTubeDoubleTap] this overlay has the typical YouTube scaling circle
* animation and provides some configurations which can't be accomplished with the regular
* Android Ripple (I didn't find any options in the documentation ...).
- *
- * Be aware that, since this kind of animation calls invalidate() very often, see CircleClapTapView
- * + ValueAnimator, there is more work on the GPU. Depending on the device (especially low end)
- * and ROM, some frame drops can occur. But for my devices, I get the same GPU Profiler picture
- * on the official YouTube app, too.
*/
class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
ConstraintLayout(context, attrs), PlayerDoubleTapListener {
@@ -137,19 +132,27 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
// If the PlayerView is set by XML then call the corresponding setter method
if (playerViewRef != -1)
- setupPlayer((this.parent as View).findViewById(playerViewRef) as DoubleTapPlayerView)
+ setPlayerView((this.parent as View).findViewById(playerViewRef) as DoubleTapPlayerView)
}
/**
* Obligatory call if playerView is not set via XML!
- * Links the DoubleTapPlayerView to this view for performing seekTo-calls
- * and hiding the controller
+ * Links the DoubleTapPlayerView to this view for recognizing the tapped position.
*
* @param playerView PlayerView which triggers the event
*/
- fun setupPlayer(playerView: DoubleTapPlayerView) {
+ fun setPlayerView(playerView: DoubleTapPlayerView) {
this.playerView = playerView
- this.player = playerView.player
+ }
+
+ /**
+ * Obligatory call! Needs to be called whenever the Player changes.
+ * Performs seekTo-calls on the ExoPlayer's Player instance.
+ *
+ * @param player PlayerView which triggers the event
+ */
+ fun setPlayer(player: Player) {
+ this.player = player
}
/*
@@ -210,14 +213,6 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
circle_clip_tap_view.arcSize = value
}
- /**
- * Sets the forward / rewind steps, default: 10 seconds
- */
- fun setForwardRewindIncrementMs(milliseconds: Int): YouTubeOverlay {
- this.fastForwardRewindDuration = milliseconds
- return this
- }
-
// PlayerDoubleTapListener methods
// YouTube behavior: the cases "started", "progressDown" and "finished" aren't handled
// (the overlay does not disappear when the double tap mode is over,
@@ -336,7 +331,7 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
currentRewindForward += fastForwardRewindDuration / 1000
textview_forward.text =
resources.getQuantityString(
- R.plurals.dtp_rf_seconds,
+ R.plurals.quick_seek_x_second,
currentRewindForward,
currentRewindForward
)
@@ -348,7 +343,7 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
currentRewindForward += fastForwardRewindDuration / 1000
textview_rewind.text =
resources.getQuantityString(
- R.plurals.dtp_rf_seconds,
+ R.plurals.quick_seek_x_second,
currentRewindForward,
currentRewindForward
)
From 786251cb3f26df67fe8da26285476209f483e0da Mon Sep 17 00:00:00 2001
From: vkay94
Date: Sat, 23 Nov 2019 16:52:16 +0100
Subject: [PATCH 06/11] YT-DoubleTap: Removed older version which uses standard
Android Ripple
---
app/src/main/AndroidManifest.xml | 11 +-
.../BaseVideoActivity.kt | 2 +-
...ideoActivityCircle.kt => VideoActivity.kt} | 19 +-
.../VideoActivityRipple.kt | 54 ----
...ty_video_circle.xml => activity_video.xml} | 2 +-
.../main/res/layout/activity_video_ripple.xml | 34 ---
.../exo_playback_control_view_ripple.xml | 102 -------
...e.xml => exo_playback_control_view_yt.xml} | 11 -
app/src/main/res/values/strings.xml | 2 +-
.../vkay94/dtpv/youtube/YouTubeDoubleTap.kt | 263 ------------------
.../vkay94/dtpv/youtube/YouTubeOverlay.kt | 4 +-
.../main/res/drawable/yt_forward_ripple.xml | 7 -
.../src/main/res/drawable/yt_forward_view.xml | 13 -
.../main/res/drawable/yt_rewind_ripple.xml | 7 -
.../src/main/res/drawable/yt_rewind_view.xml | 13 -
.../src/main/res/layout/yt_overlay.xml | 36 ++-
.../src/main/res/layout/yt_overlay_circle.xml | 68 -----
.../src/main/res/values-w600dp/dimens.xml | 4 -
.../src/main/res/values/colors.xml | 5 +-
.../src/main/res/values/dimens.xml | 6 -
.../{yt_overlay_circle.xml => yt_overlay.xml} | 4 +-
21 files changed, 33 insertions(+), 634 deletions(-)
rename app/src/main/java/com/github/vkay94/doubletapplayerviewexample/{VideoActivityCircle.kt => VideoActivity.kt} (89%)
delete mode 100644 app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt
rename app/src/main/res/layout/{activity_video_circle.xml => activity_video.xml} (99%)
delete mode 100644 app/src/main/res/layout/activity_video_ripple.xml
delete mode 100644 app/src/main/res/layout/exo_playback_control_view_ripple.xml
rename app/src/main/res/layout/{exo_playback_control_view_circle.xml => exo_playback_control_view_yt.xml} (91%)
delete mode 100644 doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeDoubleTap.kt
delete mode 100644 doubletapplayerview/src/main/res/drawable/yt_forward_ripple.xml
delete mode 100644 doubletapplayerview/src/main/res/drawable/yt_forward_view.xml
delete mode 100644 doubletapplayerview/src/main/res/drawable/yt_rewind_ripple.xml
delete mode 100644 doubletapplayerview/src/main/res/drawable/yt_rewind_view.xml
delete mode 100644 doubletapplayerview/src/main/res/layout/yt_overlay_circle.xml
delete mode 100644 doubletapplayerview/src/main/res/values-w600dp/dimens.xml
delete mode 100644 doubletapplayerview/src/main/res/values/dimens.xml
rename doubletapplayerview/src/main/res/values/{yt_overlay_circle.xml => yt_overlay.xml} (81%)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6610253..1393339 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,16 +13,7 @@
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
-
-
-
-
-
-
-
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt
index 64b9da0..7f213f0 100644
--- a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/BaseVideoActivity.kt
@@ -17,7 +17,7 @@ import com.google.android.exoplayer2.upstream.BandwidthMeter
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util
-import kotlinx.android.synthetic.main.activity_video_circle.*
+import kotlinx.android.synthetic.main.activity_video.*
@SuppressLint("Registered")
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
similarity index 89%
rename from app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt
rename to app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
index 0a4ee78..824b116 100644
--- a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityCircle.kt
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
@@ -8,17 +8,17 @@ import com.github.vkay94.doubletapplayerviewexample.dialogs.ConfigDialogColors
import com.github.vkay94.doubletapplayerviewexample.dialogs.ConfigDialogVarious
import com.github.vkay94.dtpv.SeekListener
import com.github.vkay94.dtpv.youtube.YouTubeOverlay
-import kotlinx.android.synthetic.main.activity_video_circle.*
-import kotlinx.android.synthetic.main.exo_playback_control_view_circle.*
+import kotlinx.android.synthetic.main.activity_video.*
+import kotlinx.android.synthetic.main.exo_playback_control_view_yt.*
-class VideoActivityCircle : BaseVideoActivity() {
+class VideoActivity : BaseVideoActivity() {
private var currentVideoId = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_video_circle)
+ setContentView(R.layout.activity_video)
this.videoPlayer = playerView
initializePlayer()
@@ -29,11 +29,6 @@ class VideoActivityCircle : BaseVideoActivity() {
initializeConfigButtons()
- btn_switch_mode.setOnClickListener {
- startActivity(newIntent(this@VideoActivityCircle, VideoActivityRipple::class.java))
- finish()
- }
-
btn_change_video.setOnClickListener {
releasePlayer()
initializePlayer()
@@ -60,14 +55,14 @@ class VideoActivityCircle : BaseVideoActivity() {
override fun onVideoStartReached() {
pausePlayer()
Toast.makeText(
- this@VideoActivityCircle,
+ this@VideoActivity,
"Video start reached", Toast.LENGTH_SHORT
).show()
}
override fun onVideoEndReached() {
Toast.makeText(
- this@VideoActivityCircle,
+ this@VideoActivity,
"Video end reached", Toast.LENGTH_SHORT
).show()
}
@@ -123,7 +118,7 @@ class VideoActivityCircle : BaseVideoActivity() {
override fun onArcSizeChanged(newDimen: Int) {
youtubeDoubleTap.arcSize =
- DataAndUtils.dpToPx(this@VideoActivityCircle, newDimen.toFloat())
+ DataAndUtils.dpToPx(this@VideoActivity, newDimen.toFloat())
}
}, playerView.doubleTapDelay.toInt(), youtubeDoubleTap.animationDuration.toInt(),
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt
deleted file mode 100644
index 6da4f34..0000000
--- a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivityRipple.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.github.vkay94.doubletapplayerviewexample
-
-import android.net.Uri
-import android.os.Bundle
-import android.widget.Toast
-import com.github.vkay94.dtpv.SeekListener
-import kotlinx.android.synthetic.main.activity_video_ripple.*
-import kotlinx.android.synthetic.main.exo_playback_control_view_ripple.*
-
-class VideoActivityRipple : BaseVideoActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_video_ripple)
-
- this.videoPlayer = playerView
- initializePlayer()
-
- // Add DoubleTap behavior
- initializeDoubleTapPlayerView()
-
- btn_switch_mode.setOnClickListener {
- startActivity(newIntent(this@VideoActivityRipple, VideoActivityCircle::class.java))
- finish()
- }
- }
-
- private fun initializeDoubleTapPlayerView() {
- youtubeDoubleTap
- .setPlayer(playerView)
- .setForwardRewindIncrementMs(10000)
- .setSeekListener(object : SeekListener {
- override fun onVideoStartReached() {
- pausePlayer()
- Toast.makeText(this@VideoActivityRipple,
- "Video start reached", Toast.LENGTH_SHORT
- ).show()
- }
-
- override fun onVideoEndReached() {
- Toast.makeText(this@VideoActivityRipple,
- "Video end reached", Toast.LENGTH_SHORT
- ).show()
- }
- })
-
- playerView.activateDoubleTap(true)
- .setDoubleTapDelay(700)
- .setDoubleTapListener(youtubeDoubleTap)
-
- val videoUrl = DataAndUtils.videoList.first()
- buildMediaSource(Uri.parse(videoUrl))
- }
-}
diff --git a/app/src/main/res/layout/activity_video_circle.xml b/app/src/main/res/layout/activity_video.xml
similarity index 99%
rename from app/src/main/res/layout/activity_video_circle.xml
rename to app/src/main/res/layout/activity_video.xml
index 474bb3b..9b45447 100644
--- a/app/src/main/res/layout/activity_video_circle.xml
+++ b/app/src/main/res/layout/activity_video.xml
@@ -17,7 +17,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:use_controller="true"
- app:controller_layout_id="@layout/exo_playback_control_view_circle"
+ app:controller_layout_id="@layout/exo_playback_control_view_yt"
tools:visibility="visible" />
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/exo_playback_control_view_ripple.xml b/app/src/main/res/layout/exo_playback_control_view_ripple.xml
deleted file mode 100644
index 31e272a..0000000
--- a/app/src/main/res/layout/exo_playback_control_view_ripple.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/exo_playback_control_view_circle.xml b/app/src/main/res/layout/exo_playback_control_view_yt.xml
similarity index 91%
rename from app/src/main/res/layout/exo_playback_control_view_circle.xml
rename to app/src/main/res/layout/exo_playback_control_view_yt.xml
index a1304d8..8c113ed 100644
--- a/app/src/main/res/layout/exo_playback_control_view_circle.xml
+++ b/app/src/main/res/layout/exo_playback_control_view_yt.xml
@@ -50,8 +50,6 @@
android:includeFontPadding="false"
android:paddingStart="0dp"
android:paddingEnd="4dp"
- android:paddingLeft="0dp"
- android:paddingRight="4dp"
android:textColor="@android:color/white"
android:textSize="13sp"
tools:text="12:30" />
@@ -73,9 +71,7 @@
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:paddingStart="4dp"
- android:paddingLeft="4dp"
android:paddingEnd="0dp"
- android:paddingRight="0dp"
android:textColor="@android:color/white"
android:textSize="13sp"
tools:text="29:27" />
@@ -114,13 +110,6 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
-
-
-Download
---------
-Gradle:
+# Sample app
+
+If you would like to test the YouTube overlay, then you can either download the [demo app][demoapp]
+or build it yourself from code. It provides all modifications available.
+
+The sample videos own by *Blender Foundation* and a full list can be found [here][videolist].
+
+# Download
+
+The Gradle dependency is available via [jitpack.io][jitpack].
+To be able to load this library, you have to add the repository to your project's gradle file:
```gradle
allprojects {
@@ -19,59 +27,141 @@ allprojects {
maven { url 'https://jitpack.io' }
}
}
+```
+Then, in your app's directory, you can include it the same way like other libraries:
+
+```gradle
dependencies {
implementation 'com.github.vkay94:DoubleTapPlayerView:0.7.0'
}
```
-Usage
--------------------
-
-**View**
+The minimum API level supported by this library is API 21 (Lollipop 5.0+).
-```xml
-
-```
-**Custom attributes**
+# Getting started
-| Attribute | Description | Type |
-| --------- | ----------- |------|
-| **`yt_ffrDuration`** | Fast forward/rewind skip per tap | `integer` *[time in ms]* |
-| **`yt_animationDuration`** | Speed of the circle scaling / time to expand completely | `integer` *[time in ms]* |
-| **`yt_arcSize`** | Sets the shape, the higher the value the more roundish it becomes | `dimen` |
-| **`yt_tapCircleColor`** | Color of the circle which expands | `color` |
-| **`yt_ffrDuration`** | Background color of the arc shape | `color` |
+In order to start using the YouTube overlay, the easiest way is to include it directly
+into your XML layout, e.g. on top of `DoubleTapPlayerView` or inside ExoPlayer's controller:
-Every attribute can also be get/set by Getter/Setter within code.
-In the demo app you can test different values for these attributes.
+```xml
+
+
+
+
+
+
+```
-**Activity (Kotlin)**
+Then, inside your `Activity` or `Fragment`, you can specify which preparations should be done
+before and after the animation, but at least, you have got to toggle the visibility of the overlay
+and reference the (Simple)ExoPlayer to it:
```kotlin
-youTubeOverlay.apply {
+youtube_overlay.apply {
performListener = object : YouTubeOverlay.PerformListener {
override fun onAnimationStart() {
- // Do UI changes when double tapping starts (e.g. hide controller)
- youtubeDoubleTap.visibility = View.VISIBLE
+ // Do UI changes when circle scaling animation starts (e.g. hide controller views)
+ youtube_overlay.visibility = View.VISIBLE
}
override fun onAnimationEnd() {
- // Do UI changes when double tapping ends (e.g. show controller)
- youtubeDoubleTap.visibility = View.GONE
+ // Do UI changes when circle scaling animation starts (e.g. show controller views)
+ youtube_overlay.visibility = View.GONE
}
}
-}
+}
+
+youtube_overlay.setPlayer(simpleExoPlayer)
```
-For a full example implementation take a look at the [VideoActivity][VideoActivity] in the demo app.
+This way, you have more control about the appearance, for example you could apply a fading animation to it.
+
+---
+
+# API documentation
+
+The following sections provide detailed documentation for the components of the library.
+
+## DoubleTapPlayerView
+
+`DoubleTapPlayerView` is the core of this library. It recognizes specific gestures
+which provides more control for the double tapping gesture.
+An overview about the added methods can be found in the [PlayerDoubleTapListener][PlayerDoubleTapListener] interface.
+
+You can adjust how long the double tap mode remains after the last action,
+the default value is 650 milliseconds.
+
+## YouTubeOverlay
+
+`YouTubeOverlay` is the reason for this library. It provides nearly the
+same experience like the fast forward/rewind feature which is used by YouTube's
+Android app. It is highly modifiable.
+
+### XML attributes
+
+If you add the view to your XML layout you can set some custom attributes
+to customize the view's look and behavior.
+Every attributes value can also be get and set programmatically.
+
+
+| Attribute name | Description | Type |
+| ------------- | ------------| ------|
+| `yt_ffrDuration` | Fast forward/rewind duration skip per tap. The text *xx seconds* will also be changed where xx is `value/1000`. | `int` |
+| `yt_animationDuration` | Speed of the circle scaling / time to expand completely. When this time has passed, YouTubeOverlay's `PerformListener.onAnimationEnd()` will be called. | `int` |
+| `yt_arcSize` | Arc of the background circle. The higher the value the more roundish the shape becomes. | `dimen` |
+| `yt_tapCircleColor` | Color of the scaling circle after tap. | `color` |
+| `yt_backgroundCircleColor` | Color of the background shape. | `color` |
+
+### YouTubeOverlay.PerformListener
+
+This interface listens to the *lifecycle* of the overlay.
+
+**onAnimationStart()** *(obligatory)*
+
+Called when the overlay is not visible and a valid onDoubleTapProgressUp event occurred.
+Visibility of the overlay should be set to VISIBLE within this interface method.
+
+**onAnimationEnd()** *(obligatory)*
+
+Called when the circle animation is finished.
+Visibility of the overlay should be set to GONE within this interface method.
+
+**onDoubleTapStart()**
+
+Called on first valid onDoubleTapProgressUp event.
+Possible use-case: The overlay is still animating/visible but the double tap mode is
+already over (`animationDuration` is greater than `doubleTapDelay`) and you want to
+re-hide some UI elements without interrupting the animation.
+
+**onDoubleTapEnd()**
+
+Called when double tap mode is finished.
+
+### SeekListener
+
+This interface reacts to the events during rewinding/forwarding.
+
+`onVideoStartReached()` is called when the start of the video is reached and
+`onVideoEndReached()` is called when the end of the video is reached.
+[videolist]: https://gist.github.com/jsturgis/3b19447b304616f18657
+[demoapp]: https://
+[jitpack]: https://jitpack.io/#vkay94/DoubleTapPlayerView
[PlayerDoubleTapListener]: https://github.com/vkay94/DoubleTapPlayerView/blob/master/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/PlayerDoubleTapListener.java
[MainActivity]: https://github.com/vkay94/DoubleTapPlayerView/blob/master/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/MainActivity.kt
-[VideoActivity]: https://github.com/vkay94/DoubleTapPlayerView/blob/dev/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
\ No newline at end of file
+[VideoActivity]: https://github.com/vkay94/DoubleTapPlayerView/blob/dev/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
diff --git a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/DoubleTapPlayerView.java b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/DoubleTapPlayerView.java
index 44b1fcc..58096bf 100644
--- a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/DoubleTapPlayerView.java
+++ b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/DoubleTapPlayerView.java
@@ -20,7 +20,7 @@ public final class DoubleTapPlayerView extends PlayerView {
public static final String TAG = ".DoubleTapPlayerView";
public static boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
- private boolean doubleTapActivated = false;
+ private boolean doubleTapActivated = true;
private GestureDetectorCompat mDetector;
From 2ef26da5316157da7e5198087767e45701f1b898 Mon Sep 17 00:00:00 2001
From: vkay94
Date: Tue, 3 Dec 2019 16:42:34 +0100
Subject: [PATCH 10/11] YT-Overlay: Removed listener methods on double tap
start/end
---
README.md | 19 +++-----
.../VideoActivity.kt | 4 +-
.../vkay94/dtpv/youtube/YouTubeOverlay.kt | 43 -------------------
3 files changed, 7 insertions(+), 59 deletions(-)
diff --git a/README.md b/README.md
index 31fd326..2a3c495 100644
--- a/README.md
+++ b/README.md
@@ -10,8 +10,9 @@ Created to handle fast forward/rewind behavior like YouTube.
# Sample app
-If you would like to test the YouTube overlay, then you can either download the [demo app][demoapp]
-or build it yourself from code. It provides all modifications available.
+If you would like to test the YouTube overlay, then you can either download the demo app,
+which can be found under Assets of the release or build it yourself from code.
+It provides all modifications available.
The sample videos own by *Blender Foundation* and a full list can be found [here][videolist].
@@ -86,6 +87,7 @@ youtube_overlay.apply {
}
}
+// Call this method whenever the player is released and recreated
youtube_overlay.setPlayer(simpleExoPlayer)
```
@@ -133,7 +135,7 @@ This interface listens to the *lifecycle* of the overlay.
**onAnimationStart()** *(obligatory)*
-Called when the overlay is not visible and a valid onDoubleTapProgressUp event occurred.
+Called when the overlay is not visible and the first valid double tap event occurred.
Visibility of the overlay should be set to VISIBLE within this interface method.
**onAnimationEnd()** *(obligatory)*
@@ -141,17 +143,6 @@ Visibility of the overlay should be set to VISIBLE within this interface method.
Called when the circle animation is finished.
Visibility of the overlay should be set to GONE within this interface method.
-**onDoubleTapStart()**
-
-Called on first valid onDoubleTapProgressUp event.
-Possible use-case: The overlay is still animating/visible but the double tap mode is
-already over (`animationDuration` is greater than `doubleTapDelay`) and you want to
-re-hide some UI elements without interrupting the animation.
-
-**onDoubleTapEnd()**
-
-Called when double tap mode is finished.
-
### SeekListener
This interface reacts to the events during rewinding/forwarding.
diff --git a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
index 853feb9..21e79ee 100644
--- a/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
+++ b/app/src/main/java/com/github/vkay94/doubletapplayerviewexample/VideoActivity.kt
@@ -69,13 +69,13 @@ class VideoActivity : BaseVideoActivity() {
}
performListener = object : YouTubeOverlay.PerformListener {
override fun onAnimationStart() {
- // Do UI changes when double tapping starts including showing the overlay
+ // Do UI changes when double tapping / animation starts including showing the overlay
playerView?.useController = false
youtubeDoubleTap.visibility = View.VISIBLE
}
override fun onAnimationEnd() {
- // Do UI changes when double tapping ends including hiding the overlay
+ // Do UI changes when double tap animation ends including hiding the overlay
youtubeDoubleTap.visibility = View.GONE
playerView?.useController = true
diff --git a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
index 5be0539..307a817 100644
--- a/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
+++ b/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/youtube/YouTubeOverlay.kt
@@ -45,9 +45,6 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
private var player: Player? = null
private var currentRewindForward = 0
- // Is true when DoubleTapping starts, set it to false on ProgressUp
- private var hasStarted = false
-
init {
LayoutInflater.from(context).inflate(R.layout.yt_overlay, this, true)
@@ -216,18 +213,6 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
circle_clip_tap_view.arcSize = value
}
- override fun onDoubleTapStarted(posX: Float, posY: Float) {
- hasStarted = true
- }
-
- // PlayerDoubleTapListener methods
- // YouTube behavior: the cases "started", "progressDown" and "finished" aren't handled
- // (the overlay does not disappear when the double tap mode is over,
- // ongoing taps simply do not trigger forward/rewind, the animation is finishing
- // separately (you can test it on the official YouTube app with setting
- // animation duration scaling to 5x in the developer options).
- //
- // It disappears when the circle scale animation is finished.
override fun onDoubleTapProgressUp(posX: Float, posY: Float) {
if (DEBUG) Log.d(TAG, "onDoubleTapProgressUp: $posX")
@@ -255,11 +240,6 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
when {
posX < playerView?.width!! * 0.35 -> {
- if (hasStarted) {
- hasStarted = false
- performListener?.onDoubleTapStart()
- }
-
// First time tap or switched
if (rewind_container.visibility != View.VISIBLE) {
currentRewindForward = 0
@@ -278,11 +258,6 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
}
posX > playerView?.width!! * 0.65 -> {
- if (hasStarted) {
- hasStarted = false
- performListener?.onDoubleTapStart()
- }
-
// First time tap or switched
if (forward_container.visibility != View.VISIBLE) {
currentRewindForward = 0
@@ -308,11 +283,6 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
}
}
- override fun onDoubleTapFinished() {
- hasStarted = false
- performListener?.onDoubleTapEnd()
- }
-
/**
* Seeks the video to desired position.
* Calls interface functions when start reached ([SeekListener.onVideoStartReached])
@@ -385,18 +355,5 @@ class YouTubeOverlay(context: Context?, private val attrs: AttributeSet?) :
* Visibility of the overlay should be set to GONE within this interface method.
*/
fun onAnimationEnd()
-
- /**
- * Called on first valid onDoubleTapProgressUp event.
- * Possible use-case: The overlay is still animating/visible but the double tap mode is
- * already over and you want to re-hide some UI elements which were visible because of
- * onDoubleTapEnd (interacting with the UI)
- */
- fun onDoubleTapStart() {}
-
- /**
- * Called when onDoubleTapFinished is called.
- */
- fun onDoubleTapEnd() {}
}
}
From 3f071f98416ce25f29dbf2e1c344d470c7025c76 Mon Sep 17 00:00:00 2001
From: vkay94
Date: Tue, 3 Dec 2019 16:43:37 +0100
Subject: [PATCH 11/11] Update ExoPlayer to 2.10.8 and Release 0.7.0
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index ac96260..31c1aa4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,7 +2,7 @@
buildscript {
ext.kotlin_version = '1.3.50'
- ext.exoplayer_version = '2.10.7'
+ ext.exoplayer_version = '2.10.8'
ext.appcompat_version = '1.1.0'
repositories {