youtube motion done!

next is exoplayer damn it
This commit is contained in:
Farbod 2021-12-12 16:08:23 +04:00
parent f735a69dc2
commit 972d1497a3
20 changed files with 796 additions and 32 deletions

37
.idea/deploymentTargetDropDown.xml generated Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="3100ad43a3044300" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-12-12T11:35:38.344385Z" />
<runningDeviceTargetsSelectedWithDialog>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="3100ad43a3044300" />
</Key>
</deviceKey>
</Target>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_5_API_22.avd" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetsSelectedWithDialog>
</component>
</project>

8
.idea/misc.xml generated
View File

@ -3,9 +3,13 @@
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/layout/activity_main.xml" value="0.11911231884057971" />
<entry key="app/src/main/res/layout/fragment_home.xml" value="0.1" />
<entry key="app/src/main/res/drawable/ic_close.xml" value="0.17135416666666667" />
<entry key="app/src/main/res/drawable/ic_play.xml" value="0.17135416666666667" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.1" />
<entry key="app/src/main/res/layout/activity_player.xml" value="0.1" />
<entry key="app/src/main/res/layout/fragment_home.xml" value="0.16" />
<entry key="app/src/main/res/layout/fragment_library.xml" value="0.11956521739130435" />
<entry key="app/src/main/res/layout/fragment_player.xml" value="0.15520833333333334" />
<entry key="app/src/main/res/layout/fragment_subscriptions.xml" value="0.1" />
<entry key="app/src/main/res/layout/trending_row.xml" value="0.33" />
<entry key="app/src/main/res/menu/bottom_menu.xml" value="0.15520833333333334" />

View File

@ -12,7 +12,7 @@ android {
targetSdk 31
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
@ -21,6 +21,7 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@ -46,4 +47,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.squareup.picasso:picasso:2.8'
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.google.android.exoplayer:exoplayer:2.16.1'
implementation("androidx.multidex:multidex:2.0.1")
}

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xyz.btcland.libretube">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@ -9,6 +11,11 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LibreTube">
<activity
android:name=".Player"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
/>
<activity
android:name=".MainActivity"
android:exported="true">

View File

@ -6,9 +6,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
@ -97,8 +95,8 @@ class Home : Fragment() {
val body = response.body!!.string()
println(body)
val gson = GsonBuilder().create()
val itemType = object : TypeToken<List<Trending>>() {}.type
val trendingList = gson.fromJson<List<Trending>>(body, itemType)
val itemType = object : TypeToken<List<Video>>() {}.type
val trendingList = gson.fromJson<List<Video>>(body, itemType)
runOnUiThread {
progressBar.visibility = View.GONE
recyclerView.adapter = TrendingAdapter(trendingList)

View File

@ -2,6 +2,8 @@ package xyz.btcland.libretube
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.FrameLayout
import androidx.fragment.app.Fragment
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
@ -13,5 +15,7 @@ class MainActivity : AppCompatActivity() {
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNav)
val navController = findNavController(R.id.fragment)
bottomNavigationView.setupWithNavController(navController)
}
}

View File

@ -0,0 +1,14 @@
package xyz.btcland.libretube
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class Player : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_player)
val videoId=intent.getStringExtra("videoId")
println(videoId)
}
}

View File

@ -0,0 +1,114 @@
package xyz.btcland.libretube
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.constraintlayout.widget.ConstraintSet
import kotlin.math.abs
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [PlayerFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class PlayerFragment : Fragment() {
// TODO: Rename and change types of parameters
private var videoId: String? = null
private var param2: String? = null
private var lastProgress: Float = 0.toFloat()
private var sId: Int=0
private var eId: Int=0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
videoId = it.getString("videoId")
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_player, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val playerMotionLayout = view.findViewById<SingleViewTouchableMotionLayout>(R.id.playerMotionLayout)
view.findViewById<TextView>(R.id.textTest).text = videoId
playerMotionLayout.addTransitionListener(object: MotionLayout.TransitionListener {
override fun onTransitionStarted(
motionLayout: MotionLayout?,
startId: Int,
endId: Int
) {
}
override fun onTransitionChange(motionLayout: MotionLayout?, startId: Int, endId: Int, progress: Float) {
val mainActivity = activity as MainActivity
val mainMotionLayout = mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout)
mainMotionLayout.progress = abs(progress)
eId=endId
sId=startId
}
override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
println(currentId)
val mainActivity = activity as MainActivity
val mainMotionLayout = mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout)
if (currentId==eId) {
mainMotionLayout.progress = 1.toFloat()
}else if(currentId==sId){
mainMotionLayout.progress = 0.toFloat()
}
}
override fun onTransitionTrigger(
motionLayout: MotionLayout?,
triggerId: Int,
positive: Boolean,
progress: Float
) {
}
})
playerMotionLayout.progress=1.toFloat()
playerMotionLayout.transitionToStart()
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment PlayerFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
PlayerFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}

View File

@ -0,0 +1,115 @@
package xyz.btcland.libretube
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.recyclerview.widget.RecyclerView
/**
*
* Created by Arman Chatikyan on 05 Sep 2018
*
*/
class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeSet? = null) : MotionLayout(context, attributeSet) {
private val viewToDetectTouch by lazy {
findViewById<View>(R.id.main_container) //TODO move to Attributes
}
private val viewRect = Rect()
private var touchStarted = false
private val transitionListenerList = mutableListOf<TransitionListener?>()
init {
addTransitionListener(object : MotionLayout.TransitionListener {
override fun onTransitionStarted(
motionLayout: MotionLayout?,
startId: Int,
endId: Int
) {
}
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
}
override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
touchStarted = false
}
override fun onTransitionTrigger(
motionLayout: MotionLayout?,
triggerId: Int,
positive: Boolean,
progress: Float
) {
}
})
super.setTransitionListener(object : MotionLayout.TransitionListener {
override fun onTransitionStarted(
motionLayout: MotionLayout?,
startId: Int,
endId: Int
) {
}
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
transitionListenerList.filterNotNull()
.forEach { it.onTransitionChange(p0, p1, p2, p3) }
}
override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
transitionListenerList.filterNotNull()
.forEach { it.onTransitionCompleted(p0, p1) }
}
override fun onTransitionTrigger(
motionLayout: MotionLayout?,
triggerId: Int,
positive: Boolean,
progress: Float
) {
}
})
}
override fun setTransitionListener(listener: TransitionListener?) {
addTransitionListener(listener)
}
override fun addTransitionListener(listener: TransitionListener?) {
transitionListenerList += listener
}
private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
transitionToEnd()
return false
}
})
override fun onTouchEvent(event: MotionEvent): Boolean {
//gestureDetector.onTouchEvent(event)
when (event.actionMasked) {
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
touchStarted = false
return super.onTouchEvent(event)
}
}
if (!touchStarted) {
viewToDetectTouch.getHitRect(viewRect)
touchStarted = viewRect.contains(event.x.toInt(), event.y.toInt())
}
return touchStarted && super.onTouchEvent(event)
}
}

View File

@ -1,14 +0,0 @@
package xyz.btcland.libretube
data class Trending(
val url: String,
val title: String,
val thumbnail: String,
val uploaderName: String,
val uploaderUrl:String,
val uploaderAvatar:String,
val uploadedDate: String,
val duration: Int,
val views: Int,
val uploaderVerified: Boolean
)

View File

@ -1,18 +1,21 @@
package xyz.btcland.libretube
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
import java.math.BigDecimal
import java.math.RoundingMode
class TrendingAdapter(private val trendingFeed: List<Trending>): RecyclerView.Adapter<CustomViewHolder>() {
class TrendingAdapter(private val videoFeed: List<Video>): RecyclerView.Adapter<CustomViewHolder>() {
override fun getItemCount(): Int {
return trendingFeed.size
return videoFeed.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
@ -22,17 +25,34 @@ class TrendingAdapter(private val trendingFeed: List<Trending>): RecyclerView.Ad
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val trending = trendingFeed[position]
val trending = videoFeed[position]
holder.v.findViewById<TextView>(R.id.textView_title).text = trending.title
holder.v.findViewById<TextView>(R.id.textView_channel).text = trending.uploaderName +""+ videoViews(trending.views)+""+trending.uploadedDate
val thumbnailImage = holder.v.findViewById<ImageView>(R.id.thumbnail)
val channelImage = holder.v.findViewById<ImageView>(R.id.channel_image)
channelImage.setOnClickListener{
println("channel clicked")
}
Picasso.get().load(trending.thumbnail).into(thumbnailImage)
Picasso.get().load(trending.uploaderAvatar).into(channelImage)
holder.v.setOnClickListener{
//val intent = Intent(holder.v.context, Player::class.java)
//intent.putExtra("videoId",trending.url.replace("/watch?v=",""))
//holder.v.context.startActivity(intent)
var bundle = Bundle()
bundle.putString("videoId",trending.url.replace("/watch?v=",""))
var frag = PlayerFragment()
frag.arguments = bundle
val activity = holder.v.context as AppCompatActivity
activity.supportFragmentManager.beginTransaction()
.add(R.id.container, frag)
.commitNow()
}
}
}
class CustomViewHolder(val v: View): RecyclerView.ViewHolder(v){
init {
}
}
fun videoViews(views: Int): String{
when {

View File

@ -1,6 +1,14 @@
package xyz.btcland.libretube
data class Video(
val id: Int,
val url: String,
val title: String,
val thumbnail: String,
val uploaderName: String,
val uploaderUrl:String,
val uploaderAvatar:String,
val uploadedDate: String,
val duration: Int,
val views: Int,
val uploaderVerified: Boolean
)

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/black"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/black"
android:pathData="M8,5v14l11,-7z"/>
</vector>

View File

@ -1,10 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
app:layoutDescription="@xml/activity_main_scene"
tools:context=".MainActivity"
android:id="@+id/mainMotionLayout"
>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNav"
@ -14,7 +17,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_menu"/>
app:menu="@menu/bottom_menu" />
<fragment
android:id="@+id/fragment"
@ -26,4 +29,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav" />
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="@android:color/transparent"
/>
</androidx.constraintlayout.motion.widget.MotionLayout>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/activity_player_scene"
tools:context=".Player"
android:background="#00ffffff"
>
<ScrollView
android:id="@+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_container">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fuckkkkkkkkkkkkkkkkkkkkkkkkkkkkk"/>
</LinearLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="#10000000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="@id/main_container"
app:layout_constraintStart_toStartOf="@id/main_container"
app:layout_constraintTop_toTopOf="@id/main_container"
/>
<ImageView
android:id="@+id/close_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="@id/main_container"
app:layout_constraintEnd_toEndOf="@id/main_container"
app:layout_constraintTop_toTopOf="@id/main_container"
android:src="@drawable/ic_close"
/>
<ImageView
android:id="@+id/play_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="@+id/close_imageView"
app:layout_constraintEnd_toStartOf="@+id/close_imageView"
app:layout_constraintTop_toTopOf="@+id/close_imageView"
android:src="@drawable/ic_play"
/>
<TextView
android:id="@+id/title_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="12dp"
android:alpha="0"
android:ellipsize="end"
android:maxLines="1"
android:text="This is very very very very long title"
app:layout_constraintBottom_toBottomOf="@+id/play_imageView"
app:layout_constraintEnd_toStartOf="@+id/play_imageView"
app:layout_constraintStart_toEndOf="@+id/player"
app:layout_constraintTop_toTopOf="@+id/play_imageView" />
</androidx.constraintlayout.motion.widget.MotionLayout>

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<xyz.btcland.libretube.SingleViewTouchableMotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/player_scene"
tools:context=".PlayerFragment"
android:background="@android:color/transparent"
android:id="@+id/playerMotionLayout"
>
<ScrollView
android:id="@+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_container"
android:background="@color/white"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fuckkkkkkkkkkkkkkkkkkkkkkkkkkkkk"/>
</LinearLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="350dp"
android:background="#EBFFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="@id/main_container"
app:layout_constraintStart_toStartOf="@id/main_container"
app:layout_constraintTop_toTopOf="@id/main_container"
/>
<ImageView
android:id="@+id/close_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="@id/main_container"
app:layout_constraintEnd_toEndOf="@id/main_container"
app:layout_constraintTop_toTopOf="@id/main_container"
android:src="@drawable/ic_close"
/>
<ImageView
android:id="@+id/play_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:alpha="0"
android:src="@drawable/ic_play"
app:layout_constraintBottom_toBottomOf="@+id/close_imageView"
app:layout_constraintEnd_toStartOf="@+id/close_imageView"
app:layout_constraintTop_toTopOf="@+id/close_imageView" />
<TextView
android:id="@+id/title_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="12dp"
android:alpha="0"
android:ellipsize="end"
android:maxLines="1"
android:text="This is very very very very long title"
app:layout_constraintBottom_toBottomOf="@+id/play_imageView"
app:layout_constraintEnd_toStartOf="@+id/play_imageView"
app:layout_constraintStart_toEndOf="@+id/player"
app:layout_constraintTop_toTopOf="@+id/play_imageView" />
</xyz.btcland.libretube.SingleViewTouchableMotionLayout>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/start"
motion:duration="10"
motion:layoutDuringTransition="honorRequest"
>
<KeyFrameSet>
<KeyAttribute
motion:motionTarget="@+id/bottomNav"
motion:framePosition="0"
android:translationY="0dp" />
<KeyAttribute
motion:motionTarget="@+id/bottomNav"
motion:framePosition="75"
android:translationY="55dp" />
<KeyAttribute
motion:motionTarget="@+id/container"
motion:framePosition="50"
android:scaleY="1" />
<KeyAttribute
motion:motionTarget="@+id/container"
motion:framePosition="100"
android:scaleY="0.86" />
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/start">
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
</ConstraintSet>
</MotionScene>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/start"
motion:duration="1000">
<KeyFrameSet>
<KeyAttribute
motion:motionTarget="@+id/close_imageView"
motion:framePosition="90"
android:alpha="0" />
<KeyAttribute
motion:motionTarget="@+id/play_imageView"
motion:framePosition="90"
android:alpha="0" />
<KeyAttribute
motion:motionTarget="@+id/title_textView"
motion:framePosition="95"
android:alpha="0" />
</KeyFrameSet>
<OnSwipe
motion:touchAnchorId="@+id/main_container"
motion:dragDirection="dragDown"
motion:touchAnchorSide="bottom" />
</Transition>
<ConstraintSet android:id="@+id/start">
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/scrollView2"
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp"
android:layout_height="1dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toBottomOf="@+id/main_container"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintVertical_bias="1.0" />
<Constraint
android:id="@+id/main_container"
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="54dp"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintVertical_bias="1.0" />
<Constraint
android:id="@+id/player"
android:layout_width="100dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="@id/main_container"
motion:layout_constraintTop_toTopOf="@id/main_container"
motion:layout_constraintStart_toStartOf="@id/main_container" />
<Constraint
android:id="@+id/close_imageView"
motion:layout_constraintEnd_toEndOf="@id/main_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@id/main_container"
android:layout_marginEnd="16dp"
android:alpha="1"
motion:layout_constraintTop_toTopOf="@id/main_container" />
<Constraint
android:id="@+id/play_imageView"
motion:layout_constraintEnd_toStartOf="@+id/close_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@+id/close_imageView"
android:layout_marginEnd="24dp"
android:alpha="1"
motion:layout_constraintTop_toTopOf="@+id/close_imageView" />
<Constraint
android:id="@+id/title_textView"
motion:layout_constraintEnd_toStartOf="@+id/play_imageView"
motion:layout_constraintStart_toEndOf="@+id/player"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@+id/play_imageView"
android:layout_marginEnd="12dp"
android:alpha="1"
android:layout_marginStart="8dp"
motion:layout_constraintTop_toTopOf="@+id/play_imageView" />
</ConstraintSet>
</MotionScene>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/start"
motion:duration="10"
motion:motionInterpolator="easeInOut"
>
<KeyFrameSet>
<KeyAttribute
motion:motionTarget="@+id/close_imageView"
motion:framePosition="90"
android:alpha="0" />
<KeyAttribute
motion:motionTarget="@+id/play_imageView"
motion:framePosition="90"
android:alpha="0" />
<KeyAttribute
motion:motionTarget="@+id/title_textView"
motion:framePosition="95"
android:alpha="0" />
</KeyFrameSet>
<OnSwipe
motion:touchAnchorId="@+id/main_container"
motion:dragDirection="dragDown"
motion:touchAnchorSide="bottom"
motion:maxAcceleration="40"
motion:dragScale="6"
/>
</Transition>
<ConstraintSet android:id="@+id/start">
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/scrollView2"
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp"
android:layout_height="1dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toBottomOf="@+id/main_container"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintVertical_bias="1.0" />
<Constraint
android:id="@+id/main_container"
motion:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="54dp"
motion:layout_constraintHorizontal_bias="0.5"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintVertical_bias="1.0" />
<Constraint
android:id="@+id/player"
android:layout_width="100dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="@id/main_container"
motion:layout_constraintTop_toTopOf="@id/main_container"
motion:layout_constraintStart_toStartOf="@id/main_container" />
<Constraint
android:id="@+id/close_imageView"
motion:layout_constraintEnd_toEndOf="@id/main_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@id/main_container"
android:layout_marginEnd="16dp"
android:alpha="1"
motion:layout_constraintTop_toTopOf="@id/main_container" />
<Constraint
android:id="@+id/play_imageView"
motion:layout_constraintEnd_toStartOf="@+id/close_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@+id/close_imageView"
android:layout_marginEnd="24dp"
android:alpha="1"
motion:layout_constraintTop_toTopOf="@+id/close_imageView" />
<Constraint
android:id="@+id/title_textView"
motion:layout_constraintEnd_toStartOf="@+id/play_imageView"
motion:layout_constraintStart_toEndOf="@+id/player"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@+id/play_imageView"
android:layout_marginEnd="12dp"
android:alpha="1"
android:layout_marginStart="8dp"
motion:layout_constraintTop_toTopOf="@+id/play_imageView" />
</ConstraintSet>
</MotionScene>