mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-13 22:00:30 +05:30
youtube motion done!
next is exoplayer damn it
This commit is contained in:
parent
f735a69dc2
commit
972d1497a3
37
.idea/deploymentTargetDropDown.xml
generated
Normal file
37
.idea/deploymentTargetDropDown.xml
generated
Normal 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
8
.idea/misc.xml
generated
@ -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" />
|
||||
|
@ -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")
|
||||
|
||||
}
|
@ -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">
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
||||
}
|
||||
}
|
14
app/src/main/java/xyz/btcland/libretube/Player.kt
Normal file
14
app/src/main/java/xyz/btcland/libretube/Player.kt
Normal 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)
|
||||
}
|
||||
}
|
114
app/src/main/java/xyz/btcland/libretube/PlayerFragment.kt
Normal file
114
app/src/main/java/xyz/btcland/libretube/PlayerFragment.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
@ -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 {
|
||||
|
@ -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
|
||||
)
|
||||
|
10
app/src/main/res/drawable/ic_close.xml
Normal file
10
app/src/main/res/drawable/ic_close.xml
Normal 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>
|
10
app/src/main/res/drawable/ic_play.xml
Normal file
10
app/src/main/res/drawable/ic_play.xml
Normal 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>
|
@ -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>
|
96
app/src/main/res/layout/activity_player.xml
Normal file
96
app/src/main/res/layout/activity_player.xml
Normal 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>
|
99
app/src/main/res/layout/fragment_player.xml
Normal file
99
app/src/main/res/layout/fragment_player.xml
Normal 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>
|
37
app/src/main/res/xml/activity_main_scene.xml
Normal file
37
app/src/main/res/xml/activity_main_scene.xml
Normal 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>
|
91
app/src/main/res/xml/activity_player_scene.xml
Normal file
91
app/src/main/res/xml/activity_player_scene.xml
Normal 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>
|
96
app/src/main/res/xml/player_scene.xml
Normal file
96
app/src/main/res/xml/player_scene.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user