This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Called when fab is clicked to open filter sheet (open = true) | |
| * or called when closeIcon is clicked to close the filter sheet (open = false) | |
| * | |
| * It's a 3 step animation played in sequence. Read the comments to know more. | |
| */ | |
| private fun openFilterSheet(open: Boolean) { | |
| // 1) Fab Arc Path Animator | |
| // Animates path of the fab from starting position to centre of screen |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class NoScrollRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) | |
| : RecyclerView(context, attrs, defStyleAttr) { | |
| override fun scrollBy(x: Int, y: Int) { | |
| val lm = layoutManager as? NoScrollHorizontalLayoutManager | |
| lm?.canScrollHorizontally = true | |
| super.scrollBy(x, y) | |
| lm?.canScrollHorizontally = false | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| tabsRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { | |
| override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { | |
| totalTabsScroll += dx | |
| } | |
| }) | |
| viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { | |
| override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { | |
| // Scroll tabs as viewpager is scrolled | |
| val dx = (position + positionOffset) * tabItemWidth - totalTabsScroll |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private fun expandItem(holder: ListViewHolder, expand: Boolean, animate: Boolean) { | |
| if (animate) { | |
| val animator = getValueAnimator( | |
| expand, listItemExpandDuration, AccelerateDecelerateInterpolator() | |
| ) { progress -> | |
| holder.cardContainer.layoutParams.height = | |
| (originalHeight + (expandedHeight - originalHeight) * progress).toInt() | |
| holder.cardContainer.layoutParams.width = | |
| (originalWidth + (expandedWidth - originalWidth) * progress).toInt() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cardContainer.doOnLayout { view -> | |
| originalHeight = view.height | |
| // show expandView and record expandedHeight in next | |
| // layout pass (doOnNextLayout) and hide it immediately | |
| expandView.isVisible = true | |
| cardContainer.doOnNextLayout { view -> | |
| expandedHeight = view.height | |
| // We use post{} to hide the view. Otherwise the parent will not |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| inline fun <T : View> T.doOnGlobalLayout(crossinline action: () -> Unit) { | |
| viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { | |
| override fun onGlobalLayout() { | |
| viewTreeObserver.removeOnGlobalLayoutListener(this) | |
| action() | |
| } | |
| }) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| inline fun getValueAnimator(forward: Boolean = true, duration: Long, interpolator: TimeInterpolator, | |
| crossinline updateListener: (progress: Float) -> Unit | |
| ): ValueAnimator { | |
| val a = | |
| if (forward) ValueAnimator.ofFloat(0f, 1f) | |
| else ValueAnimator.ofFloat(1f, 0f) | |
| a.addUpdateListener { updateListener(it.animatedValue as Float) } | |
| a.duration = duration | |
| a.interpolator = interpolator | |
| return a |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| override fun onBindViewHolder(holder: ListViewHolder, position: Int) { | |
| val model = adapterList[position] | |
| // set expand state on binded items because views are recycler | |
| expandItem(holder, model == expandedModel, animate = false) | |
| holder.cardContainer.setOnClickListener { | |
| if (expandedModel == null) { | |
| // expand clicked view | |
| expandItem(holder, expand = true, animate = true) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ToolbarBehavior : CoordinatorLayout.Behavior<AppBarLayout>() { | |
| /** Consume if vertical scroll because we don't care about other scrolls */ | |
| override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: AppBarLayout, | |
| directTargetChild: View, target: View, axes: Int, type: Int): Boolean { | |
| getViews(child) | |
| return axes == ViewCompat.SCROLL_AXIS_VERTICAL || | |
| super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type) | |
| } |