Ui Revamp ,And Functionality Improved(Album,Playlist,RecyclerView)

This commit is contained in:
shabinder 2020-07-21 17:02:52 +05:30
parent f57fffd6eb
commit d4823f0e10
14 changed files with 356 additions and 168 deletions

View File

@ -2,6 +2,7 @@
<dictionary name="shabinder"> <dictionary name="shabinder">
<words> <words>
<w>musicforeveryone</w> <w>musicforeveryone</w>
<w>musicplaceholder</w>
<w>shabinder</w> <w>shabinder</w>
<w>spotify</w> <w>spotify</w>
<w>spotifydownloader</w> <w>spotifydownloader</w>

View File

@ -71,7 +71,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.okhttp3:okhttp:4.8.0' implementation 'com.squareup.okhttp3:okhttp:4.8.0'
implementation 'com.github.sealedtx:java-youtube-downloader:2.2.1' implementation 'com.github.sealedtx:java-youtube-downloader:2.2.2'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13'

View File

@ -13,6 +13,7 @@ import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.github.kiulian.downloader.YoutubeDownloader import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.musicForEveryone.databinding.MainActivityBinding import com.shabinder.musicForEveryone.databinding.MainActivityBinding
import com.shabinder.musicForEveryone.utils.SpotifyNewService
import com.shabinder.musicForEveryone.utils.YoutubeInterface import com.shabinder.musicForEveryone.utils.YoutubeInterface
import com.spotify.sdk.android.authentication.AuthenticationClient import com.spotify.sdk.android.authentication.AuthenticationClient
import com.spotify.sdk.android.authentication.AuthenticationRequest import com.spotify.sdk.android.authentication.AuthenticationRequest

View File

@ -4,6 +4,7 @@ import android.app.DownloadManager
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.github.kiulian.downloader.YoutubeDownloader import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.musicForEveryone.utils.SpotifyNewService
import kaaes.spotify.webapi.android.SpotifyService import kaaes.spotify.webapi.android.SpotifyService
import kaaes.spotify.webapi.android.models.Album import kaaes.spotify.webapi.android.models.Album
import kaaes.spotify.webapi.android.models.Playlist import kaaes.spotify.webapi.android.models.Playlist

View File

@ -10,13 +10,14 @@ import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.google.android.material.snackbar.Snackbar
import com.shabinder.musicForEveryone.R import com.shabinder.musicForEveryone.R
import com.shabinder.musicForEveryone.SharedViewModel import com.shabinder.musicForEveryone.SharedViewModel
import com.shabinder.musicForEveryone.bindImage
import com.shabinder.musicForEveryone.databinding.MainFragmentBinding import com.shabinder.musicForEveryone.databinding.MainFragmentBinding
import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper
import com.shabinder.musicForEveryone.recyclerView.TrackListAdapter
import com.shabinder.musicForEveryone.utils.bindImage
import kaaes.spotify.webapi.android.SpotifyService import kaaes.spotify.webapi.android.SpotifyService
import kaaes.spotify.webapi.android.models.Track
class MainFragment : Fragment(),DownloadHelper { class MainFragment : Fragment(),DownloadHelper {
@ -34,10 +35,10 @@ class MainFragment : Fragment(),DownloadHelper {
spotify = sharedViewModel.spotify spotify = sharedViewModel.spotify
sharedViewModel.userName.observe(viewLifecycleOwner, Observer { sharedViewModel.userName.observe(viewLifecycleOwner, Observer {
binding.message.text = it binding.message.text = it
if(it!="Placeholder"){Snackbar.make(requireView(),"Hello, $it!", Snackbar.LENGTH_SHORT).show()} // if(it!="Placeholder"){Snackbar.make(requireView(),"Hello, $it!", Snackbar.LENGTH_SHORT).show()}
}) })
binding.btnGetDetails.setOnClickListener { binding.btnSearch.setOnClickListener {
val spotifyLink = binding.spotifyLink.text.toString() val spotifyLink = binding.spotifyLink.text.toString()
val link = spotifyLink.substringAfterLast('/' , "Error").substringBefore('?') val link = spotifyLink.substringAfterLast('/' , "Error").substringBefore('?')
@ -45,47 +46,55 @@ class MainFragment : Fragment(),DownloadHelper {
Log.i("Fragment", "$type : $link") Log.i("Fragment", "$type : $link")
val adapter = TrackListAdapter()
binding.trackList.adapter = adapter
adapter.sharedViewModel = sharedViewModel
when(type){ when(type){
"track" -> { "track" -> {
val trackObject = sharedViewModel.getTrackDetails(link) val trackObject = sharedViewModel.getTrackDetails(link)
Log.i("Fragment",trackObject?.name.toString())
binding.name.text = trackObject?.name ?: "Error" val trackList = mutableListOf<Track>()
var artistNames = "" trackList.add(trackObject!!)
trackObject?.artists?.forEach { artistNames = artistNames.plus("${it.name} ,") } adapter.totalItems = 1
binding.artist.text = artistNames adapter.trackList = trackList
binding.popularity.text = trackObject?.popularity.toString() adapter.notifyDataSetChanged()
binding.duration.text = ((trackObject?.duration_ms!! /1000/60).toString() + "minutes")
binding.albumName.text = trackObject.album.name Log.i("Adapter",trackList.size.toString())
bindImage(binding.imageUrl, trackObject.album.images[0].url)
} }
"album" -> { "album" -> {
val albumObject = sharedViewModel.getAlbumDetails(link) val albumObject = sharedViewModel.getAlbumDetails(link)
Log.i("Fragment",albumObject?.name.toString())
binding.name.text = albumObject?.name ?: "Error" bindImage(binding.imageView,albumObject!!.images[1].url)
var artistNames = "" binding.titleView.text = albumObject.name
albumObject?.artists?.forEach { artistNames = artistNames.plus(", ${it.name}") } binding.titleView.visibility =View.VISIBLE
binding.artist.text = artistNames binding.imageView.visibility =View.VISIBLE
binding.popularity.text = albumObject?.popularity.toString()
binding.duration.visibility = View.GONE val trackList = mutableListOf<Track>()
binding.textView5.visibility = View.GONE albumObject.tracks?.items?.forEach { trackList.add(it as Track) }
binding.albumName.text = albumObject?.name adapter.totalItems = trackList.size
bindImage(binding.imageUrl, albumObject?.images?.get(0)?.url) adapter.trackList = trackList
adapter.notifyDataSetChanged()
Log.i("Adapter",trackList.size.toString())
} }
"playlist" -> { "playlist" -> {
val playlistObject = sharedViewModel.getPlaylistDetails(link) val playlistObject = sharedViewModel.getPlaylistDetails(link)
Log.i("Fragment",playlistObject?.name.toString())
binding.name.text = playlistObject?.name ?: "Error" bindImage(binding.imageView,playlistObject!!.images[0].url)
binding.artist.visibility = View.GONE binding.titleView.text = playlistObject.name
binding.textView1.visibility = View.GONE binding.titleView.visibility =View.VISIBLE
binding.popularity.text = playlistObject?.followers?.total.toString() binding.imageView.visibility =View.VISIBLE
binding.textview3.text = "Followers"
binding.duration.visibility = View.GONE val trackList = mutableListOf<Track>()
binding.textView5.visibility = View.GONE playlistObject.tracks?.items!!.forEach { trackList.add(it.track) }
binding.textView7.text = "Total Tracks" adapter.trackList = trackList.toList()
binding.albumName.text = playlistObject?.tracks?.items?.size.toString() adapter.totalItems = trackList.size
bindImage(binding.imageUrl, playlistObject?.images?.get(0)?.url) adapter.notifyDataSetChanged()
Log.i("Adapter",trackList.size.toString())
} }
"episode" -> {showToast("Implementation Pending")} "episode" -> {showToast("Implementation Pending")}
@ -94,12 +103,6 @@ class MainFragment : Fragment(),DownloadHelper {
binding.spotifyLink.setText(link) binding.spotifyLink.setText(link)
} }
binding.btnDownload.setOnClickListener {
downloadTrack(sharedViewModel.ytDownloader,sharedViewModel.downloadManager,"${binding.name.text} ${if(binding.artist.text != "TextView" ){binding.artist.text}else{""}}")
}
return binding.root return binding.root
} }

View File

@ -0,0 +1,54 @@
package com.shabinder.musicForEveryone.recyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.shabinder.musicForEveryone.R
import com.shabinder.musicForEveryone.SharedViewModel
import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper
import com.shabinder.musicForEveryone.utils.bindImage
import kaaes.spotify.webapi.android.models.Track
class TrackListAdapter:RecyclerView.Adapter<TrackListAdapter.ViewHolder>(),DownloadHelper {
var trackList = listOf<Track>()
var totalItems:Int = 0
var sharedViewModel = SharedViewModel()
override fun getItemCount():Int = totalItems
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.track_list_item,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = trackList[position]
bindImage(holder.coverImage,item.album.images[0].url)
holder.trackName.text = "${if(item.name.length > 22){"${item.name.subSequence(0,19)}..."}else{item.name}}"
holder.artistName.text = "${item.artists[0]?.name?:""}..."
holder.popularity.text = item.popularity.toString()
holder.duration.text = "${item.duration_ms/1000/60} minutes, ${(item.duration_ms/1000)%60} seconds"
holder.downloadBtn.setOnClickListener{
downloadTrack(sharedViewModel.ytDownloader,sharedViewModel.downloadManager,"${item.name} ${item.artists[0].name?:""}")
}
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val trackName:TextView = itemView.findViewById(R.id.track_name)
val artistName:TextView = itemView.findViewById(R.id.artist)
val popularity:TextView = itemView.findViewById(R.id.popularity)
val duration:TextView = itemView.findViewById(R.id.duration)
val downloadBtn:Button = itemView.findViewById(R.id.btn_download)
val coverImage:ImageView = itemView.findViewById(R.id.imageUrl)
}
}

View File

@ -1,10 +1,11 @@
package com.shabinder.musicForEveryone package com.shabinder.musicForEveryone.utils
import android.widget.ImageView import android.widget.ImageView
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.databinding.BindingAdapter import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.shabinder.musicForEveryone.R
@BindingAdapter("imageUrl") @BindingAdapter("imageUrl")

View File

@ -1,4 +1,4 @@
package com.shabinder.musicForEveryone package com.shabinder.musicForEveryone.utils
import kaaes.spotify.webapi.android.models.Playlist import kaaes.spotify.webapi.android.models.Playlist
import retrofit.http.GET import retrofit.http.GET

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="300dp"
android:height="300dp" android:viewportWidth="512" android:viewportHeight="512">
<path android:fillColor="#FF000000" android:pathData="m256,80a48.054,48.054 0,0 1,48 48v32h12a19.991,19.991 0,0 0,3.524 -39.671,63.984 63.984,0 0,0 -127.048,0 19.991,19.991 0,0 0,3.524 39.671h12v-32a48.054,48.054 0,0 1,48 -48z"/>
<path android:fillColor="#FF000000" android:pathData="m48,152a24.027,24.027 0,0 0,24 -24v-74.234l42.53,-14.176 -5.06,-15.18 -48,16a8,8 0,0 0,-5.47 7.59v57.376a24,24 0,1 0,-8 46.624zM48,120a8,8 0,1 1,-8 8,8.009 8.009,0 0,1 8,-8z"/>
<path android:fillColor="#FF000000" android:pathData="m485.006,17.76a7.993,7.993 0,0 0,-6.741 -1.569l-72,16a8,8 0,0 0,-6.265 7.809v57.376a24,24 0,1 0,16 22.624v-73.583l56,-12.444v47.4a24,24 0,1 0,16 22.627v-80a8,8 0,0 0,-2.994 -6.24zM392,128a8,8 0,1 1,8 -8,8.009 8.009,0 0,1 -8,8zM464,112a8,8 0,1 1,8 -8,8.009 8.009,0 0,1 -8,8z"/>
<path android:fillColor="#FF000000" android:pathData="m48,456h416v40h-416z"/>
<path android:fillColor="#FF000000" android:pathData="m64,376a16,16 0,0 0,-16 16v7h48v-7a16,16 0,0 0,-16 -16z"/>
<path android:fillColor="#FF000000" android:pathData="m24,416h464v24h-464z"/>
<path android:fillColor="#FF000000" android:pathData="M256,144m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"/>
<path android:fillColor="#FF000000" android:pathData="m368,400 l16,-160h-256l16,160zM256,296a24,24 0,1 1,-24 24,24 24,0 0,1 24,-24z"/>
<path android:fillColor="#FF000000" android:pathData="m168,224h176a32,32 0,0 0,-32 -32h-112a32,32 0,0 0,-32 32z"/>
</vector>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners android:radius="25dip" />
<solid android:color="#000000">
</solid>
<stroke
android:width="2dp"
android:color="@color/grey" />
</shape>

View File

@ -14,8 +14,13 @@
android:id="@+id/message" android:id="@+id/message"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp" android:layout_marginBottom="8dp"
android:text="MainFragment" android:text="MainFragment"
android:background="@drawable/text_backdround"
android:padding="5dp"
android:textColor="@color/colorPrimary"
android:textSize="12dp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
@ -24,146 +29,77 @@
android:id="@+id/spotifyLink" android:id="@+id/spotifyLink"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="25dp"
android:background="@drawable/text_backdround"
android:hint="Link From Spotify"
android:ems="10" android:ems="10"
android:padding="5dp"
android:inputType="text" android:inputType="text"
android:text="Song Link From Spotify" android:textAlignment="center"
app:layout_constraintEnd_toStartOf="@+id/btn_getDetails" android:textColor="@color/white"
android:textColorHint="@color/grey"
android:textSize="20dp"
app:layout_constraintEnd_toStartOf="@+id/btn_search"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<Button <Button
android:id="@+id/btn_getDetails" android:id="@+id/btn_search"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:backgroundTint="@color/colorPrimary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Get Details" android:text="Search"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/spotifyLink" app:layout_constraintBottom_toBottomOf="@+id/spotifyLink"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/spotifyLink" app:layout_constraintStart_toEndOf="@+id/spotifyLink"
app:layout_constraintTop_toTopOf="@+id/spotifyLink" /> app:layout_constraintTop_toTopOf="@+id/spotifyLink" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/track_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="3dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/message"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_view"
app:layout_constraintVertical_bias="0.0" />
<ImageView <ImageView
android:id="@+id/imageUrl" android:id="@+id/image_view"
android:layout_width="180dp" android:layout_width="150dp"
android:layout_height="200dp" android:layout_height="150dp"
android:layout_marginTop="16dp" android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/spotifyLink" app:layout_constraintTop_toBottomOf="@+id/spotifyLink"
tools:srcCompat="@tools:sample/avatars" /> android:visibility="gone"/>
<TextView <TextView
android:id="@+id/name" android:id="@+id/title_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="2dp"
android:fontFamily="monospace" android:layout_marginBottom="5dp"
android:text="TextView" android:text="TextView"
android:background="@drawable/text_backdround"
android:drawableTint="@color/colorPrimary"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
android:textAllCaps="false" android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Display1" android:textColor="@color/colorPrimary"
android:textSize="24sp"
android:visibility="gone"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageUrl" /> app:layout_constraintTop_toBottomOf="@+id/image_view" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Artist
"
app:layout_constraintBottom_toTopOf="@+id/textview3"
app:layout_constraintEnd_toStartOf="@+id/artist"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_download" />
<TextView
android:id="@+id/artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView1"
app:layout_constraintTop_toTopOf="@+id/textView1" />
<TextView
android:id="@+id/textview3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Popularity"
app:layout_constraintBottom_toTopOf="@+id/textView5"
app:layout_constraintEnd_toStartOf="@+id/popularity"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<TextView
android:id="@+id/popularity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textview3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textview3"
app:layout_constraintTop_toTopOf="@+id/textview3" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Duration"
app:layout_constraintBottom_toTopOf="@+id/textView7"
app:layout_constraintEnd_toStartOf="@+id/duration"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textview3" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView5"
app:layout_constraintTop_toTopOf="@+id/textView5" />
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Album Name"
app:layout_constraintBottom_toTopOf="@+id/message"
app:layout_constraintEnd_toStartOf="@+id/albumName"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView5" />
<TextView
android:id="@+id/albumName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView7"
app:layout_constraintTop_toTopOf="@+id/textView7" />
<Button
android:id="@+id/btn_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Download"
app:layout_constraintEnd_toEndOf="@+id/name"
app:layout_constraintStart_toStartOf="@+id/name"
app:layout_constraintTop_toBottomOf="@+id/name" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000000"
>
<ImageView
android:id="@+id/imageUrl"
android:layout_width="100dp"
android:layout_height="100dp"
android:contentDescription="Track Image"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_musicplaceholder"
tools:tint="#A3FFFFFF"/>
<TextView
android:id="@+id/track_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:text="TextView"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
android:textColor="@color/colorPrimary"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageUrl"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:paddingLeft="9dp"
android:text="Artist"
android:textSize="12dp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/textview3"
app:layout_constraintEnd_toStartOf="@+id/artist"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageUrl"
app:layout_constraintTop_toBottomOf="@+id/track_name" />
<TextView
android:id="@+id/artist"
style="@style/TextAppearance.AppCompat.Body2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="9dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView1"
app:layout_constraintTop_toTopOf="@+id/textView1" />
<TextView
android:id="@+id/textview3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="9dp"
android:text="Popularity"
android:textSize="12dp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/textView5"
app:layout_constraintEnd_toStartOf="@+id/popularity"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageUrl"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<TextView
android:id="@+id/popularity"
style="@style/TextAppearance.AppCompat.Body2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="9dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textview3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textview3"
app:layout_constraintTop_toTopOf="@+id/textview3" />
<TextView
android:id="@+id/textView5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:paddingLeft="9dp"
android:text="Duration"
android:textSize="12dp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/btn_download"
app:layout_constraintEnd_toStartOf="@+id/duration"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageUrl"
app:layout_constraintTop_toBottomOf="@+id/textview3" />
<TextView
android:id="@+id/duration"
style="@style/TextAppearance.AppCompat.Body2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="9dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@+id/textView5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView5"
app:layout_constraintTop_toTopOf="@+id/textView5" />
<Button
android:id="@+id/btn_download"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="#27FF3D"
android:text="Download"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageUrl" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#6200EE</color> <color name="colorPrimary">#0AFF02</color>
<color name="colorPrimaryDark">#3700B3</color> <color name="colorPrimaryDark">#43FF56</color>
<color name="colorAccent">#03DAC5</color> <color name="colorAccent">#43FF56</color>
<color name="white">#FFFFFF</color>
<color name="grey">#99FFFFFF</color>
<color name="black">#000000</color>
</resources> </resources>

View File

@ -1,10 +1,34 @@
<resources> <resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">#00730C</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimary">#05A300</item>
<item name="colorAccent">@color/colorAccent</item> <item name="android:background">#000000</item>
<item name="android:textColor">#FFFFFF</item>
<item name="colorAccent">#43FF56</item>
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">#6DFF7C</item>
<item name="android:radius">11dp</item>
<!-- Text Appearances !-->
<!-- use our brand's custom TextAppearance4 !-->
<item name="textAppearanceHeadline4">@style/TextAppearance.AppTheme.Headline4</item>
<!-- use default Body2 text apperance !-->
<item name="textAppearanceBody2">@style/TextAppearance.MaterialComponents.Body2</item>
</style> </style>
<!-- override the Headline4 style present in the Material Theme !-->
<style name="TextAppearance.AppTheme.Headline4" parent="TextAppearance.MaterialComponents.Headline4">
<item name="android:textSize">28sp</item>
<item name="android:letterSpacing">0.1</item>
<item name="android:textStyle">bold</item>
</style>
<style name="TextAppearance.AppCompat.Body2">
<item name="android:textColor">@color/grey</item>
</style>
<style name="Widget.MaterialComponents.Button.OutlinedButton">
<item name="android:background">@color/white</item>
<item name="android:textColor">@color/black</item>
</style>
</resources> </resources>