mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-25 02:14:32 +01:00
Added Gradients in App Ui & Added Download All Tracks Functionality
This commit is contained in:
parent
735f7c270e
commit
0ce929df9b
@ -36,6 +36,10 @@
|
|||||||
android:name="com.spotify.sdk.android.authentication.LoginActivity"
|
android:name="com.spotify.sdk.android.authentication.LoginActivity"
|
||||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="preloaded_fonts"
|
||||||
|
android:resource="@array/preloaded_fonts" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@ -104,8 +104,8 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
|
|||||||
|
|
||||||
sharedViewModel.uiScope.launch {
|
sharedViewModel.uiScope.launch {
|
||||||
val me = spotifyExtra?.getMe()?.display_name
|
val me = spotifyExtra?.getMe()?.display_name
|
||||||
sharedViewModel.userName.value = me
|
sharedViewModel.userName.value = "Logged in as: $me"
|
||||||
Log.i("Network",me!!)
|
Log.i("Network","Hello, " + me!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedViewModel.userName.observe(this, Observer {
|
sharedViewModel.userName.observe(this, Observer {
|
||||||
|
@ -14,43 +14,49 @@ import kotlinx.coroutines.withContext
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
interface DownloadHelper {
|
interface DownloadHelper {
|
||||||
suspend fun downloadTrack(ytDownloader: YoutubeDownloader?, downloadManager: DownloadManager?, searchQuery:String){
|
suspend fun downloadTrack(
|
||||||
|
ytDownloader: YoutubeDownloader?,
|
||||||
|
downloadManager: DownloadManager?,
|
||||||
|
searchQuery: String
|
||||||
|
) {
|
||||||
|
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO) {
|
||||||
val downloadIdList = mutableListOf<Int>()
|
val data = YoutubeInterface.search(searchQuery)?.get(0)
|
||||||
val data = YoutubeInterface.search(searchQuery)?.get(0)
|
if (data == null) {
|
||||||
if (data==null){Log.i("DownloadHelper","Youtube Request Failed!")}else{
|
Log.i("DownloadHelper", "Youtube Request Failed!")
|
||||||
|
} else {
|
||||||
|
|
||||||
val video = ytDownloader?.getVideo(data.id)
|
val video = ytDownloader?.getVideo(data.id)
|
||||||
//Fetching a Video Object.
|
//Fetching a Video Object.
|
||||||
val details = video?.details()
|
val details = video?.details()
|
||||||
|
try{
|
||||||
|
val format: Format =
|
||||||
|
video?.findAudioWithQuality(AudioQuality.medium)?.get(0) as Format
|
||||||
|
val audioUrl = format.url()
|
||||||
|
Log.i("DHelper Link Found", audioUrl)
|
||||||
|
if (audioUrl != null) {
|
||||||
|
downloadFile(audioUrl, downloadManager, details!!.title())
|
||||||
|
} else {
|
||||||
|
Log.i("YT audio url is null", format.toString())
|
||||||
|
}
|
||||||
|
}catch (e:ArrayIndexOutOfBoundsException){
|
||||||
|
Log.i("Catch",e.toString())
|
||||||
|
}
|
||||||
|
|
||||||
val format:Format = video?.findAudioWithQuality(AudioQuality.low)?.get(0) as Format
|
|
||||||
|
|
||||||
val audioUrl = format.url()
|
|
||||||
|
|
||||||
if (audioUrl != null) {
|
|
||||||
downloadFile(audioUrl,downloadManager,details!!.title())
|
|
||||||
Log.i("DHelper Start Download", audioUrl)
|
|
||||||
}else{Log.i("YT audio url is null", format.toString())}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Library Inbuilt function to Save File (Need Scoped Storage Implementation)
|
|
||||||
// val file: File = video.download( format , outputDir)
|
|
||||||
}
|
}
|
||||||
//@data = 1st object from YT query.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloading Using Android Download Manager
|
* Downloading Using Android Download Manager
|
||||||
* */
|
* */
|
||||||
suspend fun downloadFile(url: String, downloadManager: DownloadManager?,title:String){
|
suspend fun downloadFile(url: String, downloadManager: DownloadManager?, title: String) {
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO) {
|
||||||
val audioUri = Uri.parse(url)
|
val audioUri = Uri.parse(url)
|
||||||
val outputDir = File.separator + "Spotify-Downloads" +File.separator + "${removeIllegalChars(title)}.mp3"
|
val outputDir =
|
||||||
|
File.separator + "Spotify-Downloads" + File.separator + "${removeIllegalChars(title)}.mp3"
|
||||||
|
|
||||||
val request = DownloadManager.Request(audioUri)
|
val request = DownloadManager.Request(audioUri)
|
||||||
.setAllowedNetworkTypes(
|
.setAllowedNetworkTypes(
|
||||||
@ -60,10 +66,10 @@ interface DownloadHelper {
|
|||||||
.setAllowedOverRoaming(false)
|
.setAllowedOverRoaming(false)
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setDescription("Spotify Downloader Working Up here...")
|
.setDescription("Spotify Downloader Working Up here...")
|
||||||
.setDestinationInExternalPublicDir(Environment.DIRECTORY_MUSIC,outputDir)
|
.setDestinationInExternalPublicDir(Environment.DIRECTORY_MUSIC, outputDir)
|
||||||
.setNotificationVisibility(VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
.setNotificationVisibility(VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||||
downloadManager?.enqueue(request)
|
downloadManager?.enqueue(request)
|
||||||
Log.i("DownloadManager","Download Request Sent")
|
Log.i("DownloadManager", "Download Request Sent")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,51 +61,56 @@ class MainFragment : Fragment(),DownloadHelper {
|
|||||||
adapter.trackList = trackList
|
adapter.trackList = trackList
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
Log.i("Adapter",trackList.size.toString())
|
Log.i("Adapter",trackList.size.toString())
|
||||||
|
binding.btnDownloadAll.setOnClickListener { downloadAllTracks(trackList) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"album" -> {
|
"album" -> {
|
||||||
sharedViewModel.uiScope.launch{
|
sharedViewModel.uiScope.launch{
|
||||||
|
|
||||||
val albumObject = sharedViewModel.getAlbumDetails(link)
|
val albumObject = sharedViewModel.getAlbumDetails(link)
|
||||||
|
// binding.titleView.text = albumObject!!.name
|
||||||
|
// binding.titleView.visibility =View.VISIBLE
|
||||||
|
binding.imageView.visibility =View.VISIBLE
|
||||||
|
binding.btnDownloadAll.visibility =View.VISIBLE
|
||||||
|
val trackList = mutableListOf<Track>()
|
||||||
|
albumObject!!.tracks?.items?.forEach { trackList.add(it as Track) }
|
||||||
|
adapter.totalItems = trackList.size
|
||||||
|
adapter.trackList = trackList
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
|
||||||
binding.titleView.text = albumObject!!.name
|
Log.i("Adapter",trackList.size.toString())
|
||||||
binding.titleView.visibility =View.VISIBLE
|
|
||||||
binding.imageView.visibility =View.VISIBLE
|
|
||||||
|
|
||||||
val trackList = mutableListOf<Track>()
|
bindImage(binding.imageView, albumObject.images[0].url)
|
||||||
albumObject.tracks?.items?.forEach { trackList.add(it as Track) }
|
binding.btnDownloadAll.setOnClickListener { downloadAllTracks(trackList) }
|
||||||
adapter.totalItems = trackList.size
|
|
||||||
adapter.trackList = trackList
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
|
|
||||||
Log.i("Adapter",trackList.size.toString())
|
}
|
||||||
|
|
||||||
bindImage(binding.imageView, albumObject.images[0].url)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"playlist" -> {
|
"playlist" -> {
|
||||||
sharedViewModel.uiScope.launch{
|
sharedViewModel.uiScope.launch{
|
||||||
val playlistObject = sharedViewModel.getPlaylistDetails(link)
|
val playlistObject = sharedViewModel.getPlaylistDetails(link)
|
||||||
|
binding.btnDownloadAll.visibility =View.VISIBLE
|
||||||
binding.titleView.text = "${if(playlistObject!!.name.length > 18){"${playlistObject.name.subSequence(0,17)}..."}else{playlistObject.name}}"
|
|
||||||
binding.titleView.visibility =View.VISIBLE
|
|
||||||
binding.imageView.visibility =View.VISIBLE
|
|
||||||
binding.playlistOwner.visibility =View.VISIBLE
|
|
||||||
binding.playlistOwner.text = "by: ${playlistObject.owner.display_name}"
|
|
||||||
val trackList = mutableListOf<Track>()
|
|
||||||
playlistObject.tracks?.items!!.forEach { trackList.add(it.track) }
|
|
||||||
adapter.trackList = trackList.toList()
|
|
||||||
adapter.totalItems = trackList.size
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
|
|
||||||
Log.i("Adapter",trackList.size.toString())
|
|
||||||
|
|
||||||
|
|
||||||
bindImage(binding.imageView, playlistObject.images[0].url)
|
binding.imageView.visibility =View.VISIBLE
|
||||||
|
// binding.titleView.text = "${if(playlistObject!!.name.length > 18){"${playlistObject.name.subSequence(0,17)}..."}else{playlistObject.name}}"
|
||||||
|
// binding.titleView.visibility =View.VISIBLE
|
||||||
|
// binding.playlistOwner.visibility =View.VISIBLE
|
||||||
|
// binding.playlistOwner.text = "by: ${playlistObject.owner.display_name}"
|
||||||
|
val trackList = mutableListOf<Track>()
|
||||||
|
playlistObject!!.tracks?.items!!.forEach { trackList.add(it.track) }
|
||||||
|
adapter.trackList = trackList.toList()
|
||||||
|
adapter.totalItems = trackList.size
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
|
||||||
|
Log.i("Adapter",trackList.size.toString())
|
||||||
|
|
||||||
|
bindImage(binding.imageView, playlistObject.images[0].url)
|
||||||
|
|
||||||
|
binding.btnDownloadAll.setOnClickListener { downloadAllTracks(trackList) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +132,12 @@ class MainFragment : Fragment(),DownloadHelper {
|
|||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun downloadAllTracks(trackList : List<Track>) {
|
||||||
|
sharedViewModel.uiScope.launch {
|
||||||
|
trackList.forEach { downloadTrack(sharedViewModel.ytDownloader,sharedViewModel.downloadManager,"${it.name} ${it.artists[0].name?:""}") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showToast(message:String){
|
private fun showToast(message:String){
|
||||||
Toast.makeText(context,message,Toast.LENGTH_SHORT).show()
|
Toast.makeText(context,message,Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ object YoutubeInterface {
|
|||||||
private var youtube: YouTube? = null
|
private var youtube: YouTube? = null
|
||||||
private var query:YouTube.Search.List? = null
|
private var query:YouTube.Search.List? = null
|
||||||
var apiKey:String = "AIzaSyDuRmMA_2mF56BjlhhNpa0SIbjMgjjFaEI"
|
var apiKey:String = "AIzaSyDuRmMA_2mF56BjlhhNpa0SIbjMgjjFaEI"
|
||||||
|
var apiKey2:String = "AIzaSyCotyqgqmz5qw4-IH0tiezIrIIDHLI2yNs"
|
||||||
|
|
||||||
var clientID : String = "1040727735015-er2mvvljt45cabkuqimsh3iabqvfpvms.apps.googleusercontent.com"
|
var clientID : String = "1040727735015-er2mvvljt45cabkuqimsh3iabqvfpvms.apps.googleusercontent.com"
|
||||||
|
|
||||||
fun youtubeConnector() {
|
fun youtubeConnector() {
|
||||||
@ -23,14 +25,14 @@ object YoutubeInterface {
|
|||||||
query?.maxResults = 1
|
query?.maxResults = 1
|
||||||
query?.type = "video"
|
query?.type = "video"
|
||||||
query?.fields =
|
query?.fields =
|
||||||
"items(id/kind,id/videoId,snippet/title,snippet/description,snippet/thumbnails/default/url)"
|
"items(id/videoId,snippet/title,snippet/thumbnails/default/url)"
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.i("YC", "Could not initialize: $e")
|
Log.i("YI", "Could not initialize: $e")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun search(keywords: String?): List<VideoItem>? {
|
fun search(keywords: String?): List<VideoItem>? {
|
||||||
Log.i("YC searched for",keywords.toString())
|
Log.i("YI searched for",keywords.toString())
|
||||||
if (youtube == null){youtubeConnector()}
|
if (youtube == null){youtubeConnector()}
|
||||||
query!!.q= keywords
|
query!!.q= keywords
|
||||||
return try {
|
return try {
|
||||||
@ -42,23 +44,25 @@ object YoutubeInterface {
|
|||||||
val item = VideoItem(
|
val item = VideoItem(
|
||||||
id = result.id.videoId,
|
id = result.id.videoId,
|
||||||
title = result.snippet.title,
|
title = result.snippet.title,
|
||||||
description = result.snippet.description,
|
// description = result.snippet.description,
|
||||||
thumbnailUrl = result.snippet.thumbnails.default.url
|
thumbnailUrl = result.snippet.thumbnails.default.url
|
||||||
)
|
)
|
||||||
items.add(item)
|
items.add(item)
|
||||||
Log.i("YC links received",item.id)
|
Log.i("YI links received",item.id)
|
||||||
}
|
}
|
||||||
items
|
items
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.d("YC", "Could not search: $e")
|
Log.d("YI", "Could not search: $e")
|
||||||
null
|
if(query?.key == apiKey2){return null}
|
||||||
|
query?.key = apiKey2
|
||||||
|
search(keywords)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class VideoItem(
|
data class VideoItem(
|
||||||
val id:String,
|
val id:String,
|
||||||
val title:String,
|
val title:String,
|
||||||
val description: String,
|
// val description: String,
|
||||||
val thumbnailUrl:String
|
val thumbnailUrl:String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="2dp"
|
android:layout_marginBottom="2dp"
|
||||||
android:background="@drawable/text_background"
|
android:background="@drawable/text_background_accented"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:paddingTop="6dp"
|
android:paddingTop="6dp"
|
||||||
android:text="MainFragment"
|
android:text="Authentication Needed"
|
||||||
android:textColor="@color/colorPrimary"
|
android:textColor="@color/colorPrimary"
|
||||||
android:textSize="12dp"
|
android:textSize="10dp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -10,64 +10,96 @@
|
|||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:context=".fragments.MainFragment">
|
tools:context=".fragments.MainFragment">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/btn_download_all"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/btn_design"
|
||||||
|
android:drawableEnd="@drawable/ic_arrow_slim"
|
||||||
|
android:drawablePadding="4dp"
|
||||||
|
android:drawableTint="@color/black"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:text="Download All |"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_anchor="@+id/constraint_layout"
|
||||||
|
app:layout_anchorGravity="top|center" />
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="230dp">
|
android:layout_height="280dp">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:contentScrim="?attr/colorPrimary"
|
app:contentScrim="#CE6A40FF"
|
||||||
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
|
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
|
||||||
app:layout_scrollInterpolator="@android:anim/decelerate_interpolator"
|
app:layout_scrollInterpolator="@android:anim/decelerate_interpolator"
|
||||||
app:toolbarId="@+id/toolbar">
|
app:toolbarId="@+id/toolbar">
|
||||||
<LinearLayout
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:orientation="vertical">
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/spotifyLink"
|
android:id="@+id/spotifyLink"
|
||||||
android:layout_width="257dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="20dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:background="@drawable/text_background"
|
android:background="@drawable/text_background_accented"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:hint="Link From Spotify"
|
android:hint="Link From Spotify"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:padding="5dp"
|
android:padding="8dp"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textColorHint="@color/grey"
|
android:textColorHint="@color/grey"
|
||||||
android:textSize="19sp" />
|
android:textSize="19sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/image_view"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/btn_search"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/btn_search"
|
android:id="@+id/btn_search"
|
||||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="44dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:backgroundTint="@color/colorPrimary"
|
android:background="@drawable/btn_design"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingRight="4dp"
|
||||||
android:text="Search"
|
android:text="Search"
|
||||||
android:textSize="18sp" />
|
android:textColor="@color/black"
|
||||||
</LinearLayout>
|
android:textSize="16sp"
|
||||||
<ImageView
|
app:layout_constraintBottom_toBottomOf="@id/spotifyLink"
|
||||||
android:id="@+id/image_view"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_width="match_parent"
|
app:layout_constraintStart_toEndOf="@+id/spotifyLink"
|
||||||
android:layout_height="match_parent"
|
app:layout_constraintTop_toTopOf="@id/spotifyLink" />
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:contentDescription="Album Cover"
|
<ImageView
|
||||||
android:scaleType="centerInside"
|
android:id="@+id/image_view"
|
||||||
android:src="@drawable/ic_launcher_foreground"
|
android:layout_width="0dp"
|
||||||
app:layout_collapseMode="parallax"/>
|
android:layout_height="0dp"
|
||||||
</LinearLayout>
|
android:layout_marginTop="6dp"
|
||||||
|
android:contentDescription="Album Cover"
|
||||||
|
android:foreground="@drawable/gradient"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:paddingBottom="35dp"
|
||||||
|
android:src="@drawable/ic_launcher_foreground"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_collapseMode="parallax"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/btn_search" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
@ -113,7 +145,7 @@
|
|||||||
android:id="@+id/track_list"
|
android:id="@+id/track_list"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="22dp"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
@ -121,7 +153,7 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/title_view" />
|
app:layout_constraintTop_toBottomOf="@+id/title_view" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
@ -28,17 +28,16 @@
|
|||||||
android:id="@+id/track_name"
|
android:id="@+id/track_name"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="14dp"
|
||||||
android:fontFamily="monospace"
|
android:fontFamily="@font/raleway_semibold"
|
||||||
android:letterSpacing="-0.03"
|
android:letterSpacing="0.04"
|
||||||
android:lines="1"
|
android:lines="1"
|
||||||
android:text="The Spectre"
|
android:text="The Spectre"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
||||||
android:textColor="@color/colorPrimary"
|
android:textColor="#9AB3FF"
|
||||||
android:textSize="18sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
||||||
app:layout_constraintStart_toStartOf="@+id/artist"
|
app:layout_constraintStart_toStartOf="@+id/artist"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
@ -49,9 +48,11 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
android:paddingLeft="9dp"
|
android:paddingLeft="9dp"
|
||||||
android:text="Alan Walker"
|
android:text="Alan Walker"
|
||||||
|
android:textSize="12sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/duration"
|
app:layout_constraintEnd_toStartOf="@+id/duration"
|
||||||
app:layout_constraintStart_toEndOf="@+id/imageUrl"
|
app:layout_constraintStart_toEndOf="@+id/imageUrl"
|
||||||
@ -63,8 +64,10 @@
|
|||||||
style="@style/TextAppearance.AppCompat.Body2"
|
style="@style/TextAppearance.AppCompat.Body2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="3dp"
|
||||||
android:paddingLeft="9dp"
|
android:paddingLeft="9dp"
|
||||||
android:text="4 minutes, 20 sec"
|
android:text="4 minutes, 20 sec"
|
||||||
|
android:textSize="12sp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/artist"
|
app:layout_constraintBottom_toBottomOf="@+id/artist"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
||||||
app:layout_constraintStart_toEndOf="@+id/artist"
|
app:layout_constraintStart_toEndOf="@+id/artist"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#0AFF02</color>
|
<color name="colorPrimary">#FC5C7D</color>
|
||||||
<color name="colorPrimaryDark">#43FF56</color>
|
<color name="colorPrimaryDark">#CE1CFF</color>
|
||||||
<color name="colorAccent">#43FF56</color>
|
<color name="colorAccent">#8497FA</color>
|
||||||
<color name="white">#FFFFFF</color>
|
<color name="white">#FFFFFF</color>
|
||||||
<color name="grey">#99FFFFFF</color>
|
<color name="grey">#99FFFFFF</color>
|
||||||
<color name="black">#000000</color>
|
<color name="black">#000000</color>
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
<!-- Customize your theme here. -->
|
<!-- Customize your theme here. -->
|
||||||
<item name="colorPrimaryDark">#00730C</item>
|
<item name="colorPrimaryDark">#000000</item>
|
||||||
<item name="colorPrimary">#05A300</item>
|
<item name="colorPrimary">#FC5C7D</item>
|
||||||
<item name="android:background">#000000</item>
|
<item name="android:background">#000000</item>
|
||||||
<item name="android:textColor">#FFFFFF</item>
|
<item name="android:textColor">#FFFFFF</item>
|
||||||
<item name="colorAccent">#43FF56</item>
|
<item name="colorAccent">#6A82FB</item>
|
||||||
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">#6DFF7C</item>
|
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">#A9B200FF</item>
|
||||||
<item name="android:radius">11dp</item>
|
<item name="android:radius">11dp</item>
|
||||||
<!-- Text Appearances !-->
|
<!-- Text Appearances !-->
|
||||||
<!-- use our brand's custom TextAppearance4 !-->
|
<!-- use our brand's custom TextAppearance4 !-->
|
||||||
|
Loading…
Reference in New Issue
Block a user