Skip to content

Commit

Permalink
Improve tag view & increase font size
Browse files Browse the repository at this point in the history
  • Loading branch information
mopsalarm committed Nov 10, 2019
1 parent 3d44cd3 commit d9f2bf4
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class PostAdapter
data class InfoItem(val item: FeedItem, val vote: Vote, val isOurPost: Boolean, val followState: FollowState?, val actions: PostActions)
: Item(idInCategory(1))

data class TagsItem(val itemId: Long, val tags: List<Api.Tag>, val votes: LongSparseArray<Vote>, val state: TagsView.ViewState, val actions: PostActions)
data class TagsItem(val itemId: Long, val tags: List<Api.Tag>, val votes: LongSparseArray<Vote>, val actions: PostActions)
: Item(idInCategory(2))

object CommentsLoadingItem
Expand Down Expand Up @@ -116,7 +116,6 @@ private object TagsViewHolderAdapterDelegate
override fun onBindViewHolder(holder: ViewHolder, value: PostAdapter.Item.TagsItem) {
holder.tagsView.actions = value.actions
holder.tagsView.updateTags(value.itemId, value.tags, value.votes)
holder.tagsView.setViewState(value.state)
}

private class ViewHolder(val tagsView: TagsView) : RecyclerView.ViewHolder(tagsView)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import com.pr0gramm.app.ui.base.*
import com.pr0gramm.app.ui.dialogs.ErrorDialogFragment.Companion.showErrorString
import com.pr0gramm.app.ui.dialogs.NewTagDialogFragment
import com.pr0gramm.app.ui.views.PostActions
import com.pr0gramm.app.ui.views.TagsView
import com.pr0gramm.app.ui.views.viewer.AbstractProgressMediaView
import com.pr0gramm.app.ui.views.viewer.MediaUri
import com.pr0gramm.app.ui.views.viewer.MediaView
Expand Down Expand Up @@ -339,7 +338,7 @@ class PostFragment : BaseFragment("PostFragment"), NewTagDialogFragment.OnAddNew
items += PostAdapter.Item.PostIsDeletedItem

} else {
items += PostAdapter.Item.TagsItem(state.item.id, state.tags, state.tagVotes, state.tagViewState, actions)
items += PostAdapter.Item.TagsItem(state.item.id, state.tags, state.tagVotes, actions)

if (state.commentsVisible) {
if (state.commentsLoadError) {
Expand Down Expand Up @@ -1322,10 +1321,6 @@ class PostFragment : BaseFragment("PostFragment"), NewTagDialogFragment.OnAddNew
return doVoteFeedItem(vote)
}

override fun updateTagsViewViewState(viewState: TagsView.ViewState) {
state = state.copy(tagViewState = viewState)
}

override fun writeNewTagClicked() {
doIfAuthorizedHelper.run {
if (!childFragmentManager.isStateSaved) {
Expand Down Expand Up @@ -1353,7 +1348,6 @@ class PostFragment : BaseFragment("PostFragment"), NewTagDialogFragment.OnAddNew
val itemVote: Vote = Vote.NEUTRAL,
val tags: List<Api.Tag> = emptyList(),
val tagVotes: LongSparseArray<Vote> = LongSparseArray(initialCapacity = 0),
val tagViewState: TagsView.ViewState = TagsView.ViewState.CLOSED,
val viewerBaseHeight: Int = 0,
val comments: List<CommentTree.Item> = emptyList(),
val commentsVisible: Boolean = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ class InfoLineView(context: Context) : LinearLayout(context) {

if (state != FollowState.NONE && !userService.canViewFollowCategory) {
Snackbar.make(this@InfoLineView, R.string.hint_follow_premium_only, Snackbar.LENGTH_SHORT)
.setAction(R.string.okay) {}
.configureNewStyle()
.show()
}
Expand Down
5 changes: 0 additions & 5 deletions app/src/main/java/com/pr0gramm/app/ui/views/PostActions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ interface PostActions {
*/
fun writeNewTagClicked()

/**
* Update the view state for for the TagsView
*/
fun updateTagsViewViewState(viewState: TagsView.ViewState)

/**
* Writes a new comment
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.os.bundleOf
import androidx.core.view.children
import androidx.core.view.isVisible
Expand All @@ -16,14 +17,17 @@ import com.pr0gramm.app.util.dp
import com.pr0gramm.app.util.observeChange
import kotlin.math.roundToInt

private const val AnimationDuration = 250L

class TagCloudContainerView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

var maxHeight: Int by observeChange(dp(64)) { requestLayout() }
var moreThreshold: Int by observeChange(dp(64)) { requestLayout() }
var moreOffset: Int by observeChange(0) { requestLayout() }

private var expandAnimator: ValueAnimator? = null

private var animator: ValueAnimator? = null
var clipHeight: Int by observeChange(0) { requestLayout() }

private var state: State = State.COLLAPSED

Expand All @@ -32,7 +36,7 @@ class TagCloudContainerView @JvmOverloads constructor(

if (child.id == R.id.expander) {
child.setOnClickListener {
expand()
animateTo(State.EXPANDED)
}
}
}
Expand All @@ -48,8 +52,8 @@ class TagCloudContainerView @JvmOverloads constructor(
if (state is Bundle) {
super.onRestoreInstanceState(state.getParcelable("superState"))

this.animator?.cancel()
this.animator = null
this.expandAnimator?.cancel()
this.expandAnimator = null

if (state.getBoolean("expanded", false)) {
this.state = State.EXPANDED
Expand All @@ -59,54 +63,62 @@ class TagCloudContainerView @JvmOverloads constructor(
}
}

private fun expand() {
if (state != State.COLLAPSED) {
private fun animateTo(targetState: State) {
if (state === targetState || state === State.ANIMATING) {
return
}

state = State.EXPANDING

// cancel any active animation
animator?.cancel()
expandAnimator?.cancel()

// create a new animator
val va = ValueAnimator.ofFloat(0f, 1f)
val valueStart = if (targetState === State.EXPANDED) 0f else 1f
val valueTarget = if (targetState === State.EXPANDED) 1f else 0f

// store animator in case we want to cancel it
animator = va
// create a new animator
expandAnimator = ValueAnimator.ofFloat(valueStart, valueTarget).apply {
addUpdateListener { va ->
expanderView().alpha = 1f - va.animatedValue as Float
requestLayout()
}

va.addUpdateListener { _ ->
expanderView().alpha = 1f - va.animatedFraction
requestLayout()
}
doOnEnd {
state = targetState
expanderView().isVisible = targetState === State.COLLAPSED
}

va.doOnEnd {
state = State.EXPANDED
expanderView().isVisible = false
}
doOnStart {
state = State.ANIMATING
}

va.duration = 250L
duration = AnimationDuration

va.start()
start()
}
}

/**
* Resets the view back to its collapsed version.
* This is not running any animations.
*/
fun reset() {
animator?.cancel()
fun reset(animated: Boolean = false) {
if (animated) {
animateTo(State.COLLAPSED)
} else {
expandAnimator?.cancel()
expandAnimator = null

state = State.COLLAPSED
expanderView().alpha = 1f
state = State.COLLAPSED
expanderView().alpha = 1f
requestLayout()
}
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val contentView = contentView()
val expanderView = expanderView()

val contentViewHeightSpec = if (state == State.COLLAPSED) {
MeasureSpec.makeMeasureSpec(moreThreshold + dp(8), MeasureSpec.AT_MOST)
MeasureSpec.makeMeasureSpec(clipHeight + moreOffset + dp(8), MeasureSpec.AT_MOST)
} else {
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
}
Expand All @@ -117,13 +129,13 @@ class TagCloudContainerView @JvmOverloads constructor(
var expanderHeight = 0

// test if we should show the expander.
val shouldShowExpander = (state == State.EXPANDING || contentView.measuredHeight > moreThreshold) && state != State.EXPANDED
val shouldShowExpanderNow = (state === State.ANIMATING || contentView.measuredHeight > (clipHeight + moreOffset)) && state !== State.EXPANDED

if (expanderView.isVisible != shouldShowExpander) {
expanderView.isVisible = shouldShowExpander
if (expanderView.isVisible != shouldShowExpanderNow) {
expanderView.isVisible = shouldShowExpanderNow
}

if (shouldShowExpander) {
if (shouldShowExpanderNow) {
// measure the expander view
expanderView.measure(
MeasureSpec.makeMeasureSpec(contentView.measuredWidth, MeasureSpec.AT_MOST),
Expand All @@ -133,12 +145,12 @@ class TagCloudContainerView @JvmOverloads constructor(
}

// calculate height
val heightCollapsed = contentView.measuredHeight.coerceAtMost(maxHeight) + expanderHeight
val heightCollapsed = contentView.measuredHeight.coerceAtMost(clipHeight) + expanderHeight
val heightExpanded = contentView.measuredHeight

val animationValue = currentAnimationValue()

val heightCurrent = if (shouldShowExpander) {
val heightCurrent = if (shouldShowExpanderNow) {
(heightExpanded * animationValue + heightCollapsed * (1 - animationValue)).roundToInt()
} else {
heightExpanded
Expand Down Expand Up @@ -169,14 +181,14 @@ class TagCloudContainerView @JvmOverloads constructor(
return when (state) {
State.COLLAPSED -> 0f
State.EXPANDED -> 1f
State.EXPANDING -> animator?.animatedFraction ?: 0f
State.ANIMATING -> expandAnimator?.animatedValue as? Float ?: 0f
}
}

private fun contentView() = children.first { it.id != R.id.expander }
private fun expanderView() = children.first { it.id == R.id.expander }

enum class State {
COLLAPSED, EXPANDING, EXPANDED
COLLAPSED, ANIMATING, EXPANDED
}
}
Loading

0 comments on commit d9f2bf4

Please sign in to comment.