add an initial fast scrollbar to thumbnail view

This commit is contained in:
tibbi 2017-03-04 19:29:24 +01:00
parent 06026ed671
commit 2bc78212b9
6 changed files with 176 additions and 11 deletions

View File

@ -56,7 +56,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
mIsGetAnyIntent = getBooleanExtra(GET_ANY_INTENT, false)
}
media_holder.setOnRefreshListener({ getMedia() })
media_refresh_layout.setOnRefreshListener({ getMedia() })
mPath = intent.getStringExtra(DIRECTORY)
mStoredAnimateGifs = config.animateGifs
mShowAll = config.showAll
@ -76,7 +76,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
super.onPause()
mCurrAsyncTask?.shouldStop = true
mIsGettingMedia = false
media_holder.isRefreshing = false
media_refresh_layout.isRefreshing = false
mStoredAnimateGifs = config.animateGifs
}
@ -105,6 +105,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
} else {
media_grid.adapter = adapter
}
media_fastscroller.setViews(media_grid, media_refresh_layout)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -214,7 +215,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
val token = object : TypeToken<List<Medium>>() {}.type
val media = Gson().fromJson<ArrayList<Medium>>(config.loadFolderMedia(mPath), token) ?: ArrayList<Medium>(1)
if (media.size == 0) {
media_holder.isRefreshing = true
media_refresh_layout.isRefreshing = true
} else {
if (!mLoadedInitialPhotos)
gotMedia(media)
@ -339,7 +340,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
fun gotMedia(media: ArrayList<Medium>) {
mIsGettingMedia = false
media_holder.isRefreshing = false
media_refresh_layout.isRefreshing = false
if (media.hashCode() == mMedia.hashCode())
return

View File

@ -0,0 +1,121 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import com.simplemobiletools.gallery.R
import kotlinx.android.synthetic.main.fastscroller.view.*
// based on https://blog.stylingandroid.com/recyclerview-fastscroll-part-1
class FastScroller : LinearLayout {
private val handle: View
private var currHeight = 0
private val HANDLE_HIDE_DELAY = 1000L
private var recyclerView: RecyclerView? = null
private var swipeRefreshLayout: SwipeRefreshLayout? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
fun setViews(recyclerView: RecyclerView, swipeRefreshLayout: SwipeRefreshLayout) {
this.recyclerView = recyclerView
this.swipeRefreshLayout = swipeRefreshLayout
recyclerView.setOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
updateHandlePosition()
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
showHandle()
} else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
hideHandle()
}
}
})
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
currHeight = h
updateHandlePosition()
}
private fun updateHandlePosition() {
if (handle.isSelected)
return
val verticalScrollOffset = recyclerView!!.computeVerticalScrollOffset()
val verticalScrollRange = recyclerView!!.computeVerticalScrollRange()
val proportion = verticalScrollOffset.toFloat() / (verticalScrollRange.toFloat() - currHeight)
setPosition(currHeight * proportion)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
return when (event.action) {
MotionEvent.ACTION_DOWN -> {
showHandle()
handle.isSelected = true
swipeRefreshLayout?.isEnabled = false
true
}
MotionEvent.ACTION_MOVE -> {
setPosition(event.y)
setRecyclerViewPosition(event.y)
true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
hideHandle()
handle.isSelected = false
swipeRefreshLayout?.isEnabled = true
true
}
else -> super.onTouchEvent(event)
}
}
private fun setRecyclerViewPosition(y: Float) {
if (recyclerView != null) {
val itemCount = recyclerView!!.adapter.itemCount
val proportion = y / currHeight
val targetPos = getValueInRange(0f, (itemCount - 1).toFloat(), proportion * itemCount).toInt()
(recyclerView!!.layoutManager as GridLayoutManager).scrollToPositionWithOffset(targetPos, 0)
}
}
init {
orientation = LinearLayout.HORIZONTAL
clipChildren = false
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.fastscroller, this)
handle = fastscroller_handle
}
private fun showHandle() {
handle.animate().alpha(1f).startDelay = 0L
}
private fun hideHandle() {
handle.animate().alpha(0f).startDelay = HANDLE_HIDE_DELAY
}
private fun setPosition(y: Float) {
val position = y / currHeight
val handleHeight = handle.height
handle.y = getValueInRange(0f, (currHeight - handleHeight).toFloat(), (currHeight - handleHeight) * position)
}
private fun getValueInRange(min: Float, max: Float, value: Float) = Math.min(Math.max(min, value), max)
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/small_margin"/>
<solid android:color="@color/color_primary"/>
<size
android:width="@dimen/fastscroll_width"
android:height="@dimen/fastscroll_height"/>
</shape>

View File

@ -2,6 +2,11 @@
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/media_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/media_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -9,9 +14,19 @@
<com.simplemobiletools.gallery.views.MyScalableRecyclerView
android:id="@+id/media_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_height="wrap_content"
android:scrollbars="none"
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="@integer/media_columns"/>
<com.simplemobiletools.gallery.views.FastScroller
android:id="@+id/media_fastscroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:paddingLeft="@dimen/small_margin"
android:paddingRight="@dimen/small_margin"/>
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="@+id/fastscroller_handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fastscroller_handle"/>
</merge>

View File

@ -8,4 +8,6 @@
<dimen name="timer_padding">24dp</dimen>
<dimen name="tmb_shadow_height">50dp</dimen>
<dimen name="exclude_folder_img_size">48dp</dimen>
<dimen name="fastscroll_width">8dp</dimen>
<dimen name="fastscroll_height">40dp</dimen>
</resources>