mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-23 04:57:59 +01:00
add an initial fast scrollbar to thumbnail view
This commit is contained in:
parent
06026ed671
commit
2bc78212b9
6 changed files with 176 additions and 11 deletions
|
@ -56,7 +56,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
mIsGetAnyIntent = getBooleanExtra(GET_ANY_INTENT, false)
|
mIsGetAnyIntent = getBooleanExtra(GET_ANY_INTENT, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
media_holder.setOnRefreshListener({ getMedia() })
|
media_refresh_layout.setOnRefreshListener({ getMedia() })
|
||||||
mPath = intent.getStringExtra(DIRECTORY)
|
mPath = intent.getStringExtra(DIRECTORY)
|
||||||
mStoredAnimateGifs = config.animateGifs
|
mStoredAnimateGifs = config.animateGifs
|
||||||
mShowAll = config.showAll
|
mShowAll = config.showAll
|
||||||
|
@ -76,7 +76,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
mCurrAsyncTask?.shouldStop = true
|
mCurrAsyncTask?.shouldStop = true
|
||||||
mIsGettingMedia = false
|
mIsGettingMedia = false
|
||||||
media_holder.isRefreshing = false
|
media_refresh_layout.isRefreshing = false
|
||||||
mStoredAnimateGifs = config.animateGifs
|
mStoredAnimateGifs = config.animateGifs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
} else {
|
} else {
|
||||||
media_grid.adapter = adapter
|
media_grid.adapter = adapter
|
||||||
}
|
}
|
||||||
|
media_fastscroller.setViews(media_grid, media_refresh_layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
@ -214,7 +215,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
val token = object : TypeToken<List<Medium>>() {}.type
|
val token = object : TypeToken<List<Medium>>() {}.type
|
||||||
val media = Gson().fromJson<ArrayList<Medium>>(config.loadFolderMedia(mPath), token) ?: ArrayList<Medium>(1)
|
val media = Gson().fromJson<ArrayList<Medium>>(config.loadFolderMedia(mPath), token) ?: ArrayList<Medium>(1)
|
||||||
if (media.size == 0) {
|
if (media.size == 0) {
|
||||||
media_holder.isRefreshing = true
|
media_refresh_layout.isRefreshing = true
|
||||||
} else {
|
} else {
|
||||||
if (!mLoadedInitialPhotos)
|
if (!mLoadedInitialPhotos)
|
||||||
gotMedia(media)
|
gotMedia(media)
|
||||||
|
@ -339,7 +340,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
|
||||||
|
|
||||||
fun gotMedia(media: ArrayList<Medium>) {
|
fun gotMedia(media: ArrayList<Medium>) {
|
||||||
mIsGettingMedia = false
|
mIsGettingMedia = false
|
||||||
media_holder.isRefreshing = false
|
media_refresh_layout.isRefreshing = false
|
||||||
|
|
||||||
if (media.hashCode() == mMedia.hashCode())
|
if (media.hashCode() == mMedia.hashCode())
|
||||||
return
|
return
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
13
app/src/main/res/drawable/fastscroller_handle.xml
Normal file
13
app/src/main/res/drawable/fastscroller_handle.xml
Normal 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>
|
|
@ -2,6 +2,11 @@
|
||||||
<android.support.v4.widget.SwipeRefreshLayout
|
<android.support.v4.widget.SwipeRefreshLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
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:id="@+id/media_holder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
@ -9,9 +14,19 @@
|
||||||
<com.simplemobiletools.gallery.views.MyScalableRecyclerView
|
<com.simplemobiletools.gallery.views.MyScalableRecyclerView
|
||||||
android:id="@+id/media_grid"
|
android:id="@+id/media_grid"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="none"
|
||||||
app:layoutManager="android.support.v7.widget.GridLayoutManager"
|
app:layoutManager="android.support.v7.widget.GridLayoutManager"
|
||||||
app:spanCount="@integer/media_columns"/>
|
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>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
|
13
app/src/main/res/layout/fastscroller.xml
Normal file
13
app/src/main/res/layout/fastscroller.xml
Normal 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>
|
|
@ -8,4 +8,6 @@
|
||||||
<dimen name="timer_padding">24dp</dimen>
|
<dimen name="timer_padding">24dp</dimen>
|
||||||
<dimen name="tmb_shadow_height">50dp</dimen>
|
<dimen name="tmb_shadow_height">50dp</dimen>
|
||||||
<dimen name="exclude_folder_img_size">48dp</dimen>
|
<dimen name="exclude_folder_img_size">48dp</dimen>
|
||||||
|
<dimen name="fastscroll_width">8dp</dimen>
|
||||||
|
<dimen name="fastscroll_height">40dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue