Loading commons/src/main/kotlin/com/simplemobiletools/commons/views/FastScroller.kt +56 −6 Original line number Diff line number Diff line package com.simplemobiletools.commons.views import android.content.Context import android.graphics.drawable.GradientDrawable import android.support.v4.widget.SwipeRefreshLayout import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView Loading @@ -8,15 +9,21 @@ import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.widget.FrameLayout import android.widget.TextView import com.simplemobiletools.commons.R import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.baseConfig // based on https://blog.stylingandroid.com/recyclerview-fastscroll-part-1 class FastScroller : FrameLayout { var isHorizontal = false var allowBubbleDisplay = false private var handle: View? = null private var bubble: TextView? = null private var currHeight = 0 private var currWidth = 0 private var bubbleOffset = 0 private val HANDLE_HIDE_DELAY = 1000L private var recyclerView: RecyclerView? = null Loading @@ -31,7 +38,7 @@ class FastScroller : FrameLayout { fun setViews(recyclerView: RecyclerView, swipeRefreshLayout: SwipeRefreshLayout? = null) { this.recyclerView = recyclerView this.swipeRefreshLayout = swipeRefreshLayout updateHandleColor() updatePrimaryColor() recyclerView.setOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) { Loading @@ -42,17 +49,40 @@ class FastScroller : FrameLayout { super.onScrollStateChanged(recyclerView, newState) if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { showHandle() } else if (newState == RecyclerView.SCROLL_STATE_IDLE) { hideHandle() } } }) } fun updateHandleColor() { fun updatePrimaryColor() { handle!!.background.applyColorFilter(context.baseConfig.primaryColor) updateBubblePrimaryColor() } fun updateBubbleColors() { updateBubblePrimaryColor() updateBubbleTextColor() updateBubbleBackgroundColor() } fun updateBubblePrimaryColor() { getBubbleBackgroundDrawable()?.setStroke(resources.displayMetrics.density.toInt(), context.baseConfig.primaryColor) } fun updateBubbleTextColor() { bubble?.setTextColor(context.baseConfig.textColor) } fun updateBubbleBackgroundColor() { getBubbleBackgroundDrawable()?.setColor(context.baseConfig.backgroundColor) } fun updateBubbleText(text: String) { bubble?.text = text } private fun getBubbleBackgroundDrawable() = bubble?.background as? GradientDrawable override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) { super.onSizeChanged(width, height, oldWidth, oldHeight) currHeight = height Loading Loading @@ -97,9 +127,9 @@ class FastScroller : FrameLayout { return when (event.action) { MotionEvent.ACTION_DOWN -> { showHandle() handle!!.isSelected = true swipeRefreshLayout?.isEnabled = false showHandle() true } MotionEvent.ACTION_MOVE -> { Loading @@ -113,7 +143,6 @@ class FastScroller : FrameLayout { true } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { hideHandle() handle!!.isSelected = false swipeRefreshLayout?.isEnabled = true true Loading @@ -139,15 +168,31 @@ class FastScroller : FrameLayout { override fun onFinishInflate() { super.onFinishInflate() handle = getChildAt(0) if (allowBubbleDisplay) { bubble = getChildAt(1) as? TextView } if (bubble != null) { bubbleOffset = resources.getDimension(R.dimen.fastscroll_height).toInt() updateBubbleColors() } } private fun showHandle() { handle!!.animate().alpha(1f).start() // override the fade animation handle!!.alpha = 1f if (handle!!.isSelected) { bubble?.animate()?.alpha(1f)?.start() bubble?.alpha = 1f } } private fun hideHandle() { handle!!.animate().alpha(0f).startDelay = HANDLE_HIDE_DELAY bubble?.animate()?.alpha(0f)?.setStartDelay(HANDLE_HIDE_DELAY)?.withEndAction { bubble?.text = "" } } private fun setPosition(pos: Float) { Loading @@ -159,7 +204,12 @@ class FastScroller : FrameLayout { val position = pos / currHeight val handleHeight = handle!!.height handle!!.y = getValueInRange(0f, (currHeight - handleHeight).toFloat(), (currHeight - handleHeight) * position) val bubbleHeight = bubble?.height ?: 0 val newY = getValueInRange(0f, (currHeight - bubbleHeight).toFloat(), (currHeight - bubbleHeight) * position) bubble?.y = Math.max(0f, newY - bubbleOffset) } hideHandle() } private fun getValueInRange(min: Float, max: Float, value: Float) = Math.min(Math.max(min, value), max) Loading commons/src/main/res/drawable/fastscroller_bubble.xml 0 → 100644 +12 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="4dp"/> <size android:width="-1dp" android:height="-1dp"/> </shape> commons/src/main/res/drawable/fastscroller_handle_vertical.xml +2 −2 Original line number Diff line number Diff line Loading @@ -4,8 +4,8 @@ android:shape="rectangle"> <corners android:topLeftRadius="@dimen/normal_margin" android:bottomLeftRadius="@dimen/normal_margin"/> android:bottomLeftRadius="@dimen/normal_margin" android:topLeftRadius="@dimen/normal_margin"/> <solid android:color="@color/color_primary"/> Loading commons/src/main/res/layout/fastscroller_handle_vertical.xml +18 −2 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <ImageView android:id="@+id/filepicker_fastscroller_handle" android:id="@+id/fastscroller_handle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:alpha="0" android:background="@drawable/fastscroller_handle_vertical"/> <TextView android:id="@+id/fastscroller_bubble" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/bigger_margin" android:layout_marginRight="@dimen/bigger_margin" android:alpha="0" android:background="@drawable/fastscroller_bubble" android:ellipsize="end" android:lines="1" android:padding="@dimen/medium_margin" android:singleLine="true" android:textSize="@dimen/normal_text_size" tools:text="bubble"/> </merge> commons/src/main/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ <dimen name="fastscroll_width">8dp</dimen> <dimen name="fastscroll_height">40dp</dimen> <dimen name="fingerprint_icon_size">72dp</dimen> <dimen name="fastscroll_bubble_offset">30dp</dimen> <dimen name="dragselect_hotspot_height">56dp</dimen> <dimen name="selection_check_size">26dp</dimen> Loading Loading
commons/src/main/kotlin/com/simplemobiletools/commons/views/FastScroller.kt +56 −6 Original line number Diff line number Diff line package com.simplemobiletools.commons.views import android.content.Context import android.graphics.drawable.GradientDrawable import android.support.v4.widget.SwipeRefreshLayout import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView Loading @@ -8,15 +9,21 @@ import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.widget.FrameLayout import android.widget.TextView import com.simplemobiletools.commons.R import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.baseConfig // based on https://blog.stylingandroid.com/recyclerview-fastscroll-part-1 class FastScroller : FrameLayout { var isHorizontal = false var allowBubbleDisplay = false private var handle: View? = null private var bubble: TextView? = null private var currHeight = 0 private var currWidth = 0 private var bubbleOffset = 0 private val HANDLE_HIDE_DELAY = 1000L private var recyclerView: RecyclerView? = null Loading @@ -31,7 +38,7 @@ class FastScroller : FrameLayout { fun setViews(recyclerView: RecyclerView, swipeRefreshLayout: SwipeRefreshLayout? = null) { this.recyclerView = recyclerView this.swipeRefreshLayout = swipeRefreshLayout updateHandleColor() updatePrimaryColor() recyclerView.setOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) { Loading @@ -42,17 +49,40 @@ class FastScroller : FrameLayout { super.onScrollStateChanged(recyclerView, newState) if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { showHandle() } else if (newState == RecyclerView.SCROLL_STATE_IDLE) { hideHandle() } } }) } fun updateHandleColor() { fun updatePrimaryColor() { handle!!.background.applyColorFilter(context.baseConfig.primaryColor) updateBubblePrimaryColor() } fun updateBubbleColors() { updateBubblePrimaryColor() updateBubbleTextColor() updateBubbleBackgroundColor() } fun updateBubblePrimaryColor() { getBubbleBackgroundDrawable()?.setStroke(resources.displayMetrics.density.toInt(), context.baseConfig.primaryColor) } fun updateBubbleTextColor() { bubble?.setTextColor(context.baseConfig.textColor) } fun updateBubbleBackgroundColor() { getBubbleBackgroundDrawable()?.setColor(context.baseConfig.backgroundColor) } fun updateBubbleText(text: String) { bubble?.text = text } private fun getBubbleBackgroundDrawable() = bubble?.background as? GradientDrawable override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) { super.onSizeChanged(width, height, oldWidth, oldHeight) currHeight = height Loading Loading @@ -97,9 +127,9 @@ class FastScroller : FrameLayout { return when (event.action) { MotionEvent.ACTION_DOWN -> { showHandle() handle!!.isSelected = true swipeRefreshLayout?.isEnabled = false showHandle() true } MotionEvent.ACTION_MOVE -> { Loading @@ -113,7 +143,6 @@ class FastScroller : FrameLayout { true } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { hideHandle() handle!!.isSelected = false swipeRefreshLayout?.isEnabled = true true Loading @@ -139,15 +168,31 @@ class FastScroller : FrameLayout { override fun onFinishInflate() { super.onFinishInflate() handle = getChildAt(0) if (allowBubbleDisplay) { bubble = getChildAt(1) as? TextView } if (bubble != null) { bubbleOffset = resources.getDimension(R.dimen.fastscroll_height).toInt() updateBubbleColors() } } private fun showHandle() { handle!!.animate().alpha(1f).start() // override the fade animation handle!!.alpha = 1f if (handle!!.isSelected) { bubble?.animate()?.alpha(1f)?.start() bubble?.alpha = 1f } } private fun hideHandle() { handle!!.animate().alpha(0f).startDelay = HANDLE_HIDE_DELAY bubble?.animate()?.alpha(0f)?.setStartDelay(HANDLE_HIDE_DELAY)?.withEndAction { bubble?.text = "" } } private fun setPosition(pos: Float) { Loading @@ -159,7 +204,12 @@ class FastScroller : FrameLayout { val position = pos / currHeight val handleHeight = handle!!.height handle!!.y = getValueInRange(0f, (currHeight - handleHeight).toFloat(), (currHeight - handleHeight) * position) val bubbleHeight = bubble?.height ?: 0 val newY = getValueInRange(0f, (currHeight - bubbleHeight).toFloat(), (currHeight - bubbleHeight) * position) bubble?.y = Math.max(0f, newY - bubbleOffset) } hideHandle() } private fun getValueInRange(min: Float, max: Float, value: Float) = Math.min(Math.max(min, value), max) Loading
commons/src/main/res/drawable/fastscroller_bubble.xml 0 → 100644 +12 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="4dp"/> <size android:width="-1dp" android:height="-1dp"/> </shape>
commons/src/main/res/drawable/fastscroller_handle_vertical.xml +2 −2 Original line number Diff line number Diff line Loading @@ -4,8 +4,8 @@ android:shape="rectangle"> <corners android:topLeftRadius="@dimen/normal_margin" android:bottomLeftRadius="@dimen/normal_margin"/> android:bottomLeftRadius="@dimen/normal_margin" android:topLeftRadius="@dimen/normal_margin"/> <solid android:color="@color/color_primary"/> Loading
commons/src/main/res/layout/fastscroller_handle_vertical.xml +18 −2 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <ImageView android:id="@+id/filepicker_fastscroller_handle" android:id="@+id/fastscroller_handle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:alpha="0" android:background="@drawable/fastscroller_handle_vertical"/> <TextView android:id="@+id/fastscroller_bubble" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/bigger_margin" android:layout_marginRight="@dimen/bigger_margin" android:alpha="0" android:background="@drawable/fastscroller_bubble" android:ellipsize="end" android:lines="1" android:padding="@dimen/medium_margin" android:singleLine="true" android:textSize="@dimen/normal_text_size" tools:text="bubble"/> </merge>
commons/src/main/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ <dimen name="fastscroll_width">8dp</dimen> <dimen name="fastscroll_height">40dp</dimen> <dimen name="fingerprint_icon_size">72dp</dimen> <dimen name="fastscroll_bubble_offset">30dp</dimen> <dimen name="dragselect_hotspot_height">56dp</dimen> <dimen name="selection_check_size">26dp</dimen> Loading