Skip to content

Commit

Permalink
Album activity UI according to designs
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Verein committed Jul 8, 2016
1 parent fe6dd09 commit 62798aa
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 33 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "com.android.support:appcompat-v7:$supportVersion"
compile "com.android.support:recyclerview-v7:$supportVersion"
compile "com.android.support:cardview-v7:$supportVersion"
compile "com.android.support:palette-v7:$supportVersion"
compile "com.android.support:design:$supportVersion"
compile "de.greenrobot:eventbus:2.4.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import org.jetbrains.anko.find
import org.jetbrains.anko.layoutInflater
import kotlin.properties.Delegates

class ImageTitleAdapter() : RecyclerView.Adapter<ViewHolder>() {
class ImageTitleAdapter() : RecyclerView.Adapter<ImageTitleAdapter.ViewHolder>() {

var items: List<ImageTitle> by Delegates.observable(emptyList()) { prop, old, new -> notifyDataSetChanged() }

Expand All @@ -47,16 +47,17 @@ class ImageTitleAdapter() : RecyclerView.Adapter<ViewHolder>() {
override fun getItemCount() = items.size

fun findPositionById(id: String): Int = items.withIndex().first({ it.value.id == id }).index
}

class ViewHolder(view: View, var onItemClickListener: ((ImageTitle) -> Unit)?) : RecyclerView.ViewHolder(view) {
class ViewHolder(view: View, var onItemClickListener: ((ImageTitle) -> Unit)?) : RecyclerView.ViewHolder(view) {

private val title: TextView = view.find(R.id.title)
private val image: ImageView = view.find(R.id.image)
private val title: TextView = view.find(R.id.title)
private val image: ImageView = view.find(R.id.image)

fun setItem(item: ImageTitle) {
itemView?.singleClick { onItemClickListener?.invoke(item) }
title.text = item.name
Picasso.with(itemView.context).load(item.url).centerCrop().fit().into(image)
fun setItem(item: ImageTitle) {
itemView?.singleClick { onItemClickListener?.invoke(item) }
title.text = item.name
Picasso.with(itemView.context).load(item.url).centerCrop().fit().into(image)
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.antonioleiva.bandhookkotlin.ui.adapter

import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.antonioleiva.bandhookkotlin.R
import com.antonioleiva.bandhookkotlin.ui.entity.TrackDetail
import org.jetbrains.anko.find
import org.jetbrains.anko.layoutInflater
import kotlin.properties.Delegates

/**
* @author alexey@plainvanillagames.com
*
* 06/07/16.
*/

class TracksAdapter() : RecyclerView.Adapter<TracksAdapter.ViewHolder>() {

var items: List<TrackDetail> by Delegates.observable(emptyList())
{ prop, old, new -> notifyDataSetChanged() }

override fun getItemCount(): Int {
return items.count()
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.setItem(items[position], position)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? {
val v = parent.context.layoutInflater.inflate(R.layout.track_item_view, parent, false)
return TracksAdapter.ViewHolder(v)
}

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

private val trackNumberTextView: TextView = view.find(R.id.track_number)
private val trackNameTextView: TextView = view.find(R.id.track_name)
private val trackLengthTextView: TextView = view.find(R.id.track_length)

fun setItem(item: TrackDetail, position: Int) {
val fullMinutes = item.duration / 60
val restSeconds = item.duration % 60
val trackLength = String.format("%d:%02d", fullMinutes, restSeconds);

trackNumberTextView.text = "${position + 1}"
trackNameTextView.text = item.name
trackLengthTextView.text = "$trackLength"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.antonioleiva.bandhookkotlin.ui.entity

/**
* @author alexey@plainvanillagames.com
*
* 07/07/16.
*/

data class TrackDetail(val name: String, val duration: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.antonioleiva.bandhookkotlin.ui.entity.mapper

import com.antonioleiva.bandhookkotlin.domain.entity.Track
import com.antonioleiva.bandhookkotlin.ui.entity.TrackDetail

/**
* @author alexey@plainvanillagames.com
*
* 07/07/16.
*/

class TrackDataMapper {
fun transform(domainTrack: Track): TrackDetail {
return TrackDetail(domainTrack.name, domainTrack.duration)
}

fun transform(domainTrack: List<Track>): List<TrackDetail> {
return domainTrack.map { transform(it) }
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
package com.antonioleiva.bandhookkotlin.ui.screens.album

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.os.Bundle
import android.support.v7.widget.CardView
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.MenuItem
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import com.antonioleiva.bandhookkotlin.R
import com.antonioleiva.bandhookkotlin.di.Inject
import com.antonioleiva.bandhookkotlin.di.Injector
import com.antonioleiva.bandhookkotlin.ui.activity.BaseActivity
import com.antonioleiva.bandhookkotlin.ui.adapter.TracksAdapter
import com.antonioleiva.bandhookkotlin.ui.entity.AlbumDetail
import com.antonioleiva.bandhookkotlin.ui.entity.TrackDetail
import com.antonioleiva.bandhookkotlin.ui.entity.mapper.AlbumDetailDataMapper
import com.antonioleiva.bandhookkotlin.ui.entity.mapper.TrackDataMapper
import com.antonioleiva.bandhookkotlin.ui.presenter.AlbumPresenter
import com.antonioleiva.bandhookkotlin.ui.util.getNavigationId
import com.antonioleiva.bandhookkotlin.ui.util.supportsLollipop
Expand All @@ -27,18 +36,39 @@ class AlbumActivity : BaseActivity(), AlbumView, Injector by Inject.instance {
override val layoutResource = R.layout.activity_album

val image by lazy { find<ImageView>(R.id.album_image) }
val text by lazy { find<TextView>(R.id.albums) }
val trackList by lazy { find<RecyclerView>(R.id.tracks_list) }
val listCard by lazy { find<CardView>(R.id.card_view) }
val albumListBreakingEdgeHeight by lazy { resources.getDimension(R.dimen.album_breaking_edge_height) }
val trackDataMapper = TrackDataMapper()

var presenter = AlbumPresenter(this, bus, albumInteractorProvider,
interactorExecutor, AlbumDetailDataMapper())

var adapter = TracksAdapter()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setUpTransition()
setUpActionBar()
setUpTrackList()
}

private fun setUpTransition() {
supportPostponeEnterTransition()
supportsLollipop { image.transitionName = IMAGE_TRANSITION_NAME }
}

private fun setUpTrackList() {
trackList.adapter = adapter
trackList.layoutManager = LinearLayoutManager(this)
listCard.translationY = -albumListBreakingEdgeHeight
}

private fun setUpActionBar() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
title = null
}

override fun onResume() {
super.onResume()
presenter.onResume()
Expand All @@ -54,15 +84,46 @@ class AlbumActivity : BaseActivity(), AlbumView, Injector by Inject.instance {
if (albumDetail != null) {
picasso.load(albumDetail.url).fit().centerCrop().into(image, object : Callback.EmptyCallback() {
override fun onSuccess() {
makeStatusBarTransparent()
supportStartPostponedEnterTransition()

val tracks = albumDetail.tracks.map { it.name }.joinToString()
text.text = tracks
populateTrackList(trackDataMapper.transform(albumDetail.tracks))
animateTrackListUp()
}
})
} else {
supportStartPostponedEnterTransition();
supportFinishAfterTransition();
}
}

private fun animateTrackListUp() {
listCard.animate().setStartDelay(500).translationY(0f)
}

private fun populateTrackList(TrackDetails: List<TrackDetail>) {
adapter.items = TrackDetails
}

private fun makeStatusBarTransparent() {
supportsLollipop {
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item != null && item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}

override fun onBackPressed() {
listCard.animate().alpha(0f).setListener(object: AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
supportFinishAfterTransition();
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class ArtistActivity: BaseActivity(), ArtistView, AlbumsFragmentContainer, Injec
private fun makeStatusBarTransparent() {
supportsLollipop {
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}

Expand All @@ -124,19 +124,19 @@ class ArtistActivity: BaseActivity(), ArtistView, AlbumsFragmentContainer, Injec
val bitmap = drawable?.bitmap
if (bitmap != null) {
Palette.from(bitmap).generate { palette ->
val darkVibrantColor = palette.getDarkVibrantColor(R.attr.colorPrimary);
collapsingToolbarLayout.setContentScrimColor(darkVibrantColor);
collapsingToolbarLayout.setStatusBarScrimColor(darkVibrantColor);
val darkVibrantColor = palette.getDarkVibrantColor(R.attr.colorPrimary)
collapsingToolbarLayout.setContentScrimColor(darkVibrantColor)
collapsingToolbarLayout.setStatusBarScrimColor(darkVibrantColor)
};
}
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item != null && item.itemId == android.R.id.home) {
supportFinishAfterTransition();
return true;
supportFinishAfterTransition()
return true
}
return super.onOptionsItemSelected(item);
return super.onOptionsItemSelected(item)
}

override fun navigateToAlbum(albumId: String) {
Expand Down
44 changes: 33 additions & 11 deletions app/src/main/res/layout/activity_album.xml
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<include layout="@layout/includes_toolbar"/>
android:layout_height="match_parent"
>

<com.antonioleiva.bandhookkotlin.ui.custom.SquareImageView
android:id="@+id/album_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:background="@android:color/darker_gray"
app:layout_collapseMode="parallax"
/>

<TextView
android:id="@+id/albums"
android:layout_width="match_parent"
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:text="Album content"
android:layout_width="match_parent"
android:background="@android:color/transparent"
android:layout_marginTop="@dimen/statusbar_height"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
/>

</LinearLayout>
<android.support.v7.widget.CardView
android:layout_below="@id/album_image"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="5sp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="-5dp"
android:layout_marginTop="@dimen/album_breaking_edge_height"
>

<android.support.v7.widget.RecyclerView
android:id="@+id/tracks_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</android.support.v7.widget.CardView>

</RelativeLayout>
43 changes: 43 additions & 0 deletions app/src/main/res/layout/track_item_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/track_number"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="16dp"
android:textSize="16sp"
tools:text="1"
android:gravity="end"
/>

<TextView
android:id="@+id/track_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:textSize="16sp"
tools:text="Counting Stars"
android:layout_toRightOf="@id/track_number"
android:layout_toLeftOf="@+id/track_length"
android:ellipsize="end"
/>

<TextView
android:id="@id/track_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textSize="16sp"
tools:text="4:18"
android:layout_alignParentRight="true"
/>

</RelativeLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
<resources>
<dimen name="detail_toolbar_height">300dp</dimen>
<dimen name="statusbar_height">24dp</dimen>
<dimen name="album_breaking_edge_height">-110dp</dimen>
</resources>

0 comments on commit 62798aa

Please sign in to comment.