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)
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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,16 +2,31 @@
|
|||
<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_holder"
|
||||
android:id="@+id/media_refresh_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.simplemobiletools.gallery.views.MyScalableRecyclerView
|
||||
android:id="@+id/media_grid"
|
||||
<RelativeLayout
|
||||
android:id="@+id/media_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="android.support.v7.widget.GridLayoutManager"
|
||||
app:spanCount="@integer/media_columns"/>
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.simplemobiletools.gallery.views.MyScalableRecyclerView
|
||||
android:id="@+id/media_grid"
|
||||
android:layout_width="match_parent"
|
||||
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>
|
||||
|
|
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="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>
|
||||
|
|
Loading…
Reference in a new issue