Fix miniplayer showing, cardview,remmeber last selected option,
This commit is contained in:
parent
0e179d6842
commit
b9e3483a47
22 changed files with 154 additions and 380 deletions
|
@ -64,7 +64,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
}
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
selectedFragment(PreferenceUtil.getInstance(this).lastPage)
|
||||
setMusicChooser(PreferenceUtil.getInstance(this).lastMusicChooser)
|
||||
} else {
|
||||
restoreCurrentFragment()
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
if (key == PreferenceUtil.GENERAL_THEME ||
|
||||
key==PreferenceUtil.BLACK_THEME||
|
||||
key == PreferenceUtil.BLACK_THEME ||
|
||||
key == PreferenceUtil.ADAPTIVE_COLOR_APP ||
|
||||
key == PreferenceUtil.DOMINANT_COLOR ||
|
||||
key == PreferenceUtil.USER_NAME ||
|
||||
|
@ -264,7 +264,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
}*/
|
||||
}
|
||||
|
||||
fun selectedFragment(itemId: Int) {
|
||||
private fun selectedFragment(itemId: Int) {
|
||||
when (itemId) {
|
||||
R.id.action_album,
|
||||
R.id.action_artist,
|
||||
|
@ -272,16 +272,25 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
R.id.action_genre,
|
||||
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString())
|
||||
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
|
||||
R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
|
||||
else -> {
|
||||
setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setMusicChooser(key: Int) {
|
||||
PreferenceUtil.getInstance(this).lastMusicChooser = key
|
||||
when (key) {
|
||||
FOLDER -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
|
||||
else -> selectedFragment(PreferenceUtil.getInstance(this).lastPage)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val APP_INTRO_REQUEST = 2323
|
||||
const val HOME = 0
|
||||
const val FOLDER = 1
|
||||
const val LIBRARY = 2
|
||||
private const val TAG = "MainActivity"
|
||||
private const val APP_USER_INFO_REQUEST = 9003
|
||||
private const val REQUEST_CODE_THEME = 9002
|
||||
|
|
|
@ -127,6 +127,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
|
|||
|
||||
fun expandPanel() {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
setMiniPlayerAlphaProgress(1f)
|
||||
}
|
||||
|
||||
private fun setMiniPlayerAlphaProgress(progress: Float) {
|
||||
|
@ -175,7 +176,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(), AbsPlay
|
|||
}
|
||||
when (panelState) {
|
||||
BottomSheetBehavior.STATE_EXPANDED -> {
|
||||
|
||||
onPanelExpanded()
|
||||
}
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> onPanelCollapsed()
|
||||
|
|
|
@ -35,8 +35,8 @@ class OptionsSheetDialogFragment : DialogFragment(), View.OnClickListener {
|
|||
override fun onClick(view: View) {
|
||||
val mainActivity = activity as MainActivity? ?: return
|
||||
when (view.id) {
|
||||
R.id.actionFolders -> mainActivity.selectedFragment(R.id.action_folder)
|
||||
R.id.actionLibrary -> mainActivity.selectedFragment(PreferenceUtil.getInstance(requireContext()).lastPage)
|
||||
R.id.actionFolders -> mainActivity.setMusicChooser(MainActivity.FOLDER)
|
||||
R.id.actionLibrary -> mainActivity.setMusicChooser(MainActivity.LIBRARY)
|
||||
R.id.actionSettings -> NavigationUtil.goToSettings(mainActivity)
|
||||
R.id.actionRate -> NavigationUtil.goToPlayStore(mainActivity)
|
||||
}
|
||||
|
|
|
@ -51,29 +51,4 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
|
|||
RetroColorUtil.getColor(it.palette, defaultColor))
|
||||
}
|
||||
}
|
||||
|
||||
/* protected val defaultFooterColor: Int
|
||||
get() = ATHUtil.resolveColor(getView().context, R.attr.defaultFooterColor)
|
||||
|
||||
protected val albumArtistFooterColor: Int
|
||||
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
|
||||
|
||||
override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(e, errorDrawable)
|
||||
onColorReady(defaultFooterColor)
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: BitmapPaletteWrapper,
|
||||
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
|
||||
super.onResourceReady(resource, glideAnimation)
|
||||
|
||||
val defaultColor = defaultFooterColor
|
||||
|
||||
onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor)
|
||||
getDominantColor(resource.bitmap, defaultColor)
|
||||
else
|
||||
getColor(resource.palette, defaultColor))
|
||||
}
|
||||
|
||||
abstract fun onColorReady(color: Int)*/
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ class ArtistImageFetcher(
|
|||
|
||||
override fun loadData(priority: Priority?): InputStream? {
|
||||
if (!MusicUtil.isArtistNameUnknown(model.artistName) && PreferenceUtil.isAllowedToDownloadMetadata(context)) {
|
||||
val artists = model.artistName.split(",|&")
|
||||
val artists = model.artistName.split(",")
|
||||
val response = deezerApiService.getArtistImage(artists[0]).execute()
|
||||
|
||||
if (!response.isSuccessful) {
|
||||
|
@ -97,8 +97,8 @@ class ArtistImageFetcher(
|
|||
|
||||
class ArtistImageLoader(
|
||||
val context: Context,
|
||||
val deezerApiService: DeezerApiService,
|
||||
val urlLoader: ModelLoader<GlideUrl, InputStream>
|
||||
private val deezerApiService: DeezerApiService,
|
||||
private val urlLoader: ModelLoader<GlideUrl, InputStream>
|
||||
) : StreamModelLoader<ArtistImage> {
|
||||
|
||||
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
|
||||
|
@ -110,10 +110,10 @@ class Factory(
|
|||
val context: Context
|
||||
) : ModelLoaderFactory<ArtistImage, InputStream> {
|
||||
private var deezerApiService: DeezerApiService
|
||||
private var okhttpFactory: OkHttpUrlLoader.Factory
|
||||
private var okHttpFactory: OkHttpUrlLoader.Factory
|
||||
|
||||
init {
|
||||
okhttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
|
||||
okHttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
|
||||
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
|
@ -126,11 +126,11 @@ class Factory(
|
|||
}
|
||||
|
||||
override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader<ArtistImage, InputStream> {
|
||||
return ArtistImageLoader(context!!, deezerApiService, okhttpFactory.build(context, factories))
|
||||
return ArtistImageLoader(context!!, deezerApiService, okHttpFactory.build(context, factories))
|
||||
}
|
||||
|
||||
override fun teardown() {
|
||||
okhttpFactory.teardown()
|
||||
okHttpFactory.teardown()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -139,301 +139,3 @@ class Factory(
|
|||
}
|
||||
|
||||
}
|
||||
/*class AlbumCover(
|
||||
var year: Int,
|
||||
var filePath: String?)
|
||||
|
||||
class ArtistImage(val artistName: String, // filePath to get the image of the artist
|
||||
val albumCovers: List<AlbumCover>
|
||||
) {
|
||||
|
||||
fun toIdString(): String {
|
||||
val id = StringBuilder(artistName)
|
||||
for (albumCover in albumCovers) {
|
||||
id.append(albumCover.year).append(albumCover.filePath)
|
||||
}
|
||||
return id.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ArtistImageFetcher(
|
||||
val artistImage: ArtistImage,
|
||||
val ignoreMediaStore: Boolean
|
||||
) : DataFetcher<InputStream> {
|
||||
private var stream: InputStream? = null
|
||||
|
||||
override fun cleanup() {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream?.close()
|
||||
} catch (ignore: IOException) {
|
||||
// can't do much about it
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
|
||||
}
|
||||
|
||||
override fun loadData(priority: Priority?): InputStream {
|
||||
println("MOSAIC load data for" + artistImage.artistName)
|
||||
stream = getMosaic(artistImage.albumCovers)?.let {
|
||||
it
|
||||
}
|
||||
return stream as InputStream
|
||||
}
|
||||
|
||||
private fun getMosaic(albumCovers: List<AlbumCover>): InputStream? {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
val artistBitMapSize = 512
|
||||
val images = HashMap<InputStream, Int>()
|
||||
var result: InputStream? = null
|
||||
var streams = ArrayList<InputStream>()
|
||||
try {
|
||||
for (albumCover in albumCovers) {
|
||||
var picture: ByteArray? = null
|
||||
if (!ignoreMediaStore) {
|
||||
retriever.setDataSource(albumCover.filePath)
|
||||
picture = retriever.embeddedPicture
|
||||
}
|
||||
val stream: InputStream? = if (picture != null) {
|
||||
ByteArrayInputStream(picture)
|
||||
} else {
|
||||
AudioFileCoverUtils.fallback(albumCover.filePath)
|
||||
}
|
||||
if (stream != null) {
|
||||
images[stream] = albumCover.year
|
||||
}
|
||||
val nbImages = images.size
|
||||
if (nbImages > 3) {
|
||||
streams = ArrayList(images.keys)
|
||||
|
||||
var divisor = 1
|
||||
var i = 1
|
||||
while (i < nbImages && Math.pow(i.toDouble(), 2.0) <= nbImages) {
|
||||
divisor = i
|
||||
++i
|
||||
}
|
||||
divisor += 1
|
||||
var nbTiles = Math.pow(divisor.toDouble(), 2.0)
|
||||
|
||||
if (nbImages < nbTiles) {
|
||||
divisor -= 1;
|
||||
nbTiles = Math.pow(divisor.toDouble(), 2.0)
|
||||
}
|
||||
|
||||
val resize = (artistBitMapSize / divisor) + 1
|
||||
|
||||
val bitmap = Bitmap.createBitmap(artistBitMapSize, artistBitMapSize, Bitmap.Config.RGB_565)
|
||||
val canvas = Canvas(bitmap)
|
||||
|
||||
var x = 0F
|
||||
var y = 0F
|
||||
|
||||
var j = 0
|
||||
while (j < streams.size && j < nbTiles) {
|
||||
val tempBitmap = ImageUtil.resize(streams[j], resize, resize)
|
||||
canvas.drawBitmap(tempBitmap, x, y, null)
|
||||
x += resize
|
||||
|
||||
if (x >= artistBitMapSize) {
|
||||
x = 0F
|
||||
y += resize
|
||||
}
|
||||
++j
|
||||
}
|
||||
|
||||
val bos = ByteArrayOutputStream()
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos)
|
||||
result = ByteArrayInputStream(bos.toByteArray())
|
||||
|
||||
} else if (nbImages > 0) {
|
||||
var maxEntryYear: Map.Entry<InputStream, Int>? = null
|
||||
for (entry in images.entries) {
|
||||
if (maxEntryYear == null || entry.value
|
||||
.compareTo(maxEntryYear.value) > 0) {
|
||||
maxEntryYear = entry
|
||||
}
|
||||
|
||||
}
|
||||
result = if (maxEntryYear != null) {
|
||||
maxEntryYear.key
|
||||
} else {
|
||||
images.entries
|
||||
.iterator()
|
||||
.next()
|
||||
.key
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
retriever.release()
|
||||
try {
|
||||
for (stream in streams) {
|
||||
stream.close()
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
override fun getId(): String {
|
||||
println("MOSAIC get id for" + artistImage.artistName)
|
||||
// never return NULL here!
|
||||
// this id is used to determine whether the image is already cached
|
||||
// we use the artist name as well as the album years + file paths
|
||||
return artistImage.toIdString() + "ignoremediastore:" + ignoreMediaStore
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ArtistImageLoader(
|
||||
private val context: Context
|
||||
) : StreamModelLoader<ArtistImage> {
|
||||
|
||||
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
|
||||
|
||||
return ArtistImageFetcher(model, PreferenceUtil.getInstance(context).ignoreMediaStoreArtwork())
|
||||
}
|
||||
|
||||
class Factory : ModelLoaderFactory<ArtistImage, InputStream> {
|
||||
|
||||
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<ArtistImage, InputStream> {
|
||||
return ArtistImageLoader(context)
|
||||
}
|
||||
|
||||
override fun teardown() {
|
||||
|
||||
}
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
|
||||
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
||||
|
||||
class ArtistImageFetcher(private val context: Context,
|
||||
private val deezerApiService: DeezerApiService,
|
||||
private val okHttp: OkHttpClient,
|
||||
private val model: ArtistImage) : DataFetcher<InputStream> {
|
||||
@Volatile
|
||||
private var isCancelled: Boolean = false
|
||||
private var call: Call<DeezerResponse>? = null
|
||||
private var streamFetcher: OkHttpStreamFetcher? = null
|
||||
|
||||
|
||||
override fun getDataClass(): Class<InputStream> {
|
||||
return InputStream::class.java
|
||||
}
|
||||
|
||||
override fun getDataSource(): DataSource {
|
||||
return DataSource.LOCAL
|
||||
}
|
||||
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||
try {
|
||||
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
|
||||
val artists = model.artistName.split(",")
|
||||
call = deezerApiService.getArtistImage(artists[0])
|
||||
call?.enqueue(object : Callback<DeezerResponse> {
|
||||
override fun onFailure(call: Call<DeezerResponse>, t: Throwable) {
|
||||
callback.onLoadFailed(Exception(t))
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call<DeezerResponse>, response: Response<DeezerResponse>) {
|
||||
if (isCancelled) {
|
||||
callback.onDataReady(null)
|
||||
return
|
||||
}
|
||||
try {
|
||||
val deezerResponse: DeezerResponse? = response.body()
|
||||
val url = deezerResponse?.data?.get(0)?.let { getHighestQuality(it) }
|
||||
streamFetcher = OkHttpStreamFetcher(okHttp, GlideUrl(url))
|
||||
streamFetcher?.loadData(priority, callback)
|
||||
} catch (e: Exception) {
|
||||
callback.onLoadFailed(Exception("No artist image url found"))
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
callback.onLoadFailed(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getHighestQuality(imageUrl: Data): String {
|
||||
return when {
|
||||
imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl
|
||||
imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig
|
||||
imageUrl.pictureMedium.isNotEmpty() -> imageUrl.pictureMedium
|
||||
imageUrl.pictureSmall.isNotEmpty() -> imageUrl.pictureSmall
|
||||
imageUrl.picture.isNotEmpty() -> imageUrl.picture
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
if (streamFetcher != null) {
|
||||
streamFetcher!!.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
isCancelled = true
|
||||
call?.cancel()
|
||||
if (streamFetcher != null) {
|
||||
streamFetcher!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = ArtistImageFetcher::class.java.simpleName
|
||||
}
|
||||
}
|
||||
|
||||
class ArtistImageLoader(private val context: Context,
|
||||
private val deezerApiService: DeezerApiService,
|
||||
private val okhttp: OkHttpClient) : ModelLoader<ArtistImage, InputStream> {
|
||||
|
||||
override fun buildLoadData(model: ArtistImage, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
|
||||
return ModelLoader.LoadData(ObjectKey(model.artistName), ArtistImageFetcher(context, deezerApiService, okhttp, model))
|
||||
}
|
||||
|
||||
override fun handles(model: ArtistImage): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
class Factory(private val context: Context) : ModelLoaderFactory<ArtistImage, InputStream> {
|
||||
private val deezerApiService: DeezerApiService =
|
||||
DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context)
|
||||
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.build())
|
||||
private val okHttp: OkHttpClient = OkHttpClient.Builder()
|
||||
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
|
||||
|
||||
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<ArtistImage, InputStream> {
|
||||
return ArtistImageLoader(context, deezerApiService, okHttp)
|
||||
}
|
||||
|
||||
override fun teardown() {}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
|
||||
private const val TIMEOUT = 700
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -35,12 +35,26 @@ import code.name.monkey.appthemehelper.util.ATHUtil
|
|||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.shape.CornerFamily
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
|
||||
|
||||
object ViewUtil {
|
||||
|
||||
const val RETRO_MUSIC_ANIM_TIME = 1000
|
||||
fun cardViewTopCorners(cardView: MaterialCardView) {
|
||||
|
||||
val radius = PreferenceUtil.getInstance(cardView.context).dialogCorner
|
||||
(cardView.background as? MaterialShapeDrawable).let {
|
||||
it?.shapeAppearanceModel?.apply {
|
||||
toBuilder()
|
||||
.setTopLeftCorner(CornerFamily.CUT, 10f)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createTextColorTransition(v: TextView, @ColorInt startColor: Int, @ColorInt endColor: Int): Animator {
|
||||
return createColorAnimator(v, "textColor", startColor, endColor)
|
||||
|
@ -66,7 +80,7 @@ object ViewUtil {
|
|||
progress.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
|
||||
|
||||
val background = ld.findDrawableByLayerId(android.R.id.background)
|
||||
val primaryColor = ATHUtil.resolveColor(progressSlider.context, R.attr.colorPrimary);
|
||||
val primaryColor = ATHUtil.resolveColor(progressSlider.context, R.attr.colorPrimary)
|
||||
background.setColorFilter(MaterialValueHelper.getPrimaryDisabledTextColor(progressSlider.context, ColorUtil.isColorLight(primaryColor)), PorterDuff.Mode.SRC_IN)
|
||||
|
||||
val secondaryProgress = ld.findDrawableByLayerId(android.R.id.secondaryProgress)
|
||||
|
@ -121,7 +135,7 @@ object ViewUtil {
|
|||
recyclerView.setPopupTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(accentColor)))
|
||||
recyclerView.setThumbColor(accentColor)
|
||||
recyclerView.setTrackColor(Color.TRANSPARENT)
|
||||
recyclerView.setTrackColor(ColorUtil.withAlpha(ATHUtil.resolveColor(context, R.attr.colorControlNormal), 0.12f));
|
||||
recyclerView.setTrackColor(ColorUtil.withAlpha(ATHUtil.resolveColor(context, R.attr.colorControlNormal), 0.12f))
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.shape.CornerFamily
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2019-10-11.
|
||||
*/
|
||||
class TopCornerCardView @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : MaterialCardView(context, attrs, defStyleAttr) {
|
||||
private val shapeDrawable = MaterialShapeDrawable()
|
||||
|
||||
init {
|
||||
val cornerSize= PreferenceUtil.getInstance(context).dialogCorner
|
||||
val shapeModel = shapeDrawable.shapeAppearanceModel
|
||||
background = shapeDrawable
|
||||
shapeDrawable.shapeAppearanceModel = shapeModel.toBuilder()
|
||||
.setTopLeftCorner(CornerFamily.ROUNDED, cornerSize)
|
||||
.setBottomLeftCorner(CornerFamily.ROUNDED, cornerSize)
|
||||
.setBottomRightCorner(CornerFamily.ROUNDED, cornerSize)
|
||||
.setTopRightCorner(CornerFamily.ROUNDED, cornerSize)
|
||||
.build()
|
||||
}
|
||||
}
|
|
@ -41,8 +41,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
android:layout_marginTop="6dp"
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -41,8 +41,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
app:cardElevation="8dp"
|
||||
android:layout_marginTop="6dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -73,9 +74,9 @@
|
|||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text"
|
||||
android:paddingTop="4dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="4dp"
|
||||
android:textAppearance="@style/TextViewSubtitle2"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:text="Title" />
|
||||
|
|
|
@ -114,7 +114,8 @@
|
|||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:cardCornerRadius="12dp">
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<include layout="@layout/home_content" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
|
@ -57,9 +57,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
app:cardPreventCornerOverlap="true">
|
||||
android:layout_marginTop="6dp"
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -55,8 +55,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
app:cardElevation="8dp"
|
||||
android:layout_marginTop="6dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -111,7 +111,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
|
||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||
app:cardCornerRadius="12dp">
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<include layout="@layout/home_content" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent">
|
||||
android:background="@android:color/transparent"
|
||||
android:elevation="0dp"
|
||||
app:elevation="0dp">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsingToolbarLayout"
|
||||
|
@ -56,8 +58,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
android:layout_marginTop="6dp"
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent">
|
||||
android:background="@android:color/transparent"
|
||||
android:elevation="0dp"
|
||||
app:elevation="0dp">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsingToolbarLayout"
|
||||
|
@ -54,8 +56,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
app:cardElevation="8dp"
|
||||
android:layout_marginTop="6dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -111,8 +111,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
|
||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||
app:cardBackgroundColor="?colorPrimary"
|
||||
app:cardCornerRadius="12dp">
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<include layout="@layout/home_content" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:liftOnScroll="true">
|
||||
android:background="@android:color/transparent"
|
||||
android:elevation="0dp"
|
||||
app:elevation="0dp">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsingToolbarLayout"
|
||||
|
@ -50,15 +52,16 @@
|
|||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:behavior_overlapTop="24dp"
|
||||
app:behavior_overlapTop="30dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
android:layout_marginTop="6dp"
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -102,8 +105,8 @@
|
|||
android:id="@+id/albumText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:paddingTop="4dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextViewSubtitle2"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:text="Album details" />
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:elevation="0dp"
|
||||
app:elevation="0dp">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsingToolbarLayout"
|
||||
|
@ -58,8 +61,9 @@
|
|||
android:id="@+id/contentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp">
|
||||
android:layout_marginTop="6dp"
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
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" >
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -66,7 +66,7 @@
|
|||
</FrameLayout>
|
||||
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
<FrameLayout
|
||||
android:id="@+id/toolbarContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -74,9 +74,8 @@
|
|||
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:layout_scrollFlags="scroll|enterAlways">
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:shapeAppearance="@style/ToolbarCornerCardView">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
|
@ -90,7 +89,7 @@
|
|||
app:titleMarginStart="0dp"
|
||||
app:titleTextAppearance="@style/ToolbarTextAppearanceSearch"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
@ -104,7 +103,8 @@
|
|||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="12dp">
|
||||
app:cardElevation="8dp"
|
||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||
|
||||
<include layout="@layout/home_content" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:liftOnScroll="true">
|
||||
android:elevation="0dp"
|
||||
app:elevation="0dp">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/toolbarContainer"
|
||||
|
@ -38,7 +39,7 @@
|
|||
app:cardBackgroundColor="?colorSurface"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:layout_collapseMode="pin">
|
||||
app:layout_scrollFlags="scroll|enterAlways">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -74,11 +75,10 @@
|
|||
android:layout_height="@dimen/tab_height"
|
||||
android:background="?colorSecondary"
|
||||
android:paddingStart="60dp"
|
||||
android:paddingEnd="8dp" />
|
||||
android:paddingEnd="8dp"
|
||||
app:layout_collapseMode="pin" />
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
|
|
|
@ -217,4 +217,17 @@
|
|||
<style name="ChipFont" parent="TextAppearance.MaterialComponents.Chip">
|
||||
<item name="android:fontFamily">@font/circular</item>
|
||||
</style>
|
||||
|
||||
<style name="TopCornerCardView">
|
||||
<item name="cornerFamilyTopLeft">rounded</item>
|
||||
<item name="cornerFamilyTopRight">rounded</item>
|
||||
<item name="cornerSizeTopLeft">16dp</item>
|
||||
<item name="cornerSizeTopRight">16dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ToolbarCornerCardView">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">8dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
classpath 'com.android.tools.build:gradle:3.5.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.android.tools.build:bundletool:0.9.0'
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue